 We've spoken a lot about how fast you want to load your page and how you want to optimize for the time to first frame, time to first byte and so on. So what we'll see in detail is like once application is loaded, how can you measure and optimize the rendering of your application? So before we deep dive, we'll just quickly rush through a few of the concepts which kind of happen when a rendering is happening in the browser. So just to, I think this has been mentioned before by Ankit in one of the previous talks. So during the critical render part, so your browser kind of records the HTML, it's such as a DOM, passes it, creates a DOM tree. It also fetches CSS files and if there are inline styles, it creates a CSS object model out of it. So if there is, I mean, we often do like load a lot of JavaScript, add HTML from JavaScript and also add more styles from JavaScript. So once the DOM and CSS are created, the browser kind of creates something called a render tree. So render tree is actually a visual one to one map of what you see on the browser. For example, if you have any elements that have a discipline and property, it kind of eliminates that and so on. So once the render tree, the browser knows what needs to be rendered, it kind of creates, I mean, calculates the layout for the whole render tree, which means it kind of calculates the dimensions of what should go where. And then finally it paints, flushes out after the layout, since I've done, it kind of paints all the pixels on the browser. Essentially what the browser does is it kind of writes to the screen buffer via the graphics engine and then your operating system kind of renders the pixels. So just to summarize, if you have a simple HTML like this, where you have a under head meta tags, link tags, then a couple of paragraphs or tags inside your body. So it kind of calculates the DOM as well as the CSOM, which accompanies that. And in the render tree, if you see wherever we have display none, it has been eliminated and so on. And once this is calculated, the browser calculates the layout. So remember always to ensure you add the meta tag for width equal to device width and also the initial scale, whatever you want. So that the browser can take what is available width. And based on that, for example, here the first div has a 50% width and then another div inside has another 50% of that, which is like overall 25% of the whole viewport. Then it kind of flushes out, I mean once the render tree is created and the layout is calculated, it goes ahead and throws the object out for a paint. So just to analyze a little more around this wheel, I'm just running a video for the sake of saving time. But yeah, when I mean to look at how your application is rendering, I mean, one of the best tools you can use is the Chrome developer tools. For example, let's look at a site called diverse UI where it has a bunch. I mean, it has a page loading a lot of photos that are loading in it. So if you see the DevTools, when you open it, you have a tab called Timeline as well. So if you open that, you kind of have various options to what you want to profile here. You can look at like network at the top, network.js profile. Then you can also grab screenshots of what is happening at during the time that the page loads. You also have, you can also track memory, how memory is utilized during the rendering of this and also the paints and so on. At the bottom, you also have, like if you actually hover on the timeline, you can actually see when you actually check screenshots, you can the DevTools actually captures the screenshots and you can actually see at what point your page actually loaded and started loading other images and so on. And if you can also on the timeline, you can actually click on it and kind of it's like a sliding window. You can choose where you want to track and at that point, whenever you focus, it kind of also gives a flame chart below of what is happening on various threads. So for example, here on the main thread, we have a bunch of stuff happening at that, near the end. Let me just zoom in a little and show. If you see this point, you kind of also see like there is an FPS graph here. There's also a memory graph, I mean, CPU utilization graph. There's a tiny network graph above the screenshots as well. So just zooming back. So the other thing is like, I mean, this also gives a consolidated view. If you check on the network, checkbox at the top, you can see, I mean, apart from the network tab that you might have used a lot for looking at the page load time. It actually gives that view here as well, so that you can compare it with the flame chart with the network loads, how it behave and so on. At the bottom, so just more the video a little, yeah. At the bottom, if you see, there is a summary pie chart that is given where you can actually see what time scripting took, what time rendering took, what time like pains happened, and what time the page loads happened and so on. There's also one very interesting tab there called bottom up, where you can actually see a vertical event log of what has happened during the timeline. You can actually group it by activity of what happened. You can group it by domains, and you can analyze which domain is taking a lot of time. I mean, it gives the total time taken for each. If you have some notorious domains which kind of take a lot of time, you can actually probably block them and remove them from your site and so on. Also, you can see the call tree. The one more interesting part is the event log, where you can actually see what happened. The flame chart shows in a horizontal manner, according to other panels that you have vertically there, but here you can actually see at what point each of the events happened, when did the loads happen. You can actually filter it just to see what kind of loads happened. You can see a lot of send request events there because it kind of is loading so many photos little lazily. So if you just check the scripting tab, then you can actually see that there were a bunch of timers fired and also through JavaScript, there were requests started, mainly probably for the images there and so on. Similarly, you can actually see at what point the layout events happened, whenever you add new styles, how the styles were recalculated and when it happened and so on. Similarly for paint and so on. So one thing is like so far, good performance is not just loading fast, but also running well after the page has started loading. So now let's, now we have seen how the page loads and kind of monitor what happens. A lot of parse HTML events happen, a lot of send request events happen, layout events happen and so on. But typically once the application is loaded, as the users interact, you essentially have your JavaScript kicking in kind of it adds newer markup or style elements. And this kind of forces the browser to if this new markup added or a new styles added, it needs to do a layout calculation again and then kind of push the data out for painting. So one of the things that happens in the browser is each of these, I mean for painting, it kind of paints in different layers, multiple layers that are stacked together. So once you actually render a layer, you kind of have to have a composition of these layers in the right order so that it can be sent to the GPU for painting the actual pixels. But how long do you have for doing all this stuff, right? So I mean one basic concept, I'll quickly run through it, is like you all have heard of device refresh rates. Essentially most devices refresh your screen at 60 times a second, which practically means you kind of operate at six, you need to operate your device operates at 60 FPS, which means per frame, if you calculate you kind of have 16 milliseconds. So a couple of terms that you need to always bear in mind is the frame timing, which is when the frame needs to be, I mean it's the time by which your application needs to take care of keeping the frame ready. And then after that, you have to calculate layout and paint and kind of produce a frame. And that is the budget that you have essentially. The budget, what we've already seen is 16 milliseconds. So let's go back here and kind of, DevTools also gives an additional feature for you, where you can actually, if you hit escape when your DevTools is open, it kind of opens a bunch of options. You can choose the rendering tab, open it. There is something called FPS meter there. So once you select that, it kind of starts an FPS meter at like top right of your application. So here you can actually see, for example, when I load the page, you can actually see what FPS it's operating on and so on. Right now I think it is somewhere on 5.4 FPS. We need to check a little more, okay? So that's how you can actually measure during each of your interactions, what is the frame FPS you're getting and you need to ensure you're close to 60 FPS. And best thing would be if you're always operating on 60 FPS. Else we kind of, when you skip frames and for a frame to render, if it takes more than 16 milliseconds, you kind of feel a little jaggedness, which is, which you call as junk. Given that you have to complete all these in 16 milliseconds, we need to, we'll kind of now analyze each of these phases and how we can debug and kind of better our code for these. So when you're doing only paint only changes, which means like if you're changing just a background image or just color of a font and so on, the browser kind of skips the load because it didn't recalculate your elements again, positions of your elements. It's just the pixels wherever you're changing needs to be redone. Ideally, if you, I mean, painting is also kind of a little tedious job for the browser because it needs to push all the pixels to, I mean, pixel information to the screen buffer and from there it needs to ensure it hits 16 milliseconds time frame, right? So ideally if you can avoid layout and paint, it is something that that's the space you want to be. If you are doing some animation, say for example, if you have a hamburger menu which kind of slides in and slides out and so on. So let's look at like how, if you are getting a janky experience, how can we go about it? Yeah, so first let us look at the JavaScript part, how you can look, profile and see where you need to concentrate, where you need to focus to improve on. So from the timeline, in the summary, you can actually see like for, I mean, this is for the entire page load during which you had like 668.4 milliseconds that is used up for just scripting like JavaScript execution, and so on, okay? So you can actually group by category here and then expand the scripting tree. You can actually see which file is taking how much time for execution and so on. So you can actually, some of them are like extensions that you have. So you can just ignore those because it's something that's on your browser. The other thing is if you focus on, if you focus on the red ticks at the top of the timeline, let me just zoom in a little bit. So the red ticks at the top, they kind of show you like where frames have been missed and long frame rates have been present. So at that point, if you focus on your window to that particular instance, you can actually see if the full calls a flame chart of what file, so these are like color coded by files and you can see what executed for how long and so on. So this gives you a lot more insights into what is happening at that particular instant of when your rendering is happening. So one of the ways to avoid this is, if you see, if you remember that rendering lifecycle, the first one is your JavaScript kicks in. But the point, you need to ensure that JavaScript starts executing at the beginning frame. So in 16 milliseconds, you need to start at zero. So request animation frame is a utility function that you have. We can give a callback to execute your JavaScript. It kind of ensures that whatever JavaScript is in that callback, it gets executed at the beginning of the frame always. So it kind of, we can request animation frame. You kind of, it returns an ID. You can also cancel the animation frame if you don't want to, if you want to stop the frame and so on. The other interesting thing that you have is request IDLE callback. This was something that was introduced recently. So what this does is, I mean through your rendering lifecycle, there are pain times, there are script execution that's happening, there is layouting that's happening. There's also some time when this CPU or the main thread is actually IDLE. Okay, so at this point, you can actually utilize, so for example, if you're doing some, say analytics calculations during the 16 milliseconds, which means you're adding, I mean, analytics calculation is something that will not really result in a frame paint, which means you can actually defer it for later. So that is where this request IDLE callback will help you where you can actually register a callback where you can execute whatever JavaScript doesn't, which doesn't result in a frame paint and so on. If you have more of computation that is happening, for example, say web SAP, it kind of does a lot of encryption. It can probably offload it to a web worker so that your main CPU main thread is actually freed off that computation time or that much CPU usage. So essentially you create a new worker and then interact with your worker with a post message mechanism and so on. So now we have kind of understood what we can do with JavaScript. There's a lot more techniques that you'll hear more about through this conference. These are some basic techniques that you can adopt right away. The next thing that you have to look at is the rendering part of how style and layout happens. Similarly, I would, I always love this bottom up tab here in the summary below the timeline. So you can actually see, I mean, at what point there is layouts, there are layouts happening and at what point styles are recalculated and so on. It gives a nice log and it also gives how much time each of these events took as well. So if you look at the event log and just filter rendering, I mean, filter by rendering, you can actually see which file triggered which event and how long it took and so on. So this actually gives you a good analysis of what is happening where, so that you can focus on like you can prioritize how you're kind of optimizing your JavaScript. The other thing that we often do is something like this where you interact with the DOM, get the position of an element and probably change some height and width of it afterwards and so on. So when you kind of do it in this fashion where you're actually reading something from the DOM, then kind of altering the DOM, it kind of triggers when you read again, it triggers layouts and when you write something, it invalidates whatever layout was triggered and kind of cancels that calculation because you're doing some changes again, which means you're actually just wasting the browser's time where it is trying to calculate something and you're kind of canceling it with some modifications that you're doing. So one very simple way to do avoid this is ensure you're clubbing your DOM reads at one place and then all the writes at one place so that the reflowers are triggered at the end. Yeah, that's at one instance. You can also leverage request animation frame for this and so that you can ensure whatever JavaScript modifications you're doing to the beginning of the frame and the layout calculation kind of happens later. So when you kind of adopt some simple techniques like this, you can actually reduce the number of style recalculations and layouts that happen to a very less number, okay? So this is just an example that is there but for the live stats, you can debug your application better. The last thing that you need to look at is how the paints happen, right? Again, you can filter your event log by paints and see for what paint, how much time is happening. So here, I think some of the composite layer painting, it took like 13.8 milliseconds which means it kind of has only about two milliseconds to do everything else, which ideally more often than not kind of results in a long frame. So the other way to see when paints are happening is when you hit escape again, it also has an option for enabling paint flashing. So here what happens is whenever you reload the page or whenever you want to track an interaction, you can enable this paint flashes so that it gives you insights about when a paint is happening and so on. For example, it was enabled and I've reloaded the page. So you can see a bunch of green rectangles appearing on the screen, so which means those areas have been painted by the browser and so on. So for example, whenever a new image kind of was received, it has to recalculate, I mean load those images there and so on. So that's where the paints happen. So as I said before as well, you need, I mean painting means essentially flushing out pixels data. So if you can avoid it, it will be great during say animations. Of course, there are phases in your applications where you cannot avoid a paint, but you need to ensure that it's minimal. So one of the, say if you're doing an animation, you can actually, some of the style properties that like transform on opacity, they kind of only result in a composite instead of a paint asset. So what this does, and also there's one more thing that was recently introduced, which was like, which was a style property called will change. So what this actually does is whenever you add will change to an element, it kind of creates a new layer for that element. So the rest of the page is in a layer below and when this layer is pulled out of the old layer, whatever animations you're doing, it will only paint this particular element because that's the only element that's present on this new layer. And the rest of the old layer, old elements that you have in the previous layer are not touched. So this kind of reduces the number of pixels it has to repaint. So that way it actually optimizes and gives you a lot more leeway into the 16 millisecond frame budget you have. So one last thing. So we've talked about layers a little slightly now. So you can actually under, the layers is also like, you need to be cognizant of how many layers you're actually having there. So as you have too many layers, each of these layers start occupying more memory. So especially in a small memory, devices with low memory, you kind of exhaust the memory that is available for the browser and probably it ends up crashing. So let's look at one of sites called Stripe. This page, I think when it loads, so let's start the video. So when it loads, it kind of has a bunch of animations when the page loads. So we can see and let me skip a little. Okay, so one of the things is, as you have like this site here, kind of pulls out elements that it's animating to different layers. So in DevTools, you have a nifty tab called layers, which I think in Chrome can really, I'm not sure if it's enabled by default now, but yeah, you can enable, go to Chrome flags, enable DevTools experiments. You actually get that layers tab available for you. So here, if you look at the top right, it kind of gives a diagram of how many layers are there in the application. So if you see, there are like bunch of layers in this page. So at the left, if you see, there's a tree view of how many layers are there and if there are layers inside layers, it kind of has a tree view and so on. And at the bottom, it also shows what is the memory estimate for that layer and so on. For example, here, the whole page, that layer kind of occupied 15.3 megabytes, which is, which may be huge in cases where it's actually a low-memory device. One of the cool things it also has is at the top, it has a rotate icon. So if you enable that, you can actually rotate this diagram view and see in 3D how many layers are actually present. So let me try to... So if you see, that's the depth of layers that are there. So if you see, this is a stack of layers that this page has, which are probably too many for this, unless those elements are getting animated layer later and so on. So if you've understood the layers, you can actually now debug at how many layers you're having in your application. And at each animation, you can see there'll be newer layers that can be added and then removed and so on. For, I mean, we talked about paint occupying a lot of time during your frame budget. So few of the brothers like Chrome, they enabled something called GPU rasterization. I think in Chrome, it's available from 37 version onwards. So you need to just enable this with a meta tag where you say, obviously, with device equal to with and then in one scale equal to one, it kind of activates the GPU rasterization. So when, so what is rasterization is essentially all these layers are then, I mean, how it kind of converts all these layers to pixels. And GPU rasterization actually gives, brings down the paint time from about 100 millisecond per frame to about just four to five milliseconds per frame. So this is something that you can definitely act in your web applications if it's really necessary. Yeah, because it can without any work that you're of yours can actually reduce the paint times by a lot. So just to summarize what we've kind of looked at is we kind of understood what happens during the rendering life cycle. So it's like JavaScript kicks in, it kind of triggers a bunch of style changes and newer HTML elements, which kind of result in a layout calculation. Then it needs to repaint once a fresh calculation is done, which is pushed to composite to the compositor to actually render, flush it to the GPU to render this. We also talked about how we can look at what are giants and how we can kind of debug and look into when long frame rates are occurring and so on. We kind of debug the few scenarios of each of these phases during the rendering life cycle, how you can optimize it. It's not in detail. You'll probably hear with a lot of case studies that are happening through this conference. We're also having a bunch of buff talk in the evening in the afternoon, so you can probably join and we can discuss in detail about this. The other thing also we saw was how to debug your layers and see how many layers you're having and how can you reduce the amount of layers that are not useful always and so on. And also, Nifty GPU fasterization, how you can just enable it to get a huge performance boost. So what next? A lot of techniques are happening to reduce the page load time is break down the page into pagelets. Some people have coined this term called pagelets where it's like part of a page which can be flushed and rendered upfront so that for the user, the perceived performance is actually a lot better. Okay, so this also means you kind of lazy load or stream in additional pieces of markup that you have and kind of keep adding it to the page so that for the user, they can start seeing something and when the layout and the paint render happens, they can start interacting with the application without waiting for the complete whole page to load. For example, if you see Facebook, which has a lot of functionality loaded on the homepage, it actually does this a lot so that the users can start interacting with pieces, whatever have been loaded already. The more we dive into JavaScript, the more we introduce JavaScript, the other part that also happens is you need to execute more code, the browser on the fly and which means a lot of JavaScript, JIT compilation happens and which means it can occupy more of your frame budget. So you need to be cognizant of that. So that's where kind of native apps hold the edge because everything is in binary and there's no real compilation or execution that is actually required. So there have been efforts that are going around where you want to package binary data for the website and so on. Yeah, but always remember that whenever you're facing some performance problem of your rendering, always measure first and then optimize later. So unless you measure, you just don't go by standard patterns, like prioritize what you want to do after measuring the data that you have. I think that's all I wanted to speak about. I can, one for QA. Yeah, one thing that you haven't mentioned is there is a UX part of performance, right? There are a lot of websites when they're loading some content comes up. The moment you go to click there, right? The page gets relayed, the layout changes and then you're clicking somewhere else. So what tricks can you use to make sure that your page layout and the sizes remain more or less constant while stuff comes in? So one of the things that you can definitely start measuring the data and see when the paints are happening, at what point, parts of the page, the layout is getting triggered. So if you're interacting on something and there's a layout that's getting triggered, which means before, I mean, the interaction JavaScript executes and starts another, maybe it can skip a frame and kind of, people call it something called screen tearing where half of one frame loads and another frame jumps in and a lot of, I mean, you don't see normal behavior there. So the best thing is to optimize and see what is happening and ensure you're not really reloading when something is happening. I think as a follow up to the previous, for the previous talk, you asked a question around if you're rendering react from the server, how do you ensure that there's no reload from the client side react? So when you use render to string using react server, it kind of inserts a react check, some attribute to the DOM that it renders. So using that, the client side react, uses that to see how much has already been computed and doesn't ensure it repaints those. That is something that you can look at, especially if you're using react and ensure that it's not always triggering layout fun necessarily. There's no more questions. There's no more questions. As Jay pointed out, we have lots of further sessions this afternoon at 2.50 p.m. when you measure performance. So the speakers from this morning and some of them who are speaking tomorrow will be there and we'll have a discussion over there on various aspects of performance. Thanks a lot for listening in. I'll not stop you from being more hungry.