Serve modern code to modern browsers for faster page loads
Babel is the most widely used tool to compile code that contains newer syntax into code that different browsers and environments (such as Node) can understand. This guide assumes you are using Babel, so you need to follow the setup instructions to include it into your application if you haven't already. Select
Build Systems if you are using webpack as the module bundler in your app.
To use Babel to only transpile what is needed for your users, you need to:
- Identify which browsers you want to target.
@babel/preset-envwith appropriate browser targets.
<script type="module">to stop sending transpiled code to browsers that don't need it.
Identify which browsers you want to target #
Before you begin to modify how the code in your application is transpiled, you need to identify which browsers access your application. Analyze which browsers your users are currently using as well as those that you plan to target to make an informed decision.
Use @babel/preset-env #
Transpiling code usually results in a file that is larger in file size than their original forms. By minimizing the amount of compilation that you do you can reduce the size of your bundles to improve the performance of a web page.
Instead of including specific plugins to selectively compile certain language features you are using, Babel provides a number of presets that bundles plugins together. Use @babel/preset-env to only include the transforms and polyfills needed for the browsers you plan on targeting.
@babel/preset-env within the
presets array in your Babel configurations file,
targets field to specify which browser versions you want to include by adding an appropriate query to the
@babel/preset-env integrates with browserslist, an open-source configuration shared between different tools for targeting browsers. A full list of compatible queries is in the browserslist documentation. Another option is to use a
.browserslistrc file to list the environments you wish to target.
">0.25%" value tells Babel to only include the transforms needed to support browsers that make up more than 0.25% of global usage. This ensures your bundle does not contain unnecessary transpiled code for browsers that are used by a very small percentage of users.
In most cases, this is a better approach than using the following configuration:
"targets": "last 2 versions"
"last 2 versions" value transpiles your code for the last two versions of every browser, which means support is provided for discontinued browsers such as Internet Explorer. This can unnecessarily increase the size of your bundle if you do not expect these browsers to be used to access your application.
Ultimately, you should select the appropriate combination of queries to only target browsers that fit your needs.
Enable modern bugfixes #
Originally developed as a separate preset, the bugfixes option in
@babel/preset-env solves this problem by converting modern syntax that is broken in some browsers to the closest equivalent syntax that is not broken in those browsers. The result is nearly identical modern code with a few small syntax tweaks that guarantee compatibility in all target browsers. To use this optimization, make sure you have
@babel/preset-env 7.10 or later installed, then set the
bugfixes property to
In Babel 8, the
bugfixes option will be enabled by default.
<script type="module"> #
@babel/preset-env to only target browsers that support them.
Instead of querying for specific browser versions or market share, consider specifying
"esmodules" : true inside your
Browsers that support modules ignore scripts with a
nomodule attribute. Conversely, browsers that do not support modules ignore script elements with
type="module". This means you can include a module as well as a compiled fallback.
Ideally, the two version scripts of an application are included like this:
<script type="module" src="main.mjs"></script>
<script nomodule src="compiled.js" defer></script>
Browsers that support modules fetch and execute
main.mjs and ignore
compiled.js. The browsers that do not support modules do the opposite.
If you use webpack, you can set different targets in your configurations for two separate versions of your application:
- A version only for browsers that support modules.
- A version that includes a compiled script which works in any legacy browser. This has a larger file size, since transpilation needs to support a wider range of browsers.
With thanks to Connor Clark and Jason Miller for their reviews.