4 ms·
Modern Script Loading
- chrisweekly 7y agoExcellent 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.
- ratww 7y agoAnother 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 :)
- uhryks 7y agoIf you really want to remove the compilation step you can use htm (also originally by the same author of the blog and Preact): https://github.com/developit/htm https://github.com/developit/htm
- ratww 7y agoI've used it in the past but haven't really adjusted to the syntax :( Maybe I should try again, I'd love not having to use a bundler. I also tried DomZ, which is neat too [1] [1] https://www.npmjs.com/package/domz https://www.npmjs.com/package/domz
- stevenwliao 7y agoIt's also possible that all of your potential users who were using outdated browsers left...
- ratww 7y agoNope. We actually had full support for older browsers and even tested for them before that. This was our SaaS-like application, btw, which was closed to the public. Btw, the public website also had a number of modern browsers close to 99%. Trust me, if we actually needed extra support our sales team would have made us well aware ;) EDIT: Also, this is sort of a statement. I'd rather let old browsers die. I think it's ok to say "no" to customers sometime. I want the web to evolve, might as well play a part on it, forcing people to upload their browsers, or letting their IT department know their outdated browsers are getting in the way of their productivity.
- magape 7y agoIt's hard for me to see how you can have "full support for older browsers" given that, as per the comment I've linked below, your application wouldn't load for an IE user. > There was one single visit from someone using IE, but the application wouldn't load for him anyway. (source https://news.ycombinator.com/item?id=21097946 https://news.ycombinator.com/item?id=21097946)
- stevenwliao 7y agoIt's great to take an idealistic stance here. I just wanted to point out a potential cost to this approach.
- wildpeaks 7y agoAnother 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 7y agoYep. Also hot-reload during development.
- gbuk2013 7y agoI use Vue.js old style without any compilation for a reasonably complex app and it’s pleasant enough. Node.js backend uses Pug for templating, each template includes a script template file. These template files are built with Make and load either a minified bundle (made with terser) or just a bunch of plain JS depending on the value of NODE_ENV. Works great :)
- ratww 7y agoYeah, Vue.js old style is quite nice to work when using ES6 modules! I think the only thing I'd miss is the scoped styles.
- larzang 7y agoThe 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.
- 11235813213455 7y agoI 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 7y agoThe 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-differential-serving.md https://github.com/KidkArolis/jetpack/blob/master/docs/07-di...
- acemarke 7y agoBabel 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 7y agoThere 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"...