Hi there, This post will give you a glimpse of what happens during build time of an application and how the performance of a web application can be optimized.
Let's dive deep into it!
Have you noticed what happens when you the run the command npm run build
in your create-react-app
?
Well, we can see that our big application that comprised of different folders and files is bundled together to a single build folder like below
Wait what? Who did that? Who transformed my big application to a single build folder?
The answer is Webpack
What is Webpack?
Let's assume we are developing a large application. It is not advisable to have all our JavaScript in a single .js
file. So we will modularize the code and have different files for each functionalities and import the functionalities when required. Without webpack, the html
document looks like this
<body>
<div id="root"></div>
<script src="header.js"></script>
<script src="footer.js"></script>
<script src="main.js"></script>
</body>
Here there are just three javascript files, what if there are more? Is it advisable to have the script
tag for all of the javascript files?
The answer is a big no!
Another potential problem with this is that the order should be maintained manually. Also everything exists in the global scope which will lead to the global pollution eventually.
Here comes webpack to the rescue!
Webpack is a bundler which bundles multiple folders and files in an application and generates one or more bundles. When webpack processes the application, it forms the dependency graph based on the import/export statements in a depth first search manner and generates a bundle which is the build
folder in our CRA (create-react-app)
Babel
Webpack just understands import/export statements, then builds and traverses the dependency graph. Modern browsers can understand the new JavaScript syntax. But some older browsers do not support it. So what can be done if we want our application to support the older browsers as well ?
We have Babel which is a JavaScript compiler which converts ECMAScript 2015+ code into a backwards compatible version of JavaScript in current and older browsers or environments.
Say we have an arrow function which is a ES6 syntax as below
const addTwoNumbers = (num1, num2) => {
return num1 + num2
}
Babel transpiles the above code as
"use strict";
var addTwoNumbers = function addTwoNumbers(num1, num2) {
return num1 + num2;
};
We know that let and const are ES6 keywords, so const is transpiled to var
and the arrow function is transpiled to ES5 function declaration syntax
You can check this out using Babel repl
Performance Optimization
Now we know what is webpack and babel, let's see how we can optimize the performance of an application,
Code Splitting
We have seen that webpack transforms multiple files to a single file. From this, we can infer that every time we request a page in an application, the entire file is being loaded which hits the performance. Why do we need to load the entire application when the user just wants to see the landing page.
To avoid this, we can do code splitting. Code Splitting is an optimization technique where we can split the code into various bundles instead of having all the code in a single bundle. This way, only the bundle that is required is loaded and other bundles are loaded on demand which minimizes the wait time of the user.
The above technique of deferring the loading of resources on the initial load and loading the resources only on demand is called lazy loading
Minification
Webpack processes the application in two modes: development and production
When we build in production mode, webpack does Minification.
Minification is the process of stripping out the unnecessary and redundant code in the application. This process removes whitespace, unused variables and comments and shortens the variable and function names. This eventually leads to a significant reduction in the size of the file that needs to be loaded in production which in turn increases the performance of the application.
Versioning
Versioning is the creation and management of multiple releases of a product, all of which have the same general function but are improved, upgraded or customized.
How can versioning be done?
In the above image, have you noticed the filenames such as ` main.f49b4b98.chunk.css
. Did u wonder what this random value f49b4b98
is. No matter how many times I build the application without changing the code , this value f49b4b98
is going to be the same. As soon as I change something in the code and build the application, a different version is generated. This is how webpack does versioning.
This value is generated by taking the hash for that particular file and appending it to the filename. As said earlier, every time there is a change in the file, the file name will differ as it will have a different hash
Caching
Versioning and caching goes hand in hand
Say we are making a change that affects just one bundle, all the other bundles remain same.
Do you think it's good for the browser to download the entire application on every request of the user.
Definitely not, because what is the point of the browser downloading the same file that has no changes again and again. That's where caching comes into picture.
The browser is smart enough to selectively download the resources, i.e., If the browser finds that the file name has not changed, it will not download the file again. It just displays the file in the browser's cache. Caching improves the performance of the application on a larger extent.
Image Optimization
Let's assume that our web application has large number of images. Images are resources that have their own size, they need to be loaded to be rendered on the page. How can we optimize it?
One way could be lazy loading - When we have hundreds of images, it is not advisable to load all the images at once, instead we can dynamically load them on demand or on a certain user action such as on scrolling or after reaching a certain height in the web page
It is always preferred to use .svg
images. Why ?
- Because svg files are resolution independent, i.e., the quality of the image is maintained across different screen sizes. Whereas jpg or png files might get blurry on a smaller or bigger screen.
- SVG files are smaller in size. Smaller the size of the file, faster the loading of the application which again increases the performance of the application.
We have come to the end of the blog, we have seen a lot of optimization techniques. Though webpack abstracts a lot of things and we often don't need to do all of the discussed things manually, I believe, as developers, it's extremely important to understand all of the things mentioned above.
Hope you find it insightful. I would suggest you to play around with web tooling to have a better understanding of what's happening under the hood in a toolkit such as create-react-app
Connect with me on Instagram, Twitter and Linkedin
Happy Coding!!