Exploring ReactScan: Aiden Bai's Tool for Identifying React Performance Issues - JsJ 668

In this episode of JavaScript Jabber, panelist Dan Shappir sits down with guest Aden Bai to delve into the nuances of React performance. Broadcasting from Tel Aviv, Dan welcomes Aden, who is based in San Francisco, for an insightful discussion on optimizing React apps. Aden, known for his projects Million JS and ReactScan, shares his journey into coding and his focus on enhancing web performance.

Hosted by: Dan Shappir
Special Guests: Aiden Bai

Show Notes

In this episode of JavaScript Jabber, panelist Dan Shappir sits down with guest Aden Bai to delve into the nuances of React performance. Broadcasting from Tel Aviv, Dan welcomes Aden, who is based in San Francisco, for an insightful discussion on optimizing React apps. Aden, known for his projects Million JS and ReactScan, shares his journey into coding and his focus on enhancing web performance. Together, they explore the intricacies of the virtual DOM, React rendering processes, and the common pitfalls that developers face in managing performance. Aden introduces ReactScan, a tool designed to visualize and troubleshoot performance issues in React applications, making complex profiling accessible to a broader range of developers. The conversation also touches on broader performance metrics like Core Web Vitals and the challenges of maintaining efficiency across various devices and browsers. Whether you're a seasoned developer or new to React, this episode offers valuable insights into creating faster and more efficient web applications. Tune in to learn how you can improve your React project's performance and user experience with tools and techniques from top industry experts.

Transcript

Dan Shappir [00:00:05]:
Hello, everybody, and welcome to another exciting episode of JavaScript Jabber. Today, I'm all on my lonesome, Dan Shappir, coming to you from Tel Aviv in Israel, and I'll be interviewing Aden Bai. Hi, Aden.

Aden Bai [00:00:20]:
Hi. How are you?

Dan Shappir [00:00:22]:
I'm doing well overall. How about yourself?

Aden Bai [00:00:26]:
Doing well. It's a not so hot, not too cold, day in San Francisco. So

Dan Shappir [00:00:32]:
Oh, that's lovely. It's kind of same over here in in Tel Aviv. So at least we are sharing good weather. And we are here today to talk about React performance. But before we start, Adin, maybe you can tell us a little bit about yourself and your very lengthy career in tech.

Aden Bai [00:00:52]:
Yeah. I I got started coding in middle school, but, like, you might know me for, million JS. It's like I tried to make a compiler for React, and then more recently, React scan, which is all, like, the purple flashing boxes on all these popular websites. You see it on Twitter. I've mainly mainly focused on performance most of my life, because I think it's it's an interesting problem. Not many people focus on it, and it's also very hard.

Dan Shappir [00:01:23]:
Yeah. Tell me about it. It's been one of my main focuses for the last, couple of years. For those of you who don't know, I also happen to be an invited expert on the w three c web performance working group. Maybe you should join us there as well. We talk about, things not so much related to React, more about, the relevant web standards, things like core vitals and stuff like that, and the APIs in the browser that can be used to retrieve them, to measure them, etcetera. I know that's not our topic, but I do want to talk a little bit about million JS because it seems so interesting. So as I recall, it it it's it's less correct description? Yeah.

Dan Shappir [00:02:12]:
That's correct. That a more or less correct description?

Aden Bai [00:02:16]:
Yeah. That's correct. Like, basically, how React works under the hood is it takes, like, two versions of the view. So, like, the old version and the new version, and then it reconciles it. Like, it figures out the differences between those, and then it applied it to the actual DOM. But, like, this is, like, an o an operation or some large big o notation that's over o one. And the the problem with that is if when the the the versions get really big, like, the trees get really big, you're doing a lot of computation. So I was like, okay.

Aden Bai [00:02:50]:
Wouldn't it be cool if you could precompile this? Like, okay. Based on the JSX you provided, there's, like, obvious points where it actually changes, like, when you have those JSX container expressions, like the when you pass, like, some data in. And so I precompiled that and then found, like, the the specific code paths that matter to make the DOM changes. So every time you render a component, instead of doing that whole reconciliation process, it just changes the DOM, like like, pinpoint processes, basically.

Dan Shappir [00:03:21]:
Kind of implementing fine grain reactivity in a sense over on top of React, I guess.

Aden Bai [00:03:28]:
Yeah. Like benefits of fine grain reactivity, but without using fine grain reactivity.

Dan Shappir [00:03:33]:
Yeah. I think you kind of mentioned several things that are kind of important in the context of React performance as you were describing this. I think that, first and foremost is, this whole thing about virtual DOM and the reconciliation. We actually had a couple of chapters in JavaScript Jabber talking about the virtual DOM, why what it is, why it exists, etcetera. But I still think it might be worth while to talk a little bit about what it is because it's so central to everything we'll be talking about today. So can you tell us a little bit about you the virtual DOM from your perspective?

Aden Bai [00:04:14]:
Yeah. Virtual DOM is basically it's kind of a overloaded term. It's basically taking two, like, versions of the UI and figuring out the differences between them and then actually changing the UI. React doesn't actually hold the DOM tree inside of itself. I mean, it kinda does, but, like, when it does when it figures out what to change, it doesn't actually store the DOM nodes as the whole tree and then dip the DOM nodes. It dips, like, a virtual version of it. This can lead to some problems. Like, so for example, like, for Facebook, it might be somewhat okay, like, when you we're switching pages.

Aden Bai [00:04:53]:
But, like, if you are creating, like, a stock trading app, like a stock trading dashboard, where, like, there needs to be, like, like, updates every several like, some amount of milliseconds, or you're making, like, significant DOM mutations every single second, or if your website targets it targets, like, very low end devices, then that sort of mechanism can lead to some performance problems.

Dan Shappir [00:05:20]:
I I think the key aspect here is that React took what I consider to be kind of an idealized approach to UI generation, which is let's in an ideal world, I would say, React the React approach is let's take the entire application state and apply, like, a function to it, a pure function even, that generates the UI that the user sees. And that every change in the state would ideally, again, regenerate the entire UI. So, you know, you check or uncheck a small checkbox in the UI, and, theoretically, the entire user interface of the application gets rerendered because then you don't need to think about, state changes in the user interface. It's just everything again and again from scratch. But the problem with this approach is that a naive implementation would obviously be just way too slow. It it's kind of taking, by the way, the approach that we had in the old days of the multipage applications and kind of applying it to the client side rendering mechanism that we have in JavaScript code that, updates the DOM. In that in in the old days, you would go to the back end, and then you would get the entire page back each and every time. So it's kind of like doing that, but, again, but doing everything on the client side and doing it for every state logical change.

Dan Shappir [00:07:00]:
And the virtual DOM was, like, the first thing that they implemented in order to make it viable from in the from the perspective of performance. That is the virtual DOM, by the way, it's just it's a fancy term, but real really, all it means is, JavaScript objects, really. That's that's all the virtual DOM is. So instead of having actual DOM elements, which are rather heavy because of all the functionality that they encapsulate, you just use JavaScript objects simple JavaScript objects as stand ins. And like you said, when the state changes and the new virtual DOM is created, React then takes the new virtual DOM. The old virtual DOM does a comparison, finds the differences, and then calculates the minimal amount of actual DOM changes to transition from the first state to the second state, and that's the reconciliation process. And for a long time, it was thought that it was that approach was good enough in terms of performance. But like you said, when user interfaces started becoming more complicate complicated or more complex, and as we needed to support lower end devices, like more mobile devices, for example.

Dan Shappir [00:08:21]:
And as we needed more frequent updates, even this type of optimization started to break down, because doing all this reconciliation work still has overhead. And this is when million JS, I guess, came in to to start to try to reduce that by, like you said, being able to be smart about pinpointing the exact locations of the differences and not having to do the entire comparison of the entire virtual DOM tree. Right?

Aden Bai [00:08:53]:
Yeah. Exactly. I view, like, virtual DOM is more of in a historical context, like, it's more of getting things correct. Like, before, people use, like, backbone or they roll their own JavaScript libraries. And this would literally results in, like, like, there were literally so many frame like, bugs in these frameworks. Virtual DOM is, like, a very exhaustive approach to the problem, but it's more likely to get things correct than not.

Dan Shappir [00:09:21]:
Yeah. Because when you're essentially building the entire UI from scratch from the current state, you don't have to worry about an incorrect, UI transition or state transition messing up your display. I think, Facebook had they they had the story about one of the motivations for creating React in the first place is that they had a counter in their user interface about the number of messages that, you had pending or something like that. And any change to that mechanism was always buggy because they always had to somehow sync with everything else that was changing on the page and and because so much so many things were changing more or less concurrently at on in the UI, all of them are synchronous to each other. They would always get into edge cases and edge situations. And being able to just rerender the entire UI from scratch virtually solve that problem very neatly. But, again so we had couple of performance issues. One performance issue is the one that you addressed with Minion JS, which is the fact that even that sophisticated reconciliation could be too slow, especially if the virtual DOM was really large, especially if the device was low end, and especially if you did it very frequently.

Dan Shappir [00:10:50]:
The other problem, I think, is that even building the virtual DOM, which is mostly just running your code that generates the the JSX from the state, can be heavy and performance intensive if done too often

Aden Bai [00:11:11]:
Yep.

Dan Shappir [00:11:11]:
Or if if it's just too complicated. And I think that this is where ReactScan comes in because it's that's your new project, the one that we're gonna talk about, because it strives to, if I understand correctly, minimize the amount of redundant helps you help you to minimize the amount of redundant rerenders that you perform. Correct?

Aden Bai [00:11:36]:
Yeah. Exactly. I can give a brief introduction. Basically, ReactScan is a tool that helps you find, like, rerendering performance problems in your React app. Today, you can just drop it in your app as a script tag, and it basically highlights the components that render and potentially slow down your app. That I I spent, like, maybe three years optimizing websites, everything from, like, WebRTC, like, virtual camera websites to ecommerce websites to, like, static sites. And when I try to debug these performance problems on these sites, it's really hard. Like, it's either, like, I do console dot time and time end, or I use lighthouse scores, which is, like, a skill level zero to profiling tools and that Chrome dev tools, React dev tools at, like, skill level 100.

Aden Bai [00:12:24]:
And so there's, like, nothing in between those those two types of tools. And this made me really frustrated. Right? I I, like, I've spent so long just trying to understand how these level 100 tools work that, that I realized that most people don't have the time or ability to figure it out.

Dan Shappir [00:12:42]:
Coordination. Exactly.

Aden Bai [00:12:45]:
So React Skin helps bridge the gap. Today, we do renders, but soon, we'll support more stuff more stuff in that, like INP, CLS, LCP, which are, like, the, lighthouse Google lighthouse scores, as well as stuff like long tasks, FPS, all of this, like, metrics and stuff that take that are decently, like, not, like, decently hard like, decently not easy to measure correctly and interpret, basically.

Dan Shappir [00:13:17]:
So you threw out a bunch of metrics. And then as I mentioned, metrics are near and dear to my heart. They are part of what I do on the w three c web performance working group, which I'm an invited expert on. I think the the three main ones, referred to as, unsurprisingly, as core web vitals because they are the core ones. We talked about them on on this show on several occasions. I think we even had specific episodes dedicated to them, but still, it again, it might be worthwhile to mention, what they are and what they measure. Do you wanna do that, or should I?

Aden Bai [00:13:57]:
I can explain, like, ten seconds. Like, INP is basically interacting a page and getting the result back visually. LCP is basically the largest, like, content fill. Basically, any element with text or image some big text in it, and it it's the, like, what however time it loads. And then CLS is basically, how much your page layout shifts. You want your INP to be as low as possible. You want your LCP to be as low as possible and c l s c l CLS to be low as well.

Dan Shappir [00:14:29]:
Yeah. Exactly. And it's interesting because they're they are not trivial in the context of React, especially.

Aden Bai [00:14:38]:
Yeah.

Dan Shappir [00:14:39]:
And it's interesting because different facets of React address different these different metrics. So, for example, if we're talking about the largest content for Paint, which, like you said, is the amount of time from when the page starts loading until the largest piece of content is actually rendered on the browser screen, if we think about what React does to try to optimize it, so initially, React, for those who who may not recall, was just client side rendered, and that kind of guarantees slow LCP by definition, because nothing is shown until all the JavaScript is downloaded, including React. And then the client side JavaScripts need to do the AJAX calls to get the data and then render the UI based on the data and the code, and only then do you actually see anything on the screen. So that's when React introduced server side rendering and stat or SSR and static side generation or SSG with, meta frameworks like, Next. Js or, Remix. So, it's by the way, it's interesting in this context that still many organizations that I encounter don't really care that much about LCP in the context of, React applications because a lot of the web applications that are built using React are things like dashboard or internal enterprise applications. And there, their approach is that it's loaded once and then used all day long, and therefore, the loading time is is less important. I actually think that in many cases, this is a misguided view because, for example, let's say you're commuting to work on a train.

Dan Shappir [00:16:35]:
You want to use that time. You're connecting via VPN into your internal network. You're loading your internal application, and it takes your entire train ride to actually load, which which isn't fun. But be that as it may, so that's LCP. There's the INP, which you mentioned, which is how responsive the page is to interactions, how long it takes the page from when you actually click on a button to actually render the result of clicking on that button. And, again, React can be really problematic there because if it's doing very lengthy rendering operations or rerendering operations and you click in the middle of one of these operations, then it won't actually respond or do anything until all that JavaScript finishes running.

Aden Bai [00:17:30]:
Mhmm.

Dan Shappir [00:17:31]:
And CLS, I think, is the one that is least directly related to, React itself because it's more it has more to do, I think, with how you style your CSS, stuff like that. I would say, though, that for people who are using, what's it called, React suspense, they need to watch out for, CLS, because if their loading code doesn't match the size of the actual finally rendered component, then things will shift after the after the low, the loader is done. So so you do need to watch out for that if you're using suspense in the context of React, I think. Would you agree with that?

Aden Bai [00:18:23]:
Yeah. Also for images. Right?

Dan Shappir [00:18:25]:
Yeah. But images are the you are you know, that's a universal issue. That's not React specific. Yeah. So Million JS kind of addressed, I guess, both LCP because you were running the rendering code faster.

Aden Bai [00:18:43]:
Mhmm.

Dan Shappir [00:18:44]:
And, also, it kind of, addressed INP because it blocks the rendering time for a shorter period of time. Yeah. What I understand that you're addressing with ReactScan is mostly about figuring out how to do less rendering and also generally make the rendering itself faster, which, again, will would primarily benefit INP, I guess.

Aden Bai [00:19:16]:
I see it as, like, rendering is always somehow related to some performance problem on the page if you use a React site. Like, I'll give a couple examples. Like, for example, with with with CLS. Right? It could be a styling issue, but as a user, I want to know, like, where that specific, specific, like, layout shift is occurring. With INP, I wanna click a button and I want and there's, like, maybe a bunch of renders. I don't know why it's slow. Rendering is somehow always somehow related to that. Even LCP as you said.

Aden Bai [00:19:53]:
Right? Like, like, if there's a lot of rendering on the page that doesn't need to render, like, maybe below the folder outside the viewport, then it's not good. Right? Even, like, other performance issues, like, when FPS drops or, like, I'm trying to think of other examples. But, like, whenever the page feels sluggish, it's always rendering is always somehow related to the problem.

Dan Shappir [00:20:19]:
So FPS, can you elaborate on what that is?

Aden Bai [00:20:22]:
FPS is frames per second. Basically, this is important for movement or animation tasks. So, like, when you scroll the page or something is animating, like, rainbow gradient for some reason, that FPS is important. You wanna usually keep it over 60 FPS, is the standard.

Dan Shappir [00:20:44]:
And, again, JavaScript gets in the way because, the main thread well, the browser is kinda not exactly, but mostly single threaded. So whenever you're running JavaScript, it kinda blocks everything. And if you're blocking everything too much, then you get jank or jitter because you're not able, like you said, to hit that 60 FPS. I I totally agree with what you said about, identifying things that render needlessly. My own experience is that a lot of React teams don't even ever get there. Basically, when they see that something that the UI renders correctly, that's good enough for them, and they don't care about the fact that it's rendering correctly over and over and over again, effectively do doing a lot of work at the virtual DOM level without actually ever updating the actual DOM because the reconciliation basically notices that they're just recreating the exact same virtual DOM over and over again.

Aden Bai [00:21:50]:
Yep.

Dan Shappir [00:21:51]:
But even that, even though it's cheaper than updating the DOM, still, you know, accumulates if you're constantly doing that. You're literally just running an infinite loop of JavaScript that's doing nothing. Is that is that been also your experience that it happens in a lot of organizations and a lot of websites?

Aden Bai [00:22:11]:
Yeah. That's definitely one of the problems. It's also I don't think it's necessarily engineer's fault. Right? It's really hard to care about these things because they're not visible. Just like if the page UI is not correct, it's very visible. You have to fix it. If there's an error, you have to fix it. Right? It's not like you can avoid these things.

Aden Bai [00:22:29]:
The performance you can pretty easily avoid because most developers use, like, a really high end MacBook or high end PC. Where you can, like any performance problem, you can blaze through and, like, basically hit with no problem. And, also, developers are so used to slow build tools and slow, like, development server start startups that, like, one hundred, two hundred, three hundred milliseconds, it feels like nothing. So the problem is performance is not visible, and developers are really out of touch in touch with users for performance. Like, even even if even for, like, performance experts who, like, think about performance every day, they're also not super in tune with, like, the actual product's performance. Like, maybe they go to Datadog and they see the metrics, and they're like, okay. How can I improve this today? Or they see a regression in performance after a specific git commit. But then it's like, okay.

Aden Bai [00:23:21]:
What do I do? Like, how do I reproduce this? It's kind of hard to do those things. React scan is, our attempt to try to fix some of this. Right? Like, how, how do we make performance visible? Like, how can we show developers that there's problems on the side without, like, having them loaded up on a Moto g four or something?

Dan Shappir [00:23:42]:
Moto g four, by the way, for those of you who are too young to know, is an old Motorola phone that Google still uses virtually for, simulating performance of websites on low end devices. Yeah. If you're using Lighthouse, that's what they use there. Okay then. So you want to, visualize the performance issues. How do you go about it? What do you actually show? How do I see that I have a a performance issue in my React website? By the way, the tool is for React. Right? It's not, you know, for websites that aren't React based. Correct?

Aden Bai [00:24:22]:
Yeah. React for now. Right now, we highlight renders. And if there is some sort of long task or FPS drop or INP that's really high, we turn the color of the renders to, like, from purple to, like, red or something. In the future, we wanted to have more visualizations. Like, when I click a button, what is the INP or, like, the local tested INP? We have, like, or, like, what is the, like, long animation frame like, when a long animation frame happens, I want to see that the long animation frame happened. I wanna understand, like, when jank happens or when jank happens, what is the cause of that jank? Renders us, like, our base abstraction, basically. Like, usually, it's always related to it's, like, always somewhere within the problem, and so we show it via renders, basically.

Dan Shappir [00:25:13]:
So, basically, if I understand correctly, you're adding rectangles around the React components that get get rendered.

Aden Bai [00:25:22]:
Yeah.

Dan Shappir [00:25:22]:
And these component and these, borders kind of highlight whenever the component renders. So if if it's constantly highlighted, you know, that this component is, for some reason, being constantly rerendered. Right? Yeah. And and by the way, again, rerendering is at the virtual DOM level. So even a component might be rerendered even if nothing actually is changed for it in the actual browser DOM. Correct?

Aden Bai [00:25:55]:
Yes. Yes.

Dan Shappir [00:25:57]:
So it's it's your code and React code doing work for that component whether or not anything actually gets updated in the actual display.

Aden Bai [00:26:07]:
Yep.

Dan Shappir [00:26:09]:
And, usually, the border would have one color. What is it? Like, you said purple or something like that.

Aden Bai [00:26:16]:
Mhmm.

Dan Shappir [00:26:16]:
But if it's resulting if it's causing, the browser itself to actually experience delays, then it will actually change color and become red.

Aden Bai [00:26:28]:
Exactly. Yeah.

Dan Shappir [00:26:30]:
Very cool. So I assume you've tested it on various websites and saw them flashing rectangles all over the place. Can you give, like, interesting examples?

Aden Bai [00:26:42]:
A month ago, I founded this performance problem on the GitHub site when you would scroll on the code view, every line of code will be rendered. So I I tweeted it. It got a lot of likes, a lot of views. And then I don't remember their name, but someone from the like, the VP of DevRel at GitHub was like, hey. One day later, I was like, hey. We fixed this issue. And when I tested it, the FPS increased, and I was like, holy crap. Like, it's it was really cool how just this random package, we made, and then just tweeting it out and just showing a video of it actually made a real performance change on the site.

Aden Bai [00:27:18]:
Yeah.

Dan Shappir [00:27:19]:
Yeah. That's really cool. And my my experience is that it's exactly that, that it's very difficult to notice that the problems exist, especially, like you said, when developers have really high end, Macs and stuff like that. But once you understand where the problem is, in a lot of case not all cases, but in a lot of cases, the fix is fairly straightforward. You've got, let's say, some use effect that's updating a state, which is retriggering the use effect, which is, again, updating the state and and and over and over and over again in in this kind of an infinite rendering loop, something along these lines.

Aden Bai [00:28:03]:
Yeah. Yeah. The the the main hard part of performance isn't the solution. The solution space is actually really small. It's usually, like, one to five solutions for every problem. But finding the problem is the hard part. It's almost 99% of the work.

Dan Shappir [00:28:25]:
Yeah. I I totally I totally agree with that. By the way, I'm just there are a lot a whole bunch of silence in the background, so I apologize for being a bit distracted. Yeah. I I that totally matches my own experience that it's sometime that I being able to pinpoint the cause of a performance issue is the hardest problem. But you know what? In that regard, it's not that different from a from a lot of bugs. You know, the the famous Heisenbugs that that happen occasionally are very difficult to reproduce and figure out. And then, you know, you smack your head when you realize what the problem is because the fix is often very, very straightforward.

Dan Shappir [00:29:09]:
My question then is how were you able to get this information out of React? I mean, you know, React doesn't exactly tell you that, hey. You've got a performance issue. It just does this whole rerendering thing kind of automatically behind your back. So how did you figure this out?

Aden Bai [00:29:30]:
Yeah. Most simply, so React dev tools has information about componentry and renders. Well, how does it do this? Well, React internally has a it attaches, like, a property on the window object called React dev tools global hook, and it has much of information about the fiber tree. And so, ReactScan internally uses that to get information about fibers. Just for context, a fiber is basically like the virtual DOM, how React internally represents the user interface. We can use the fibers to detect renders, and then we show those renders using a canvas on the screen.

Dan Shappir [00:30:12]:
So based you're using a you're not modifying the CSS. You're actually using canvas in order to draw the stuff on the screen?

Aden Bai [00:30:22]:
Yes. If we modify the CSS, there would be, like, some overhead on that. And so any performance score you would see is going to be noticeably like, it's gonna be artificially inflated. So what we did was we put the canvas on a worker thread so it doesn't have as much performance impact as if you actually modified the CSS.

Dan Shappir [00:30:42]:
Ah, cool. So what you're saying is you kind of put, an invisible, canvas on top of the entire rendered screen, I guess. And your and Canvas can be updated from a worker thread off of the main thread, which is not something you can do with the regular browser on. So you're able to, I draw into this wholly separate user interface GPU layer without impacting the rendering time of the actual, browser at all. That's very, very cool.

Aden Bai [00:31:27]:
There's a little bit overhead because we have to still send the data over to the worker thread. But from our testing, it's pretty minimal. It doesn't affect, like, the standard metrics as much.

Dan Shappir [00:31:40]:
I understand. But, for example, you still need to, for example, get the rectangle the actual rectangles on the display of of, the, dome elements. And if they they're scrolled, you kind of need to move the rectangle along with them or something or or things along that line.

Aden Bai [00:32:01]:
That's right.

Dan Shappir [00:32:03]:
So that does still take a little bit of overhead in terms of of work on the main thread. But, basically, you're just firing that, throwing that over into that worker, and it does the heavy lifting.

Aden Bai [00:32:16]:
Exactly. Yeah.

Dan Shappir [00:32:18]:
Have you measured the impact, performance impact that having React scan on the site actually has? Because that's that's indeed a real problem that, you know, it's kind of like quantum physics where where where you're measuring things, can actually impact the behavior of the application. Like, I recently saw a tweet about somebody saying that he had a bug in their in in his code. He added a log. The bug the bug went away. He removed the log. The bug came back. So sometimes even the act of measuring can really impact the performance and behavior of the of an application. So how how did you actually verify that you have hardly any impact on the run time of the application itself?

Aden Bai [00:33:06]:
Measuring here, like, it's, like, not really a good way to figure out the overhead. Like, basically, we run on dev, which means it's using development builds, which is not the same as a production build. So development builds will likely be slower than production builds. On a basic app, it's around it's, like, less than 1%. On a more heavy app, it's still less than 1%. But, like, in reality, we like, you can you have to, like, measure on, like, a large scale applications and actually on the correct build of of the app to understand the overhead. Right now, it doesn't matter too much. But, like, as as I said, like, it may be so for some edge case, it might be much more.

Dan Shappir [00:33:51]:
Question. As you said, you're using the same APIs that React DevTools uses internally. In fact, by the way, undocumented APIs as as I understand. What is the advantage then of using React scan over just using React's own developer tools for essentially the same purpose? Because they also have a performance view in there. If if you install the Chrome extension for the React developer tools, for example, you get a performance tab a React performance tab in the developer tools. So what's the advantage of of using a React scan over that capability that React provides themselves out of the box.

Aden Bai [00:34:41]:
Yeah. Like, I view React DevTools as, like, the end game of DevTools. Like, it's it's a great version. There's obviously improvements that it can make can be made, but it's, like, the best React dev tools we have today. Right? The problem is, like, you need kind of, like, a there there's there's there's, like, a very low like, you you have to be decently skilled at using React dev tools or Chrome dev tools in order to use those dev tools. And most people don't really know how to do it. React scan is a more accessible version of it, specifically for rendering and performance app performance issues inside your React app. React React app tools is a more general, more advanced dev tools for interacting with your app.

Aden Bai [00:35:29]:
Yeah. I use So I use React scan and React dev tools, for my use case.

Dan Shappir [00:35:36]:
Oh, okay. Cool. So when I use React scan, is it does it even require the dev tools to be open, or do I just see everything on the browser's display itself?

Aden Bai [00:35:49]:
On develop in development, you just drop a script tag into your, like, head tags, and then it should work.

Dan Shappir [00:35:56]:
And you don't need to open dev tools at all?

Aden Bai [00:35:58]:
No. No. Yeah. You just have it. It just runs.

Dan Shappir [00:36:01]:
You know where that's, potentially a very significant advantage on mobile devices. The fact that I can just drop in a script tag and see the issues on the browser's screen itself is a big advantage in terms of identifying such issues versus having to attach the the phone a phone a physical phone via physical wire to a Mac or PC in order to open a remote debugger and then debug everything that way. It's a much more convoluted process. If I can just see all the problems directly on my mobile screen, that's a huge advantage from my perspective.

Aden Bai [00:36:48]:
Yeah. Yeah. It seems like a really good use case.

Dan Shappir [00:36:51]:
Now do you only show the squares or with the colors, or do you show additional information there?

Aden Bai [00:36:58]:
So it do, show some additional information on the screen itself. So each rectangle will have a little label on it showing the component name and also how many times it renders and how much time it took. You can also in you there's, like, a in browser toolbar. You can inspect any component or render to see when it renders. You can replay them. You can see what props change, what state change, what context change, and you can just figure out exactly what are the props or attributes or information about the React component that are causing the problematic performance.

Dan Shappir [00:37:33]:
Wow. That's really, really cool. By the way, when I drop in that script tag, does it, automatically enable this u, this, UI, or do I also need to do something in the browser itself to enable it? Because I'm thinking that in some cases, people will want to have that, script tag be present, you know, always, but not have all the users seeing those rectangles?

Aden Bai [00:38:05]:
Yeah. By default, it only runs in development. We do offer, like, programmatic off and on APIs. So, like, companies like Notion or Shopify, what they do is they or sorry. Yeah. Shopify, Notion, they have an internal toolbar. And, basically, you can click, like, turn React scan on, and it turns the it opens the react scan overlay and toolbar.

Dan Shappir [00:38:30]:
What you might want to do, as well is maybe add the support for a special URL parameter so that you could turn it on or off using a URL parameter that, you know, doesn't hopefully, doesn't conflict with anybody's URL parameter, but that would make it especially easy, especially on mobile. I'm thinking that that would be very useful. We did similar things at Wix where we added, special debugging capabilities into Wix websites, but they were only enabled with a very specialized unafit well, not document an an not externally documented URL parameter. Obviously, nothing that could actually break a website. You know, you need to be careful because there are potential, security issues around that. You know, somebody could send a link with that URL parameter to somebody, and then they would see the the red lines. And then they would get all freaked out because they would think something is wrong or something along these lines.

Aden Bai [00:39:38]:
Mhmm.

Dan Shappir [00:39:38]:
But in general, I think that, this can be, a re a useful feature.

Aden Bai [00:39:45]:
Yeah. That's awesome. We'll add it right after this podcast.

Dan Shappir [00:39:48]:
I'm glad that I can help make the product better. I also saw various demos that you were showing about all sorts of ways to graph the component hierarchies in in, in the React application. Is that also part of the same thing?

Aden Bai [00:40:06]:
We haven't shipped that, but we're we're just playing around with what visualizations would work. So, like, for context, I was working in this really large enterprise ecommerce app, and they had a bunch of components depending on the same context. But it was really convoluted. Right? Because there were, like, nested hooks. There was nested components. Like, a bunch of stuff was rerendering. I didn't know why. So, I spent, like, ten hours just on TL draw, graphing out the entire code base from the root that was rerendering.

Aden Bai [00:40:38]:
And I was like, why the why the heck am I doing this? Like like, this is, like, so much work just to figure out why all these components are rerendering. One thing we wanna do this do try is doing this automatically. Like, can we graph out the component tree and also the hooks tree, and show where the source of the problem is? Most, like, re rendering issues, like, they can be caused by a higher component or a context. But, usually, they're systemic. Right? Like, it's usually, like, one context causing all of these components to rerender, and all of these components have faulty implementations that cause this performance issue. So we're we're trying to we're trying some visualizations to help fix that.

Dan Shappir [00:41:19]:
So, we have a user from LinkedIn who asked, what is the business model for the ReactScan project? Is there a cost to using ReactScan? I'll fill in the blank. Is it open source? Is it free? What's what's your business model around this tool? Are are you is it already released? Is it beta? Where are we at? Yeah.

Aden Bai [00:41:40]:
It's it's, it's not one point o, but it you can it's stable. You can try on your app. It's free, open source. You can copy the code. You can fork it. You can do anything with it. If your company requires it to be hosted on our internal package, you can do whatever you want. The way we make money is through monitoring and observability.

Aden Bai [00:41:57]:
So we have a different product that uses ReactScan on, in in, like, ETE or staging environments. So you can run your Playwright test. We figure out the performance scores of this playwright test and tell you whether the performance increased or decreased. This is a real this is a real problem because, like, most observability tools like Sentry, Datadog, they're really confusing. Right? You have to, like, read profiles. The graphs are somewhat, like, weird. Like, I I and it doesn't really tell me, like, what is the root cause of the problem. We're trying to solve this.

Aden Bai [00:42:31]:
We're trying to do this specific solve this for React.

Dan Shappir [00:42:34]:
So it's it's essentially a performance budget tool for React applications.

Aden Bai [00:42:40]:
Yeah. Exactly.

Dan Shappir [00:42:41]:
By the way, for again, performance budget is something that we mentioned in previous episodes. For those of you who don't remember or don't know what it is, a performance budget is a way to say, like, specify how much how performant I expect my application to be. And then during the testing process in your CICD, flow, you can measure the performance of of the latest build, compare it to your budget limits. And if you exceed your budget limits, you essentially break the build like you would for any other bug. And then the only way in which you can release it is either fix the performance issue that you're under budget again or, unfortunately, in some cases, you might need to increase the budget because maybe you just made the UI more complicated and sophisticated, and therefore, it's a legitimate decision to make. But you you're you're doing it, with full awareness of what you're changing. It's not just something that happens and you're not even aware that it's going on, that your application is becoming slower.

Aden Bai [00:43:50]:
Yeah.

Dan Shappir [00:43:51]:
So you're building a performance budgeting tool that's focused on React application. It's not just working at the core web vitals level. It's it's focused on React, and it helps you understand, how your React application is actually working in terms of performance. And if you exceed your budget, not only does it break your build, but it also tells you where the problem like is likely at.

Aden Bai [00:44:16]:
We do also do core of vitals. So, basically, the data hierarchy is interactions. So if interaction becomes slower on your playwright test, that's a problem. Then we go a little bit deeper out like, if an interaction is slow, what components may have caused that or what components under where may have caused that and then potentially, like, down to the render. Like, what props, context, or state may have changed?

Dan Shappir [00:44:43]:
Now what I'm thinking that might be really useful in this context is something although of the I'm not exactly it's more of a vague idea that I have rather than a plan. But, you know, one way in which, React performance is improved in, at least in perceived performance, if not actual performance, is using, suspense by, deferring rendering of certain non urgent UI components. Maybe they are on maybe they're outside the visual display area, or maybe they show lower important information or stuff like that. How how do you handle those? Can you recommend to me that this thing should be should you suspense or or stuff like that? Is that something that you're thinking about or looking at?

Aden Bai [00:45:41]:
Yeah. Of course. That's all in scope, basically.

Dan Shappir [00:45:46]:
Cool. And so any, like, hints about what you're thinking about doing in this context?

Aden Bai [00:45:55]:
Specifically for so there's couple applications. Like, things outside the viewport, will and it rend if it renders, we mark that as, like, an unnecessary render. Like, there I mean, like, obviously, there are different solutions here. Like, first, maybe don't render it or maybe there are some, like, hacky solutions for, like, partial hydration. Like, don't hydrate unless it's viewed, or, like, suspense as you're saying. We don't do recommendations yet, but we do detect the problems itself right now.

Dan Shappir [00:46:29]:
Okay. So when you're doing, when you're high doing the that rectangle highlight, if the rectangle is wholly outside, the visual the visual viewport, then it gets kind of flagged and logged that, hey. This was an unnecessary render. You should be doing something about avoiding avoiding that.

Aden Bai [00:46:53]:
Exactly. Yeah.

Dan Shappir [00:46:55]:
Or postponing that or or something along these lines. Mhmm. That's very, very nice. So you said that you're using both React scan together with, the re with the React dev tools. What where do you focus what information do you get where? Like, what what's the benefit of using them both together?

Aden Bai [00:47:22]:
Yeah. Anywhere from, like, skill level zero to skill level maybe 70 or 80%, which is basically, like, looking at the renders where they occur, inspecting components with props change or components change, I use React scan for. For React DevTools, I use the profiler component. So, like, it shows, like, a timeline of, like, what functions ran. I also use the Chrome dev tools profiler. And then sometimes I use the componentry provided within React dev tools. Like, obviously, if React dev tools works for you, you should use it. I recommend giving React scan a try.

Aden Bai [00:47:54]:
If it works better for certain use cases, you should use it for use case. If it doesn't, then then don't.

Dan Shappir [00:47:59]:
One more thing that you might try to do, assuming it's not too complicated or doesn't have too high overhead in in and of itself, is that if the user hovers on top of one of those tooltips, then that you render on the canvas, then you can could display additional information, like what caused the latest render or stuff like that, things that wouldn't fit inside the tooltip in its own in of of itself. Again, anything that can save me the need to have to open Chrome DevTools and go back in history would be very beneficial. Obviously, a problem with hovering is that it doesn't actually work on mobile devices, so maybe a click on those.

Aden Bai [00:48:42]:
Yep.

Dan Shappir [00:48:42]:
You know, tapping on the tooltip or something along these lines, that that could be that could be useful. Again, especially because on mobile devices, access accessing dev tools becomes a lot more challenging. So anything you can show on on the mobile display itself is is very beneficial.

Aden Bai [00:49:00]:
That's an amazing idea. Yeah. It's not perfect. I'm just getting this is like a user interview.

Dan Shappir [00:49:08]:
Well, you know, performance is my jam. So, you know, I've been doing this for a long time. A long I wouldn't say longer than you've been alive, but, starting to come on that. So, yeah. Anything else you wanna tell us about your tools or or things that you're looking at doing or things that you want our listeners to know about?

Aden Bai [00:49:32]:
Yeah. I mean, if there's one thing you should listen, do is performance matters a lot, like, probably more than you expect. And even if it I mean, like, even if it doesn't matter at your company, like, peep leadership doesn't really care, you should try, at least, see if it maybe will improve some metric for users or improve your sales. If you're just an individual user, try learning how performance works, upscale yourself. Performance, like, from my experience, there are not that many performance experts, and there's a lot of need for performance experts. And so from a job opportunity perspective, there is also there's an opportunity there. So learn performance, try react scan if you want to, and yeah.

Dan Shappir [00:50:22]:
In this context, by the way, there's the act excellent web.dev website, which is actually run by the, Google Chrome DevRel team, I think. And they have a section there called case studies, case dash studies on web.dev, which basically is just this huge list of case studies of companies that improve their performance and got a huge boost to their sales or bottom line or whatever as a result. So if your company doesn't care about performance and you need to convince management that performance is actually important, then web.dev slash case dash studies is a great resource to use in this context. And I totally agree with you, that having good performance is is a game changer in many cases. It it's the whole difference between an application that's pleasant to use, that's engaging, versus one that you hate using because it's janky and unresponsive.

Aden Bai [00:51:29]:
For sure.

Dan Shappir [00:51:29]:
Yeah. And it's also an accessibility thing. And, it's it's about enabling people who might otherwise not be able to use your application to actually use it and benefit from it. Because, again, like you said, if your application was written by people with really high end devices, fast Macs, fast iPhones, and they never bother to check on lower end devices

Aden Bai [00:52:12]:
Yeah. Exactly. And and you'd be surprised the amount of ecommerce companies where performance actually matters to sales that don't monitor monitor performance or care that much. And so what happens is they are literally losing out on, like, 7 to 8 figures sales every year.

Dan Shappir [00:52:30]:
By the way, again, speaking about React, we had Rick Vickscomi from, Google on our show a few years back, and he runs this great service. I don't know if you're familiar with it. It's, it's, Chrome user experience report or CrUX. Yes. And they have this website where you can actually see the performance graphs by technology. So Google literally grabs performance information from your browser unless you opt out from your Chrome browser, and they upload it into their database, anonymously, of course, or at least so they say. And then they and there, they run all sorts of analysis on it, including which technologies it uses. And that makes it possible, for example, to see how good React websites in general are in terms of performance.

Dan Shappir [00:53:26]:
So we mentioned, the the three core web vitals. A a good a site is considered to have good performance if it has if it's good for all three core web vitals. That means that it's fast enough at the seventy fifth percentile for LCP, for CLS, and for INP. For example, LCP needs to be faster than two and a half seconds at the seventy fifth percentile as I recall. Yep. And it turns out that if you look at React websites, can you guess what percentage of React websites in in the totality of all React websites actually get good core vitals?

Aden Bai [00:54:10]:
If I were to guess, maybe, like, 10 to 20%.

Dan Shappir [00:54:13]:
No. You're being overly harsh. It turns out well, it used to be that way, but it turns out that the browser makers have been doing a phenomenal job of of, improving the performance of the platform itself. So even though React websites may in and of themselves may not have improved that much, just because the browsers have been getting better and faster and more sophisticated, then there's the React scores have gone up. In fact, all website scores have gone up.

Aden Bai [00:54:46]:
Amazing.

Dan Shappir [00:54:48]:
So, so if I look so we were at 20% on React websites, back in 02/2021. So in April 2021, we crossed the 20%, threshold. Now React websites are 41 have good core vitals.

Aden Bai [00:55:13]:
That's phenomenal. Yeah.

Dan Shappir [00:55:14]:
That means that almost well, 59% don't, which is the majority of React websites, which is truly unfortunate. By the way, if we compare to other technologies, WordPress is slightly ahead of React. So people building WordPress websites, they're the, they are at 43%. So they are 2% better than React. So you're thinking you're a hotshot React developer and I'm talking to our listeners. There's a good chance that the WordPress website built by some web designer has better performance than your sophisticated React website. And if I'm looking at other technologies, like you mentioned Shopify, Shopify is at 76%, and Wix, for example, is at 65%. So, 76% of all shop of all the Shopify websites have good core vitals, and that's almost double React.

Dan Shappir [00:56:16]:
That's pretty that's pretty unfortunate from my perspective.

Aden Bai [00:56:23]:
Yeah.

Dan Shappir [00:56:26]:
And, hopefully, with hopefully, with tools like React Scan, people can make their React websites, more like, load faster, be more responsive, and generally be more pleasant and more accessible to use. By the way, have you saw also thought about doing things related to accessibility in your application, or are you, for now, focusing wholly on performance?

Aden Bai [00:56:51]:
For now on performance, but that'd be a cool extension if there, if there is a enough of enough of a need for that.

Dan Shappir [00:56:59]:
I think there there should be, but, you know, it's your business. So if people want to try out ReactScan, like you said, it's open source, it's free to use, how can they go about it? And if they want to try out your more sophisticated, tools for the CICD pipeline, how should they go about it?

Aden Bai [00:57:21]:
Yeah. You can just go to reactscan.com. That's react-scan.com or just look up React Scan on Google. There there's resources it tells you how to install the basic React Scan, and we have another page called monitoring, which should be on the website that you can click on and then try to demo and then add to your website yourself. It should React Scan takes less than a minute to set up. Our monitoring service takes also probably less than five minutes.

Dan Shappir [00:57:49]:
Is it also possible to add it to a page using NPM, or is it just via script tag?

Aden Bai [00:57:54]:
NPM script tag, you can run it via your CLI. There's there's, like, four ways to do it.

Dan Shappir [00:57:59]:
Cool. Anything else that you wanna mention or talk about in this context?

Aden Bai [00:58:06]:
Not at all. I just really, really grateful to be a on this podcast, and good to talk to you again, Dan.

Dan Shappir [00:58:12]:
Yeah. Same here. I love talking about performance, and I I love seeing somebody so young, so into it, and and making such an impact in this context. You know? Bringing anything we can do to improve the situation with React is is great in my book. I mean, at the very least, we need to be above 50%. I mean, at the very least, more than half the React websites should have good performance. By the way, what is also surprising to me and and even more unfortunate, can you guess what the situation is with Next. Js?

Aden Bai [00:58:49]:
Is it lower than React?

Dan Shappir [00:58:52]:
Surprisingly, it is. You would expect it to be higher because it provides SSR and SSG, which are great for, LCP, but but it isn't. I actually have a talk that I gave on this topic trying to kind of analyze why that is. But the bottom line is that, as I said with React, it's 41% of React websites Mhmm. Or websites using React would be a better way of phrasing it, have good core vitals. With Next. Js, it's only 28%.

Aden Bai [00:59:26]:
Yeah. I'd be curious why. That's interesting.

Dan Shappir [00:59:29]:
Yeah. I I'd be curious why as well. I'm guessing part of it is maybe having to do with the long tail of of old, Next JS versions, maybe not installed on Vercel, maybe installed on on AWS and not properly optimized. But it's a good but it's a good question of why that is. And like I said, I have several theories, and I've I've even given talks on this topic. So if if you're running a conference and you want to hear my opinion of about why some frameworks are faster than others, then invite me to to speak at your conference. Anyway, okay. I think with that, I'll be pushing us to that final part of our episode, which is the picks part.

Dan Shappir [01:00:17]:
I didn't give you a heads up for it. I hope that you came prepared nonetheless. I'll go first so you have time to to choose. Okay. Basically, picks is where we shout out whatever. It can be technical things. It can be nontechnical things. It can be your favorite movie, TV show, band, whatever, book.

Dan Shappir [01:00:40]:
Do you still read books? And, and, and, you know or or technical things that you wanna just, you know, shout out about, including your own. So I'll start with mine. I don't have a lot in the way of picks. I have just one. So I've I'm from Israel, from Tel Aviv in Israel. Obviously, the situation here has been really unfortunate over the past, year with the over a year, almost a year and a half with the war going on and a lot of suffering and loss of life. At least we got some really great news as yesterday as of the time of this recording where a ceasefire has gone into effect. And in particular, three Israeli hostages were released.

Dan Shappir [01:01:37]:
They were held in in captivity by Hamas for, for four hundred and seventy one days. Just imagine being held in a tunnel underground with the threat of death constantly hovering over your head with hardly any food and no ability to move, and and some of them were also victims of abuse, even sexual abuse. It's it's very distressing. So three of the hostages were released, yesterday as part of this agreement between Israel and Hamas. Their names are Doron Steinbacher, Emily Damari, and, I should have come better prepared, and Romy Gonen. Two of them were actually abducted from their own homes. So on 10/07/2023, Hamas terrorists broke into their home, kidnapped them literally out of their beds. One of them was shot.

Dan Shappir [01:02:47]:
She lost, some fingers in her hand, and they were taken into Gaza literally in their pajamas. The third one was kidnapped from the Nova music festival. Again, she was also shot and and wounded, and and they never got medical attention for that. And I'm really happy that they've been finally been released and reunited with their families. Hopefully, they'll be able to make a full recovery from this ordeal. Obviously, it's it's not simple, but, and that still leaves 94 hostages, Israeli hostages, in Hamas' hands. I really hope that the, ceasefire can, persist, and these hostages will be released eventually as well, hope hopefully, as soon as possible. And that would be my pick for today.

Dan Shappir [01:03:38]:
It really brought joy to my heart yesterday when when the these hostages were finally released. And that's my pick for today. Do you have any picks for us, Aidan?

Aden Bai [01:03:52]:
I have one thing. I am much less, much less important. But Yeah. I really I I mean, I I knew this since a while ago, but I really like the the proxy API in JavaScript. So, basically, you can wrap any object in this, like, proxy keyword, and then you can spy on any property. So if you access, like, object dot name, you know when that you can, like, programmatically know when that, property is accessed.

Dan Shappir [01:04:20]:
Oh, yeah. Proxy is really cool. Yeah. Basically, you take you do a new proxy and you pass in the object you want to, what would be the instrument or track. And like you said, any access to either read a property from that object, write a property to that object can be tracked, can also be modified, by the way. Yeah. So you can kind of it it the the one thing to be careful with, by the way, in this context is that it can be used and it was in fact created for that purpose to kinda break JavaScript semantics in a sense, because you can override the standard JavaScript object behavior with, with proxy. I've actually done exactly what you described.

Dan Shappir [01:05:06]:
I had a problem in an application Mhmm. A legacy application that I was trying to refactor. Some code was modifying a global object, and I was unable to locate where that modification was happening. So I literally created a proxy around that global and put a debugger statement in the property set. And and that way, I I when the the break happened in the in the developer tools, I had the call stack, and I could find where that operation actually happened. That was, I felt like having a superpower when I was able to do that. Yeah. Proxies are very powerful.

Dan Shappir [01:05:48]:
By the way, another use of proxies, I don't know if you know this, but, Vue, I think, uses proxies at least in the development mode, to implement their reactivity.

Aden Bai [01:05:59]:
Yeah. I think Valteo and then some other state management too. Or you can use it to, like, for for if you wanna get fired, you can use it to prank your coworkers.

Dan Shappir [01:06:12]:
Okay. Now you have to tell me. What did you do?

Aden Bai [01:06:15]:
I haven't done it, but I was thinking of replacing, like, yeah, like, we have an internal library, like, returning a proxy and having all the properties return undefined or something. But, yeah, Something super stupid.

Dan Shappir [01:06:29]:
Yeah. Okay. You know? Well, boys will be boys or devs will be devs, I guess. Yeah. Anyway, Aidan, it's been really fun having you on the show. I'm really excited about the stuff that you're doing. I'm really happy whenever something comes along which makes it possible to improve performance on the web. We we definitely need more of that.

Dan Shappir [01:06:53]:
And, it's it's amazing to see somebody so young making such an impact, and, I hope to be hearing more great things from you and having you on the show again to talk about more stuff that you're doing.

Aden Bai [01:07:06]:
Yep.

Dan Shappir [01:07:07]:
Now

Aden Bai [01:07:07]:
Thanks for chatting.

Dan Shappir [01:07:08]:
And now if people want to contact you about, you know, your existing projects, more ideas for what can be done and improved with these, or maybe ideas for future projects, how are what's the best way to reach out to you?

Aden Bai [01:07:21]:
I'm on Twitter, Blue Sky, YouTube. Just look at my name, and then you can just DM me, and I'll answer you.

Dan Shappir [01:07:27]:
So it's Aiden Bai on all those platforms?

Aden Bai [01:07:30]:
Aiden Wei Bai. Yeah.

Dan Shappir [01:07:32]:
Aiden Wei Bai. Okay. Great. So again, Aidan, thank you for coming on our show and to all our listeners, thank you for joining us. And that's it for today. Bye.
Album Art
Exploring ReactScan: Aiden Bai's Tool for Identifying React Performance Issues - JsJ 668
0:00
1:07:49
Playback Speed: