
Modern Script Loading - fagnerbrack
https://jasonformat.com/modern-script-loading/
======
ratww
Another possibility, albeit much more dramatic, is only using modules, if your
audience is 100% modern browsers.

At my previous job we imported our Google Analytics data into caniuse.com [1]
and noticed that >99.9% of our app users were in modern browsers. Same for the
public facing website. There was one single visit from someone using IE, but
the application wouldn't load for him anyway.

Using those stats we were able to also remove a bunch of polyfills. The next
step we were planning was either using a CDN for dependencies or something
like Pika [2].

Unfortunately both Vue.js and React/Preact [3] require a compilation step for
a good experience IMO. Otherwise I'd just skip the compilation step altogether
and write JS like in the old times.

[1] [https://caniuse.com/feed/116](https://caniuse.com/feed/116)

[2] [https://www.pika.dev/about/](https://www.pika.dev/about/)

[3] [https://preactjs.com](https://preactjs.com) \- a library made by the TFA
author :)

~~~
wildpeaks
Another reason for keeping a compilation step is it's not just about scripts,
it also generates the assets (stylesheets, images, 3d models, etc) and does
postprocessing like calculating SRI hashes.

~~~
ratww
Yep. Also hot-reload during development.

------
larzang
The best solution remains in my opinion browserslist-targeted compiling. I
don't think it makes sense to pretend you can/should write non-trivial JS
today without a build step, especially if you're worried optimizing delivery.
Are you seriously going to fret about delivering unnecessary polyfills to
modern browsers while simultaneously delivering unoptimized code and styles
because you felt like going old school?

You can write tomorrow's JS and CSS today while explicitly supporting
whichever of yesterday's browsers you know you need to, and have the delivered
code improve over time as older browsers are phased out without you having to
rewrite it.

------
chrisweekly
Excellent writeup! It's a tricky thing to get right, in part bc it keeps
changing. Good job reinforcing the need for devs reading this to understand
that and to err on the side of making deliberate, rational choices for their
circumstances, vs "here's the best way to do it" leading to ignorant cargo-
cult / copy-paste nonsense.

------
11235813213455
I usually do

    
    
      <script nomodule src="https://polyfill.io/v3/polyfill.js?flags=always&features=default,fetch"></script>
    

to load polyfills only for browsers that need it

------
kn8
The two drawbacks of module/nomodule that I don’t see being discussed often:

\- babel compiles async/await down to regenerator when using modules: true (at
least for now) \- the definition of “modern” browsers will change eventually
and module/nomodule detection will not be relevant

Which is why I’d use ua sniffing:
[https://github.com/KidkArolis/jetpack/blob/master/docs/07-di...](https://github.com/KidkArolis/jetpack/blob/master/docs/07-differential-
serving.md)

~~~
acemarke
Babel compiles whatever you tell it to, and each piece of syntax is a separate
plugin.

For `babel-preset-env` specifically, it compiles whatever syntax is not
natively supported by the browser versions you told it to target.

So, compiling `async/await` and compiling ES module syntax are separate
things.

~~~
developit
There are a few cases where syntax compilation is split up cleanly, but when
you dig into the internals of preset-env, transforms are rarely that isolated.
That being said, "watch this space"...

