βœ‚οΈ Code Splitting

Load code as you need it (if you need it)

Parcel supports zero configuration code splitting out of the box. This allows you to split your application code into separate bundles which can be loaded on demand, which means smaller initial bundle sizes and faster load times. As the user navigates around in your application and modules are required, you can load child bundles on demand.

Code splitting is controlled by use of the dynamic import() syntax, which works like a hybrid of the normal import statement and the require function, but returns a Promise. This means that the module can be loaded asynchronously.

ΒΆ Using dynamic imports

The following example shows how you might use dynamic imports to load a sub-page of your application on demand.

 
import("./pages/about").then(function (page) {
// Render page
page.render();
});
pages/about.js:
export function render() {
// Render the page
}

Because import() returns a Promise, you can also use async/await syntax.

 
async function load() {
const page = await import("./pages/about");
// Render page
page.render();
}
load();
pages/about.js:
export function render() {
// Render the page
}

ΒΆ Unused exports

If you use one of the following patterns with dynamic imports, unused exports in b.js can be removed (similarly to how they are removed with import {x} from "./b.js";).

For the await cases, unused exports can unfortunately only be removed when await is not transpilied away by Babel (= with a modern browserslist config).

 
let { x: y } = await import("./b.js");
 
({ x } = await import("./b.js"));
 
let ns = await import("./b.js");
console.log(ns.x);
 
import("./b.js").then((ns) => console.log(ns.x));
 
import("./b.js").then(({ x: y }) => console.log(y));

ΒΆ "Internalized" Bundles

If a asset is imported both synchronously and asynchronously, it doesn't make sense to create an actual async bundle (because the module is already loaded anyways).

In this situation, Parcel instead turns import("foo") into Promise.resolve(require("foo")). So in a larger build, you should think of dynamic/async imports as "I don't need this import synchronously" rather than "This will become a new bundle".

ΒΆ Shared Bundles

In many situations (e.g. when two HTML entry with a JavaScript <script> use the asset(s) or when two dynamic imports have common assets), Parcel splits these into a separate sibling bundle ("shared" bundle) to minimize code duplication.

The parameters for when this happens can be configured in package.json:

package.json:
{
"name": "my-project",
"dependencies": {
...
},
"@parcel/bundler-default": {
"minBundles": 1,
"minBundleSize": 3000,
"maxParallelRequests": 20
}
}

Options:

HTTP version version minBundles minBundleSize maxParallelRequests
1 1 30000 6
2 (default) 1 20000 25

You can read more about this topic here on web.dev