Photo by Lautaro Andreani on Unsplash
React's Hidden Weapon : How Bundlers Slash HTTP Requests
Let's unbundle how bundlers reduce HTTP requests !!
Well do you know how exactly they reduce HTTP requests ? Below are a few questions that arise when someone is building their React concepts from scratch.
Is there a HTTP request everytime browser needs to access JavaScript/CSS file ?
Let’s say browser needs to access a JavaScript function funx() and
image.png which is inlined.
Are there going to be 2 HTTP requests ?Or HTTP requests are only made to load files in the browser’s memory ?
Do we even need any HTTP request to access a function that is present in our JavaScript file once JS is already loaded to browser’s memory ?
Let’s find that out !! But before that try to answer these questions on your own.
1. Why Bundling Reduces HTTP Requests
To start, let's recap a fundamental concept:
When building a web application, the browser needs to download resources such as:
JavaScript files
CSS files
Images, fonts, etc.
Each of these resources typically requires a separate HTTP request (even if they are all related to your website), and each request comes with overhead, like DNS lookup, TCP handshake, and establishing secure connections (TLS/SSL), which can slow down page load times.
The Overhead of Multiple HTTP Requests:
Let's say you have a webpage with the following files:
app.js
utils.js
styles.css
logo.png
For the browser to load your page, it needs to:
Request
app.js
from the server.Request
utils.js
from the server.Request
styles.css
from the server.Request
logo.png
from the server.
This means 4 separate HTTP requests for these resources. Even though these resources are related, each request involves a round-trip to the server, establishing connections, etc.
2. Bundling Reduces the Number of Requests:
Bundling works by combining multiple JavaScript and CSS files into one or a few larger files (known as a bundle), which dramatically reduces the number of HTTP requests.
Example:
Let’s assume you use a bundler like Webpack or Rollup. It can take:
app.js
+utils.js
→ Bundle intobundle.js
styles.css
→ Bundle intobundle.css
After bundling:
The browser would only need to make 2 requests instead of 4:
Request 1 for
bundle.js
(which now contains bothapp.js
andutils.js
).Request 2 for
bundle.css
(which contains thestyles.css
).
If the browser already has these files cached, then future page loads could require zero requests for these files, improving performance.
3. What Happens in Memory After Bundling?
When the browser loads the bundle.js
and bundle.css
, it loads them into memory (the browser's memory, specifically the JavaScript heap and CSSOM, respectively). Any function, variable, or image that's embedded (e.g., in a data URL) within these bundles can be accessed directly from memory without the need to make additional HTTP requests.
Let’s say I want to access 2 resources, funx() & and image.png :
If the JavaScript function
funx()
is inbundle.js
, the browser can execute it directly from memory after it loadsbundle.js
.If the image is base64-encoded and included in
bundle.js
orbundle.css
, the browser can display it immediately by decoding the base64 string (without any additional HTTP requests).
Thus, after the first load, everything (JavaScript, CSS, and images) is available directly from the browser’s memory, which eliminates the need for additional HTTP requests.
images/
directory and referenced it in bundle.js
), the browser will make a separate HTTP request for the image, even though it's referenced inside the bundle.js
.For example, if the bundle.js
contains code that references the image, the image might be located at /images/image1.png
. The browser would then make a separate request to load the image:
Request 3: The browser sends an HTTP request to fetch /images/image1.png.
4. Exact HTTP Requests Made by the Browser (Without Bundling)
Let’s see exactly what happens without bundling. Suppose you have these separate files:
app.js
utils.js
styles.css
logo.png
Without Bundling:
The browser sends multiple HTTP requests to the server:
Request #1: GET
/app.js
- The browser asks the server for the
app.js
file.
- The browser asks the server for the
Request #2: GET
/utils.js
- The browser then asks for
utils.js
.
- The browser then asks for
Request #3: GET
/styles.css
- The browser asks for the CSS styles.
Request #4: GET
/logo.png
- The browser asks for the image
logo.png
.
- The browser asks for the image
5. Exact HTTP Requests Made by the Browser (With Bundling)
Now, let’s see what happens after bundling the resources into a single JavaScript bundle (bundle.js
) and CSS bundle (bundle.css
).
With Bundling:
Instead of making 4 separate requests, the browser now makes only 2 requests:
Request #1: GET
/bundle.js
- The browser asks for the single
bundle.js
file, which contains both JavaScript files (app.js
andutils.js
), and possibly inline images or other resources.
- The browser asks for the single
Request #2: GET
/bundle.css
- The browser asks for the
bundle.css
file, which contains all the CSS.
- The browser asks for the
If the image is base64-encoded within the JavaScript or CSS file, no additional request is made for the image.
Congrats, you've just spared your website from the traffic jam!
6. Additional Benefits of Bundling:
Reduced Round-Trip Time (RTT): Every separate HTTP request involves its own round-trip time (RTT). This is the time it takes for a request to travel from the browser to the server and back. If you make several requests, this time adds up. By bundling files into fewer requests, you minimize the number of round trips.
Caching Efficiency:
- When you bundle your files, you can take advantage of cache control headers. If you version your
bundle.js
file (e.g.,bundle.[hash].js
), the browser can cache that file, and only re-fetch it when it changes. This is more efficient than caching individual files because it reduces the number of cache invalidations.
- When you bundle your files, you can take advantage of cache control headers. If you version your
Compression: Bundled files (especially when minified and compressed) are typically smaller than the sum of individual files, which means less data is transferred, leading to faster load times.
Tree Shaking: Modern bundlers like Webpack can also remove unused code through a process called tree shaking. This can reduce the size of the bundle even further, improving performance.
Example:
Without Bundling:
You have these 4 files:
app.js
→ 50 KButils.js
→ 30 KBstyles.css
→ 40 KBlogo.png
→ 20 KB
Total Data Transferred:
- 4 HTTP requests with a total size of 140 KB.
Each HTTP request has its own overhead.
With Bundling:
You bundle all JS files (
app.js
+utils.js
) intobundle.js
→ 80 KBYou bundle the CSS (
styles.css
) intobundle.css
→ 40 KBThe image (
logo.png
) is base64-encoded and included in thebundle.js
→ 20 KBTotal Data Transferred:
2 HTTP requests with a total size of 140 KB (the same total size, but fewer requests).
Additionally, once
bundle.js
andbundle.css
are cached, no more requests are needed.
Conclusion:
Without bundling, the browser would send multiple HTTP requests for each individual file (JavaScript, CSS, images, etc.), leading to higher overhead due to more connections, DNS lookups, etc.
With bundling, the browser only sends a few requests (usually just 2 for JS and CSS) and loads everything it needs from those bundled files, reducing the overhead and improving the load speed of your website.
By combining multiple resources into fewer files (bundling), you reduce the number of HTTP requests, optimize the load time, and take better advantage of caching and compression.
I hope this clarifies the exact mechanism of bundling and how it reduces HTTP requests. Feel free to comment if you have any more questions or need further clarification !