In a previous article, I recommended Webpack as a reliable build system. It gives you lots of control over the initialization (download, parsing, processing) of resources used by your front end. Let’s use a traditional website index.html as an example to portray how to get started with Webpack and how to get it running with a basic setup.
How the code is delivered and utilized
<html lang="en">
<head>
<title>My Cool App</title>
<link href="//cool.site.com/styles.min.css" rel="stylesheet"></link>
<script src="//cdn/rendering-engine.min.js">
<script src='//cdn/dependency1.min.js'/>
<script src='//cdn/dependency2.min.js'/>
<script src='//your.site.com/index.js'/>
</head>
<body>
<div id="app"></div>
</body>
</html>
The above is the first entry point to your app that the browser will download and parse. Perhaps you’ve chosen to inline a lot more than what I show up above, but the inlining code has its pros and cons. (Inlining is when styling or code is included in the index.html.) The more there is, the more that needs to be parsed from the index.html before the render. This index.html above instructs the browser to fetch four more dependencies “bundles synchronously.” These are downloaded synchronously (HTTP 1.1) or asynchronously (HTTP 2). After, they are parsed and executed synchronously in sequence. If these bundles are significant in size, it will take some time for your site to become interactive.
Getting to the first paint
In modern web apps, we often use “rendering engines” to generate HTML at run time. This means we likely need to download a massive library to do that work and then wait on it to start rendering something for us to see it! This time is at the cost of the user’s attention and creates the perception that your entire app is slow.
To combat this, we need to deliver the first paint as fast as possible. (Under 1 second or even under 500 ms). We won’t depend on our rendering engine to deliver the first paint. Instead, we will “inline” our markup for the first paint with as little scripting and styling as possible. (Remember: the more we inline, the more we bulk up the index.html download and parse time.) We can automate this whole task with Webpack and generate our index.html by using server-side rendering work that most modern rendering engine support. However, that is a more advanced subject, and we will return to that in a future article. I’ll also dive deeper into pre-loading and prefetching resources to optimize loading scripts as well at a later time.
Getting Started With Webpack
First, Webpack must be installed as a dependency:
- npm install webpack –save-dev
- npm install webpack-cli –save-dev
Using a basic Webpack 4 config that looks something like below. (Note: most build systems, including Webpack, run on Node.js. This gives access to OS APIs such as local file I/O and on-demand JavaScript parsing such as require()).
const path = require('path');
module.exports = {
entry: {
main: './src/index.js'
},
output: {
filename: 'main-bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
This will use your index.js source entry point, walkthrough and build the dependency graph, and bundle everything together in a single webpack. Given what we discussed above, our index.html now looks like this:
<html lang="en">
<head>
<title>My Cool App</title>
<link href="//cool.site.com/styles.min.css" rel="stylesheet"></link>
<script src='//your.site.com/main-bundle.js'/>
</head>
<body>
<div id="app">
<p>This will render near immediately and make it seem like my site is faster!</p>
</div>
</body>
</html>
But wait! Our code is now inlined, which should be faster since it’s parsed and rendered immediately. In exchange, we jammed all of our code into one bigger file. Won’t this thing be slightly slower now that everything is one large bundle?
Correct, and arguably even slower as we now can’t take advantage of the benefits of HTTP 2.0. We are well underway with at least grokking the capabilities of a web pack! We will pick up how to make this faster in future articles by identifying the code needed for the first render’s continued user interactivity. It is essential to acknowledge that anything required for the first render is “critical.” Everything else should be downloaded later via lazy loading.
I only skimmed the surface for some basic Webpack tutorial (which is done much better here on the official documentation). Still, hopefully, this article starts helping connect the dots for the conceptual value of Webpack. Now that your getting started with Webpack, we’ll dig into code-splitting next!