Search code examples
lazy-loadingbabeljsfeature-detectionpolyfillscore-js

How to detect features and lazy-load only the needed polyfills with babel / core-js?


Polyfill services like polyfill.io seem to be delivering only small feature detects to the browser and then lazy-load only the polyfills that are actually needed.

As I understand the babel documentation on polyfilling, babel always include the full set of potentially needed polyfills: it will process a browserslist and then include those polyfills from core-js that the weakest browsers need. A bundler like webpack would then probably merge all these polyfills into the application, but without runtime feature detects.

My application uses modern ES language features but also targets a wide range of browsers, including IE10 and IE11. That requires a lot of polyfills and will probably bloat the bundle, especially for modern browsers that may not need the most of the polyfills.

So I was wondering: can I tell either babel and/or webpack to only include feature detects, split the polyfills off into separate chunks (individually or into small bundles), and then, at runtime, only "lazy"-load what is actually needed?


Solution

  • Services like polyfill.io investigate your User Agent against a predefined set and based on that provide you with different bundle of polyfills. What you're trying to do is actually way different.

    One solution I could thing of is to introduce code splitting into your build (it is on by default in Webpack 4 production build) and create several files in your project, where each would import a different set of polyfills. This will require you to import polyfills manually, but will allow you to have several polyfill chunks, each with a different subset of missing features. After you will have those chunks, you could use some feature detection (probably Modernizr) on the startup of your application and dynamically load only those chunks which are needed by the browser. Keep in mind that this process is rather cumbersome - you will need to take care of including each polyfill manually. Also another disadvantage of it, it will need to make several requests to the server, which will additionally slow down your app start time.

    As to other part of your question - webpack/babel will not do the automatic polyfill chunks splitting and runtime feature checking for you, those will need to be handled manually.