Intro
Since internet speed varies for everybody and people don't have time to wait for your website to load, it makes the performance very important. All big and growing companies prioritize fast and seamless user experience because they know that people of today's age are not used to waiting around. Amazon calculated that if the page load slows down with 1 second, that could cause them to lose 1.6$ billion in sales each year. Google calculated that if their search results slow down 4/10 of a second they could lose up to 8 million searches a day, resulting in them losing profit on their ad revenue. Now there are a lot of ways to make your code more performant and your website faster, let's dabble into the different ways to do that.
QUICK OVERVIEW
Let's first review what happens when someone visits a website while browsing the web. There is a client/browser and a server, you make a get request to the server with the URL (www.)example_site.(com), then that server returns an HTML file, and after receiving an HTML file it parses through the different tags and maybe finds out a link tag containing CSS required for the styling.
After becoming aware of the CSS it requests the CSS file from the server and retrieves it. The browser does the same thing for image files and script files for javascript. This process involves the client, the server, and the network transfer.
THE CLIENT, THE SERVER, AND THE NETWORK TRANSFER
The client, the server, and the network transfer are where the work happens to display a website. This gives us 3 ways to optimize the speed of your website and application and thereby improving customer or user satisfaction, retention, and conversion.
So the first thing we can improve on is the front end and rendering of the client view, the next thing we can improve on is the network transfer of files and requests and reduce the network latency. And the third place we can improve on is the backend.
The Network transfer optimization
When it comes to network transfer optimization we can minimize the text files with build tools which will usually delete the white space in the code making it lighter, we can minimize the images and use lower size images on smaller screens, we can also pick the right file format for the images based on how they look and what you want to use them for. For example, if the picture is colorful then we should make the format jpg, if it's going to be transparent then SVG format works best, gif for animation and png for simple pictures with few colors, so maybe something like a logo.
Another thing that can help network optimization is delegating the number of files that can be delivered at a time. By limiting the files delegated in the request process the website won't be overloaded and speed down but rather be lighter on its loading, for this, we bundle the info into one file. And we can also use media queries to change the size based on viewport size and also delete metadata resulting in a faster website.
The Critical Render Path optimization
Let's talk about what happens after the files arrive in the browser and how we can optimize this step. After the HTML arrives, the browser commences building what we call the DOM(Document Object Model). And when the browser parses or reads the HTML, it incrementally generates a tree model of the HTML tags needed to build the website.
And this DOM describes the content of the webpage, but as its parsing, through the HTML it encounters a link tag that's asking for a CSS file. So it requests a CSS file from the server and fetches it for use and then continues generating the DOM and creating the structure of the website. After finishing with the DOM and fetching all the CSS files the browser starts creating the CSSOM.
The CSSOM has the styling information attached to the tree nodes, and this tree describes how the content is styled. After the DOM and CSSOM are generated then the JavaScript script tags will fetch the Javascript from the server and thereafter use the javascript to manipulate the DOM or the CSSOM.
After all those processes are finished, the browser then combines the DOM and the CSSOM into a render tree. This render tree has both the information from the HTML and the styling and layout information from the CSS. By combining the DOM and the CSSOM the browser constructs this render tree so that it knows what to exactly render on the page. The browser then forgets the server files and just uses the render tree to paint and display the website, and then at the end of all that we will finally have a website.
This is called the critical render path, which is one of the most important concepts for optimizing browser performance. This is the path the browser takes to display the website on the screen. Even though it may seem like a long process, in real life it happens extremely fast. And just like we can optimize the network performance, we can do the same thing with the critical render path.
The first step is optimizing the HTML file, how do we do that? The first thing we want to do is load files that are CSS files as soon as possible and the script files that are javascript files as late as possible, with a few exceptions here and there. This is because one of the main principles of CSS performance is getting the CSS to the browser as soon as possible and the JavaScript requires the HTML and CSS to be parsed before it can run and execute DOM/CSSOM manipulation. With this strategy, we give the CSS time to finish parsing and creating the CSSOM, we also get the added bonus of rendering the tree path faster because the script will be parsed after all the necessary resources are finished rendering.
The second step is optimizing the CSS, and one thing we can do is load what is necessary by not repeating the same code multiple places. Another thing we can do is code CSS that only renders the components that are needed, for example, if we refresh a page then the CSS will render the components that are in the view first on top of the page, this is called above the fold loading.
You can implement the above the fold loading by using JavaScript to load the stylesheet at the end of the body tag so that it fetches the stylesheet after all the other resources are loaded up with the help of createStylesheet() functionality and the onload() functionality. We can also optimize it with media attributes and media queries by displaying different CSS on different media sources.
Now, let's take a look at JavaScript and how to optimize the website speed by improving the way it gets parsed. One thing we can do here is load the script's asynchronously, this can be done with the async attribute inside the script tag so that the script gets loaded on another processing thread with the help of the browser. This is recommended to only be used on scripts that don't affect the DOM or the CSSOM, that way it won't affect the user experience in case the script loads faster than the DOM or the CSSOM. A good place to use this might be for analytics scripts or tracking scripts.
Another thing we can do is use the defer attribute which works like the async method but in this case, the JavaScript will only execute after everything has been fully parsed. The defer method is very good for loading scripts that will interact with the DOM or the CSSOM. The last thing We can do is minimize dom manipulations and avoid long-running JavaScript code.
Summary
We have taken a look at how to optimize HTML, CSS, and JavaScript loading so that the browser can render the web app/webpage as soon as possible for the user. We have gone through the sequence of the critical render path and how everything falls into place to create the render tree through combining the DOM, CSSOM, and JavaScript. Keep in mind that google chrome by default enables async functions. I hope this was helpful, and if you have any questions leave them below.