51 votes

JavaScript bloat in 2024

25 comments

  1. [2]
    PetitPrince
    Link
    This compares how much Javascript is loaded from popular sites (cold loaded). Some highlights: PornHub loads ~10x less JS than YouTube (1.4MB vs 12MB) Gmail have an incomprehensible large...

    This compares how much Javascript is loaded from popular sites (cold loaded). Some highlights:

    • PornHub loads ~10x less JS than YouTube (1.4MB vs 12MB)
    • Gmail have an incomprehensible large footprint (20MB). Fastmail is 10x ligthter (2MB). Figma is equivalent (20MB) while being a more complex app.
    • Jira has 58MB of JS loaded (wtf)

    (there's an average of 175 KB of Javascript in a random Tildes page :') )

    33 votes
    1. teaearlgraycold
      Link Parent
      Figma feels like one of the only ones that can get a pass. I'm actually impressed with their code size. It's a testament to how much the browser can do for you. As a standalone app Adobe would be...

      Figma feels like one of the only ones that can get a pass. I'm actually impressed with their code size. It's a testament to how much the browser can do for you. As a standalone app Adobe would be shipping you 10GB to install.

      25 votes
  2. [20]
    Rocket_Man
    Link
    Theres not a perfect solution to this but if Javascript could get a big comprehensive standard library we might get some real code reuse on the web. Currently Id guess most of this size is having...

    Theres not a perfect solution to this but if Javascript could get a big comprehensive standard library we might get some real code reuse on the web. Currently Id guess most of this size is having to download web frameworks over and over again. Which sucks because it's slow and wasteful. But in most circumstances I'd imaging there will be significant caching.

    23 votes
    1. [8]
      Wes
      Link Parent
      I agree with you, and I've long felt that browsers should maintain a local cache of the most common libraries specifically for that purpose. The list would evolve over time, but imagine how many...

      I agree with you, and I've long felt that browsers should maintain a local cache of the most common libraries specifically for that purpose. The list would evolve over time, but imagine how many times jQuery v2.2.4 has been downloaded, or the specific version that's packaged with WordPress sites. Nowadays we'd likely see many copies of React or Vue included as well.

      Popular web fonts are also good candidates. Raleway is used on plenty of marketing pages. And Font Awesome? Used on virtually every eCommerce site. What a waste of bits downloading the same glyphs every time just to show a shopping cart symbol, or a couple social media buttons in the footer.

      I think it's really unfortunate that browsers have (maybe had to) become fearful of using caches because they leak a small amount of information based on previous history. Shared site caches are now dead, so even using the same CDN doesn't prevent redownloads of assets.

      A local cache of common libraries somewhat sidesteps this problem, but still lets you query the list to identify the specific browser version being used. A dynamic list that is per-profile solves that, but then creates a worse problem by introducing a new fingerprinting method instead.

      I wish we could actually take advantage of all these optimizations without worrying about bad actors so much. Especially now that including the hash in the resource request is becoming a common practice. It seems like we could really optimize things for users on poor internet. Disk space is rarely the limiting factors anymore, with the possible exception of mobile phones.

      It's reminds me of the Spectre/Meltdown mitigations that killed performance on many CPUs. It's good that patches were made available, but a toggle to enable "risky execution" could be very helpful for tasks that are running trusted code in a secure environment. There's a number of situations where execution speed would be prioritized over the threat of bad code path optimization.

      Some platforms already allow a high security setting like Apple's lockdown mode for high-risk targets (journalists, et al). Similarly, Firefox has a setting to discourage fingerprinting by turning off a number of browser features (like dark mode support). So a slider that lets you choose between browser features + speed (JITs, shared caches, page prefetching), and absolute security (disabled fingerprinting, imprecise timers, or disabled JS) isn't too different than what we have now.

      But realistically I don't expect browsers to ever expose something like this. Most users wouldn't be able to make a threat assessment for themselves, and no browser wants to be known as less secure than their competitors, regardless of how theoretical these risks may be.

      19 votes
      1. [5]
        PetitPrince
        Link Parent
        It's presented with a privacy focus, but that's what Decentraleyes does.

        browsers should maintain a local cache of the most common libraries

        It's presented with a privacy focus, but that's what Decentraleyes does.

        11 votes
        1. [4]
          riQQ
          Link Parent
          There's also LocalCDN, a fork of Decentral Eyes: https://www.localcdn.org/

          There's also LocalCDN, a fork of Decentral Eyes:

          https://www.localcdn.org/

          10 votes
          1. zonk
            Link Parent
            I'm using that and so far I didn't (consciously) run into any issues. Nearing 30,000 injections since I've installed it :) And I'm also running NoScript and if I just briefly visit a website, I'm...

            I'm using that and so far I didn't (consciously) run into any issues. Nearing 30,000 injections since I've installed it :) And I'm also running NoScript and if I just briefly visit a website, I'm not even fetching all the JS, otherwise that number would be even higher. I wish the addon would show the saved traffic from this :)

            5 votes
          2. [2]
            adutchman
            Link Parent
            Makes me wonder if we just couldn't implement a method like that in the standard library: you make a call to the standard library that specifies the package, the hash and a url. If the browser has...

            Makes me wonder if we just couldn't implement a method like that in the standard library: you make a call to the standard library that specifies the package, the hash and a url. If the browser has it, it grabs it from there, if not the url is used. In the end the only difference is how fast you recieve a package and the code doesn't need to query a list because the browser will just use the url if it doesn't have the package

            2 votes
            1. Moonchild
              Link Parent
              Allowing this for arbitrary resources is problematic security-wise—browsers used to allow all cached resources to be shared between websites, and stopped for this reason. Suppose resource X is...

              Allowing this for arbitrary resources is problematic security-wise—browsers used to allow all cached resources to be shared between websites, and stopped for this reason. Suppose resource X is currently used exclusively by benign website A, which you frequent (and hence X is in your cache). Then, when you visit malicious website B, it can request X, and time how long the request takes. If it completes instantly, then it must have been in your cache, so B is able to learn that you visit A.

              10 votes
      2. teaearlgraycold
        Link Parent
        Yes but we could have a curated list of globally cacheable URLs (or ETags). If that sounds weird, consider that cookie behavior is guided by a magic list of domain names that host 3rd party sites...

        Yes but we could have a curated list of globally cacheable URLs (or ETags). If that sounds weird, consider that cookie behavior is guided by a magic list of domain names that host 3rd party sites - stuff like herokuapp.com. So if you have my-site.herokuapp.com you can’t read or write cookies to the root domain.

        Because what’s the problem with knowing that a browser has jQuery cached? That’s not a strong signal anyway.

        4 votes
      3. Moogles
        Link Parent
        I’m surprised Chrome doesn’t ship with the google font library bundled in.

        I’m surprised Chrome doesn’t ship with the google font library bundled in.

        3 votes
    2. [11]
      ButteredToast
      Link Parent
      A robust standard library wouldn’t fix it all but would go a long way towards improving things. Not only does application code have to import libraries for a bunch of really basic things, but so...

      A robust standard library wouldn’t fix it all but would go a long way towards improving things.

      Not only does application code have to import libraries for a bunch of really basic things, but so do the dependencies of all of those libraries. As a result, where on other platforms most commonly used libraries only go 2-3 layers deep on subdependencies, JS libraries go many times deeper. That adds up to a lot of extra weight fast.

      The other half of the equation is lack of capable, styleable widgets/controls included with HTML. Basic things like popup menus have probably been reimplemented tens of thousands of times for no good reason, and things that are frequently used table stakes in desktop/mobile UI frameworks (such as a scrolling list that recycles its items for efficiency) are totally absent in the browser.

      So on top of making the JS stdlib more robust, browsers/HTML also need a much better selection of widgets out of the box so it’s not necessary to pull in third party libraries so often.

      7 votes
      1. [6]
        fxgn
        Link Parent
        HTML actually has native popup menus since 2022! https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog

        things like popup menus have probably been reimplemented tens of thousands of times for no good reason

        HTML actually has native popup menus since 2022!

        https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog

        16 votes
        1. [5]
          RheingoldRiver
          Link Parent
          Woah, very cool! Looking forward to using this in 2030 lol

          Woah, very cool! Looking forward to using this in 2030 lol

          6 votes
          1. fxgn
            Link Parent
            "since 2022" was not referring to the date it was introduced to the spec, but rather to the date it got implemented in all major browsers. If you check the MSN link, it has a "Baseline 2022" badge...

            "since 2022" was not referring to the date it was introduced to the spec, but rather to the date it got implemented in all major browsers.

            If you check the MSN link, it has a "Baseline 2022" badge at the top, which means that it's safe to use

            https://caniuse.com/dialog

            It's supported since Chrome 37, Firefox 98 and Safari 15.4. You can safely use it already

            13 votes
          2. [3]
            teaearlgraycold
            Link Parent
            Thanks to Google’s monopolistic control over the web we can use it much sooner than that!

            Thanks to Google’s monopolistic control over the web we can use it much sooner than that!

            1. [2]
              RheingoldRiver
              Link Parent
              Google's monopolistic control of the web is why I will never use something unsupported by Firefox & Safari. Also, people don't update their browsers in a timely manner.

              Google's monopolistic control of the web is why I will never use something unsupported by Firefox & Safari. Also, people don't update their browsers in a timely manner.

              7 votes
              1. vord
                Link Parent
                It's a lot better than it used to be, given that not updating is mostly an opt-out now. Corporations are probably slower than average consumer devices anymore.

                It's a lot better than it used to be, given that not updating is mostly an opt-out now.

                Corporations are probably slower than average consumer devices anymore.

                3 votes
      2. [4]
        ComicSans72
        Link Parent
        The web honestly doesn't need a list that recycles it's views. Web rendering is crazy fucking fast compared to native mobile frameworks and doesn't jank even with list that's hundreds of thousands...

        The web honestly doesn't need a list that recycles it's views. Web rendering is crazy fucking fast compared to native mobile frameworks and doesn't jank even with list that's hundreds of thousands of items long. Browser rendering is already moved off the main thread and uses tiled rendering just because of this shit. It sucks at animations where layout changes (so are mobile frameworks), but it's great at scrolling huge documents.

        I don't really think you want shared libraries on the web shipped like this. It throws away privacy and opens you up to insanely dangerous cross site scripting attacks.

        4 votes
        1. [2]
          post_below
          Link Parent
          If you mean shipped as part of a local cache of commonly used libraries, that doesn't seem less secure than loading the libraries multiple times using arbitrary links provided by random websites....

          If you mean shipped as part of a local cache of commonly used libraries, that doesn't seem less secure than loading the libraries multiple times using arbitrary links provided by random websites.

          What privacy would you be throwing away? If you have the file locally then you don't have to tell anyone you're loading it.

          It's true that rendering is (mostly) fast, but only on a fast device. Not everyone has one. Bigger than the processor cycle cost, though, is the bandwidth cost. Even in developed countries people sometimes have slow connections due to congestion or location.

          On the scale of common libraries (like jQuery) that are being (re)downloaded for no reason countless times a second, you could even talk about the cumulative carbon footprint.

          6 votes
          1. ComicSans72
            Link Parent
            How does that work? You say "give me react 11.5.4"? What does the browser do if it doesn't have that version? Or if it's older? I guess you say "give me react 11.5.4. here's a link to it if you...

            How does that work? You say "give me react 11.5.4"? What does the browser do if it doesn't have that version? Or if it's older? I guess you say "give me react 11.5.4. here's a link to it if you don't have that"? What's the difference between that and the current http cache at that point?

            3 votes
        2. ButteredToast
          (edited )
          Link Parent
          I disagree, browsers absolutely need an HTML recycler widget. There’s been many times over the years where I’ve encountered infinite scrolling lists that only use as much JS as is needed to fetch...

          I disagree, browsers absolutely need an HTML recycler widget. There’s been many times over the years where I’ve encountered infinite scrolling lists that only use as much JS as is needed to fetch a page of new data and dump it in the page where after a few pages jank starts to creep in as resource consumption rises, eventually getting to a point where there’s readily visible stutter and on mobile devices, other (usually more important) apps start getting pushed out of memory.

          Contrast this to e.g. NSTableView in AppKit, a recycling table view, which back in the early 2000s could scroll a list with virtually unlimited items smoothly on a sub-1ghz single core machine with 128MB of RAM. I want to see this kind of efficiency on the web (and so do many devs, judging by the number of recycler widget libraries that exist).

          As far as shared libraries goes, while I’m not opposed to the idea I’d much rather obviate the vast majority of third party libraries altogether. We’ve already seen this happen with jQuery, which thanks to improvements in JS has been reimplemented in ultra tiny “sugar” libraries that wrap standard JS with jQuery syntax. Those comfortable with plain JS syntax can forgo jQuery entirely.

          There’s no reason this shouldn’t happen with any sufficiently popular library. React for instance is popular enough that by now browsers should have provisions for its most broadly used features, allowing React to become much more lightweight (being built around those provisions, letting the browser do the heavy lifting) and allowing for those with relatively basic needs to skip importing React entirely.

          Repeat this cycle enough times and the heavy, dependency-fractal JS libraries we’re familiar with today will eventually go extinct with most libraries instead implementing smaller-scoped, less frequently needed, highly specific functions or being little more than sugar.

          4 votes
  3. [3]
    first-must-burn
    Link
    JavaScript is far from my forte, but it seems like something like an optimizing compiler for JavaScript could solve some of this? Maybe even compile your JS app to webasm? C/C++ compilers are good...

    JavaScript is far from my forte, but it seems like something like an optimizing compiler for JavaScript could solve some of this? Maybe even compile your JS app to webasm? C/C++ compilers are good at dropping symbols that are never used. Seems like that would help with the "loading a 3mb library to use the string reverse function" problem too.

    Maybe there is something about the dynamic nature of JavaScript that prevents this? But I can see even subsetting the language to make this possible would be a win for the language in the long run.

    6 votes
    1. danke
      Link Parent
      The JS world's jargon for LTO / dead code removal is called "tree shaking" and it's something that the most popular bundlers support, but most libraries are designed in a way that isn't decoupled...

      The JS world's jargon for LTO / dead code removal is called "tree shaking" and it's something that the most popular bundlers support, but most libraries are designed in a way that isn't decoupled enough to make it as efficient as it could be (e.g. runtime selection of code paths).

      8 votes
    2. marcel
      Link Parent
      We have compilers, lots of them actually. Hundreds! uglify-js (included by default in the popular bundlers) will fold constant expressions, shake dead code, you can even enable unsafe math...

      We have compilers, lots of them actually. Hundreds! uglify-js (included by default in the popular bundlers) will fold constant expressions, shake dead code, you can even enable unsafe math optimizations and others. Google has been using Closure for decades and its results are pretty remarkable.

      There's even domain specific optimizers optimize concatenation of CSS class names, optimize react expressions (and a brand new one from the react team). Tons of em.

      You just have to care though. It's frankly easier to launch a 20MB website and then have a big meeting to fix it once it gets too bad. JavaScript isn't an "only one way to do it" language though and if you pull in a bunch of packages from npm each of those packages might pull in their own favorite library which gets out of hand quickly. It's led to a lot of teams being able to build pretty complex projects very quickly, at the cost of some bytes.

      6 votes