Announcing Microfill


Previous week I released Microfill, a tool that dynamically loads the polyfills that are needed. For example, a Promise polyfill will only be loaded if Promise isn't supported in the current browser.

How does that work?

Instead of loading the script file, a file generated by Microfill is loaded. That file will look like:

;(function(){
    var hex = 0;

    if (!window.Promise) hex += 1 << 0;
    if (!window.fetch) hex += 1 << 1;
    if (!window.setImmediate) hex += 1 << 2;

    var script = document.createElement("script");
    script.src = "file-" + hex.toString(16) + ".js";
    script.type = "text/javascript";
    document.head.appendChild(script);
})();

The code will check whether Promise and/or fetch are available. If a feature is missing, hex will be increased by a certain value. That value is given by 1 << i, which means "shift the bits from the number 1 i places to the right". The binary representation of 1 is 1b (the b means that it's a binary number, that's not JavaScript, just mathematical notation). Shifting 3 places would give 1b << 3 = 1000b = 8. You can also calculate 1b << n using 2n.

Given the value of hex, we know which polyfills should be loaded. For example, if hex = 110b, that would mean that hex = 1b << 2 + 1b << 1, thus we need to load the second and third polypill (fetch and setImmediate).

The value of hex is used to create the url to the script file that will be loaded. In our previous example we would load script-7.js.

During the build process all those files are generated. If you have N different polyfills, there will be generated 2N different packages. Every polyfill can be on (needed) or off (feature is already available in the browser), so we get 2 * 2 * 2 * ... * 2 which is equal to 2N.

For every number between 0 (inclusive) and 2N (exclusive) we look at which bits are on (and thus which polyfills need to be added). These files, including the script that will determine which polyfills need to be added (example above), are the output of Microfill.

Using gulp

The easiest way to use Microfill is to use gulp-microfill:

var gulp = require('gulp');  
var microfill = require('gulp-microfill');

gulp.task('default', function() {  
    return gulp.src('lib/**/*.js')
        .pipe(microfill(['set-immediate', 'promise', 'fetch', 'collection']))
        .pipe(gulp.dest('release'));
});

Try it out

You can install gulp-microfill and Microfill using npm, or take a look at their GitHub repositories: