I recently read an article on SmashingMagazine on managing bundles for modern and legacy browsers, in which the author had discovered that bundles built for legacy browsers are, on average, 25% larger than those created for modern browsers.
This is mainly due to the fact that native support for ES6 has resulted in the possibility to achieve the same results with less code. Unfortunately, legacy browsers such as Internet Explorer lack support for most, if not all, of ES6, forcing developers to include workarounds and polyfills just to get things working, resulting in larger bundle files.
In the article, the author suggested creating separate bundles for each platform, and employing server-side browser sniffing to serve the appropriate bundle to users.
While this method works, there are numerous reasons why browser sniffing is bad.
<script type="module" src="bundle.modern.js"></script>
<script nomodule src="bundle.legacy.js"></script>
The main advantage of this strategy is that you don’t need to do anything other than include one script tag for modern browsers, and another one for legacy, and let the browser handle the rest.
These browsers will simply fall back to using legacy code that, if built correctly, should have no negative impact other than having to load additional bloat that resulted from the polyfills that these browsers don’t actually need.
Regardless, I think this is still the way to go, as we currently have no idea when Microsoft will drop support for Internet Explorer, and we still have to support our corporate visitors, many of whom are stuck on this archaic monstrosity due to silly corporate policies.
Apparently, as it turns out, IE still downloads both files, but it would only parse the legacy code, as demonstrated in the screenshot below.
So JS modules will not help you reduce the overall download size, at least not on IE. In which case, the original suggestion to use browser sniffing to serve the correct bundle makes more sense.