We’ll talk about best practices to either reduce (or increase!) the JavaScript footprint on your web site to a sweet and very practical spot for best results. It’s far more common to have too much JavaScript on your web site, but can you go too far? Is zero JavaScript a worthwhile goal? Let’s talk about it!
The year is 1964. Only 5 years before the Apollo 11 moon landing and the midpoint between the very first release of Internet Explorer (1995) and the current year 2026. https://unsplash.com/photos/a-tv-sitting-on-the-ground-in-front-of-a-brick-building-SnewvLPyeAQThe location? Los Angeles, CA (USA).Local nightly news anchors for KHJ channel 9 decided to broadcast a PSA or Public Service Announcement (also known as a Public Information Film or PIF) warning to all parents in the area: It’s 10PM. Do you know where your children are?What kind of parents existed in 1964? What kind of kids? Why did they need this reminder? And today, I bring the developers creating the next generation of JavaScript heavy applications the same call to action: it’s 10PM — do you know where your JavaScript are?Today we’re starting a rumor that Americans say that “JavaScript” is plural, just like we do with Math, which JavaScript is also coincidentally kinda bad at.And to do that, we’ll take a trip to the local optometrist and create a little component that lets us compare two separate images, a before and an after image. https://optician-sans.com/Here’s what a component like this might look like. This one is a <wa-comparison> custom element from the Web Awesome component library. Today we’re going to walk through 14 different eras of web development as though they were DEFCON levels on a Cold War threat readiness system, and we’ll create 14 different image comparison components to show how far we’ve come and what might come next.Let’s hop into our mandalorian time machine and travel back to the year 1991.The year is 1991, a short 35 years backwards in time, but only 22 years after humanity bravely landed on the moon. One can only assume that dinosaurs had very recently gone extinct. We find a young, spry London-born 36 year old Tim Berners-Lee publishing the very first draft of…HTML. How might one create an image comparison component in HTML? Call it out if you know it:That’s right, ASCII art. Unfortunately <pre> was not available to preserve whitespace.Here are the originals. Which one could we use? Call it out if you know it https://www.w3.org/History/19921103-hypertext/hypertext/WWW/MarkUp/Tags.htmlIf you said plaintext, sure!but <plaintext> vacuums up the rest of the document (and doesn’t expect a closing tag), as stated to improve parsing performance. A thousand HTML sanitizer scripts just held this breath, because just like an unclosed <style> element, this behavior will still vacuum everythingLet’s swap to <listing>, which is a better fit. I think we’ve exhausted this one. Let’s move on.The year is 1992. Some dude (we needn’t immortalize who) introduced the`<img>` element, the very first mechanism for displaying images inline in HTML. First available in the Mosaic browser, this first offers us the barest bones featureless image comparison component was first possible. Leaving the viewer to crane their neck left and right to compare images, disgustingly manually.Trojan Room Coffee pot at the University of Cambridge by Quentin Stafford-Fraser and Paul Jardetzky Originally created in 1991, put on the web after <img> was introduced; XBM format https://en.wikipedia.org/wiki/X_BitMap though GIF was available at the time (maybe JPEG, though that timeline is much closer) This may not be the first image, a title likely given to a July 1992 image of a Cern-based musical group. https://www.cl.cam.ac.uk/coffee/coffee.htmlhttps://www.webdesignmuseum.org/web-design-historyCan anyone guess what happened in 1995?https://www.youtube.com/watch?v=5NShEY1ScSYFor this one, I think it’s prudent that we pay homage to the MM_swapImage script. If you aren’t familiar with this one, it was introduced in Macromedia Dreamweaver to swap image sources when a user interacts with them.Let’s start to document our dependencies.Cons: not seen by the HTML preload scanner but guess what: we didn’t have a preload scanner then The mm_ scripts did include JavaScript preloading. I know this is a trivial example but it’s important to internalize this concept and how it can represents layout shift.Anyway, let’s not spend too much time on this one it’s very outdated and not used any more.https://www.w3.org/TR/CSS1/ Håkon Wium Lie and Bert Bos who as far as I can tell is unrelated to Wes Bos CSS1 was in 96 but we’re going CSS2 in 98 so that we can use position and overflowIntroduced in a SXSW talk in 2003. Photo via https://www.linkedin.com/in/schampeo/ Slides: https://web.archive.org/web/20141108064903/http://hesketh.com/publications/inclusive_web_design_for_the_future/ Webmonkey article https://hesketh.com/publications/progressive_enhancement_and_the_future_of_web_design.htmlHow it loads is just as important as what is loading. This ties into (not just) Progressive Enhancement, but Browser Support, Performance, FOUC, Layout Shift, et alThe link element blocks rendering, waiting for the stylesheet. A script like this in 2003 was blocking, though now we can use modules or asynchronous/defer to better control that behavior. External requests creates a network dependency! In the wild wild west of the world wild web, no network request can be guaranteed to complete so we must think about what happens when resources don’t load or aren‘t supported by the viewer’s browserAnd even though progressive jpeg was available, I didn’t use it here for dramatic effect and the image content chunks in, line by line, reminiscent of my childhood.We should also think about what happens if the network requests complete but are delayed! Just off the cuff and absolutely in no way pun intended, maybe we could call it the extermporal dead zoneSUSPEND REALITY and time warp in a service workerHave you heard of 56k Fridays? I’m not saying you use this to add a simulated network delay to folks with more CPU cores, but here is a script to do thatMay 2008 https://web.archive.org/web/20081216035512/http://googleajaxsearchapi.blogspot.com/2008/05/speed-up-access-to-your-favorite.htmlGoogle Hosted Libraries popularized this in the jQuery community https://developers.google.com/speed/librariesThough instead of performance savings, there are now performance costs with this approach — though the biggest cost for me is relying on an external third party for your site’s runtimePRIVACY Separate cache for each origin https://andydavies.me/blog/2018/09/06/safari-caching-and-3rd-party-resources/https://addyosmani.com/blog/double-keyed-caching/https://developer.chrome.com/blog/http-cache-partitioninghttps://fossa.com/blog/polyfill-supply-chain-attack-details-fixes/https://developer.mozilla.org/en-US/docs/Web/Security/Defenses/Subresource_Integrity the failure mode here is pretty unfriendly.November 2008Cheap server rendering without an application server, popularized via the default option for GitHub PagesReal OG’s might recognizelol image mapThe PE profile here seems better but the user experience is definitely worse!though IE9 was first in 2011https://www.w3.org/TR/2001/WD-css3-mediaqueries-20010404/Overview.htmlimplemented using @media and css background-image https://alistapart.com/article/responsive-web-design/Islands architecture popularized by the Astro about ten years after RWD is also in this same league https://scottjehl.com/posts/responsive-video/ 2023!Were CRT televisions 16:9? I don’t remember.You might imagine doing the same with a navigation menu viewable at large viewport sizes but not at small ones.Not just on the client! Servers can make choices like this too: to conserve resources using static assets instead of dynamic pages, to use low-tech features like image dithering to reduce serving costs. https://solar.lowtechmagazine.com/This wasn’t a particularly good time for folks that cared how the web was delivered or rendered. But it was a very popular time for web development!Import your styles, and they get bundled up globally2 network resources on the critical rendering path, including a hefty library This is like strapping your baby into thehttps://www.reddit.com/r/mildlyinteresting/comments/133ze96/today_in_minnesota_an_empty_flatbed_with_a_single/Styled Components 2016–2026 Emotion 2017I get it—why not? the JS dependency is already there! It makes sense if you’re already bought in to CSR. 51kb to 61 kbTurns out JavaScript isn’t good at this, especially against CSS and especially when dealing with frequent rerenders.https://styled-components.com/https://speakerdeck.com/vjeux/react-css-in-js?slide=28https://unsplash.com/photos/brown-and-black-brick-wall-KREQ7J7nsNw A mea culpa moment for CSRNotably here when I’m talking about SSR, I’m using the component definition of SSR, not the application version (which means rendering dynamic HTML on-request). The reason it’s murky is because people are making money from the confusion 😘 https://www.zachleat.com/web/ssr-overloaded/https://github.com/vercel/next.js/tree/1.0.1 used Glamor for first-party CSSnext@1 (2016) 328 KB react@19 (2026) 191 KB next@16 (2026) hello world grown by 30% to 455.3 KBas we all know, systems typically get less complex over time so this is fine.almost 400 KB of JavaScript between your finger and your eye split across 6 external requests (EACH is required for interactivity), remember the goal is to poke the eye as fast as you canTailwind 1.0 was released in 2019I could probably write a whole talk about the introduction of this compared with zero runtime CSS in JS tools. Linaria 1.0 was available in 2019 too. I do have opinions, primarily that CSS seems to be shipping wildly fast in a way that abstractions are having trouble keeping up. But the biggest takeaway here is that all of these tools helped move CSS out of the client JS bundle.Even React pivoted away from this in 2021. https://github.com/reactwg/react-18/discussions/110January 2020, Custom Elements v1 cross-browser available when Edge swapped to Chromiumhttps://webawesome.com/docs/components/comparison/Smaller JavaScript cost than a jQuery (87 KB)Flash of Unstyled ContentVite released April 2020You don’t have to gamble with these slotsThe first party, accessible JavaScript-enhanced experience is the ideal case. But here we provide an interactive middle ground when something in your environment has gone wrong.This one is using a range input. You could use the :target pseudo selector here as well to make the dead zone interactive again. You could also imagine how this same logic could be applied to a tabs component, notable for making sacrifices in unstyled render or missing interactivity. Web components offer this unique styling and markup enhancement out of the box, and I think that’s great.