Code splitting involves splitting code into various bundles or components. These files can then be loaded in parallel which can help with performance preventing needing to load huge files such as with your Javascript code. Instead of a single ‘frontend.js’ file, we get multiple small ‘chunks’ of smaller files, which can then be lazy loaded to only load the functionality that is needed on a page. This is a feature that bundlers like Webpack and Browserify include by default.
An interesting side effect of code splitting is the method for loading the bundle files is usually separate than the rest of the logic for versioning your assets, which can be problematic if you are expecting your asset version to be automatically bumped on deployment.
CDN Asset Caching Strategies
CDNs such as Cloudflare and Akamai are great, as it takes the burden of hosting files off of your server and puts them on a network of content delivery which can greatly improve site speeds. These files are cached on the CDN, which means they don’t automatically get new changes and are on a long TTL (time to live) interval. Versioning your assets in your source code provides assets a unique URL, generally through querystring parameters, that will allow CDNs to load the latest version of your asset files. For example, say you have a strategy to load your assets with a version appended as the querystring with the last modification Unix timestamp as the version. Your filename would be loaded as frontend.js?ver=<last modified date/time
>. When your file is modified, the CDN will grab the newest version of the file from your server.
Bundle Filename Issue
This versioning strategy can work great in most situations. An issue arises when using code splitting. If using code splitting, frontend.js is broken up into multiple files such as 1.bundle.js, 2.bundle.js, 3.bundle.js
, etc. which are referenced from frontend.js.
By default the filename for those files are referenced directly, so even though you may be loading frontend.js?ver=<last modified date/time>
, the references to 1.bundle.js
never have that version appended. This can be problematic, as the CDN will keep serving the old version of the bundle files, which likely don’t correspond to the updated frontend.js
file, which will cause JS errors until the cache is either flushed or TTL is reached.
Implementation
The solution for this issue is to modify the config file and ensure that a hash is added to the output filename. In the example of a Webpack config, webpack.config.js, your chunkFilename may be set to [name].bundle.js
by default.
By utilizing the [contenthash]
string in the chunkFilename
it will create a dynamic hash each time your files are built which will bypass the cached version of a CDN asset and load the newest version (which will be subsequently cached). Example:
output: { path: path.resolve(process.cwd(), settings.paths.dist.base), chunkFilename: '[name].[contenthash].bundle.js', publicPath: '/assets/dist/', filename: settings.filename.js, }
This will then change 1.bundle.js
to be 1.7e2c49a622975ebd9b7e.bundle.js
which will be unique on every deployment.
More information about caching using Webpack can be viewed on their caching guide.