The Web Almanac by HTTP Archive

By admin
Part I Chapter 2

JavaScript

JavaScript is a powerful force that provides the lion’s share of interactivity on the web. It drives behaviors from the simple to the complex, and is making more things possible on the web than ever before.

Yet, the increased usage of

JavaScript
PRODUCT

to deliver rich user experiences comes at a cost. From the moment JavaScript is downloaded, parsed, and compiled, to every line of code it executes, the browser must orchestrate all kinds of work to make everything possible. Doing too little with JavaScript means you might fall short of fulfilling user experience and business goals. On the other hand, shipping too much on JavaScript means you will be creating user experiences that are slow to load, sluggish to respond, and frustrating to users.


This year
DATE

, we’ll once again be looking at the role of

JavaScript
ORG

on the web, as we present our findings for

2022
DATE

and offering advice for creating delightful user experiences.

To begin, we’ll assess the amount of

JavaScript
ORG

web developers ship on the web. After all, before improvements can be made, an assessment of the current landscape must be performed.

Explore the results View data

View query

View image Show description of Figure

2.1
CARDINAL

Bar chart showing the

10
CARDINAL

,

25
DATE

,

50
DATE

,

75
DATE

, and

90th
ORDINAL

percentiles of

JavaScript
PRODUCT

kilobytes per page. On mobile pages, the values are

87
CARDINAL

,

209
CARDINAL

,

461
CARDINAL

,

857
CARDINAL

, and

1,367
CARDINAL


KB
ORG

respectively. Desktop values are slightly higher across the board. Figure

2.1
CARDINAL

. Distribution of the amount of

JavaScript
PRODUCT

loaded per page.

As was the case

last year
DATE

, this year marks yet another increase in the amount of

JavaScript
PRODUCT

shipped to browsers. From

2021 to 2022
DATE

, an increase of

8%
PERCENT

for mobile devices was observed, whereas desktop devices saw an increase of

10%
PERCENT

. While this increase is less steep than in

previous years
DATE

, it’s nonetheless the continuation of a concerning trend. While device capabilities continue to improve, not every one is running the latest device. The fact remains that more JavaScript equates to more strain on a device’s resources.

Explore the results View data

View query

View image Show description of Figure

2.2
CARDINAL

Bar chart showing the

10
CARDINAL

,

25
DATE

,

50
DATE

,

75
DATE

, and

90th
ORDINAL

percentiles of kilobytes of unused

JavaScript
PRODUCT

per page. On mobile pages, the values are

0
CARDINAL

,

62
DATE

,

162
CARDINAL

,

342
CARDINAL

, and

604
CARDINAL

. Desktop trends slightly higher. Figure

2.2
CARDINAL

. Distribution of the amount of unused

JavaScript
PRODUCT

bytes.

According to

Lighthouse
ORG

, the median mobile page loads

162
CARDINAL

KB of unused

JavaScript
PRODUCT

. At the

90th
ORDINAL

percentile,

604
CARDINAL

KB of

JavaScript
ORG

are unused. This is a slight uptick from

last year
DATE

, where the median and

90th
ORDINAL

percentile of unused

JavaScript
PRODUCT

was

155
CARDINAL


KB
ORG

and

598
CARDINAL

KB, respectively. All of this represents a very large amount of unused

JavaScript
PRODUCT

, especially when you consider that this analysis tracks the transfer size of

JavaScript
ORG

resources which, if compressed, means that the decompressed portion of used

JavaScript
PRODUCT

may be a lot larger than the chart suggests.

When contrasted with the total number of bytes loaded for mobile pages at the median, unused

JavaScript
ORG

accounts for

35%
PERCENT

of all loaded scripts. This is down slightly from

last year
DATE

’s figure of

36%
PERCENT

, but is still a significantly large chunk of bytes loaded that go unused. This suggests that many pages are loading scripts that may not be used on the current page, or are triggered by interactions later on in the page lifecycle, and may benefit from dynamic import() to reduce startup costs.

Every resource on a page will kick off

at least one
CARDINAL

request, and possibly more if a resource makes additional requests for more resources.

Where script requests are concerned, the more there are, the more likely you’ll not just load more

JavaScript
PRODUCT

, but also increase contention between script resources that may bog down the main thread, leading to slower startup.

Explore the results View data

View query

View image Show description of Figure

2.3
CARDINAL

Bar chart showing the

10
CARDINAL

,

25
DATE

,

50
DATE

,

75
DATE

, and

90th
ORDINAL

percentiles of

JavaScript
ORG

requests per page. On mobile pages, the values are

4
CARDINAL

,

10
DATE

,

21
DATE

,

37
DATE

, and

60
CARDINAL

. Desktop trends slightly higher by

1-3
CARDINAL

requests across the board. Figure

2.3
CARDINAL

. Distribution of the number of

JavaScript
ORG

requests per page.

In

2022
DATE

, the median mobile page responded to

21 JavaScript
CARDINAL

requests, whereas at the

90th
ORDINAL

percentile, there were

60
CARDINAL

. Compared to

last year
DATE

, this is an increase of

1
CARDINAL

request at the median and

4
CARDINAL

requests at the

90th
ORDINAL

percentile.

Where desktop devices in

2022
DATE

are concerned, there are

22
CARDINAL

JavaScript requests at the median, and

63
CARDINAL

at the

90th
ORDINAL

percentile. Compared to

last year
DATE

, this is an increase of

1 JavaScript
CARDINAL

request at the median, and

4
CARDINAL

at the

90th
ORDINAL

percentile—the same increase as noted for mobile devices.

While not a large increase in the number of requests, it does continue the trend of increased requests

year
DATE

over year since

the Web Almanac
ORG

’s inception in

2019
DATE

.

Since the advent of

JavaScript
PRODUCT

runtimes such as Node.js, it has become increasingly common to rely on build tools in order to bundle and transform JavaScript. These tools, while undeniably useful, can have effects on how much JavaScript is shipped. New to

the Web Almanac
ORG


this year
DATE

, we’re presenting data on the usage of bundlers and transpilers.

JavaScript bundlers are build-time tools that process a project’s

JavaScript
PRODUCT

source code and then apply transformations and optimizations to it. The output is production-ready JavaScript. Take the following code as an example:

function sum (a, b) { return a + b; }

A bundler will transform this code to a smaller, but more optimized equivalent that takes less time for the browser to download:

function n (n,r){ return n + r}

Given the optimizations bundlers perform, they are a crucial part of optimizing source code for better performance in production environments.

There are a wealth of choices when it comes to JavaScript bundlers, but one that pops into mind often is webpack. Fortunately, webpack’s generated

JavaScript
PRODUCT

contains a number of signatures ( webpackJsonp , for example) that make it possible to detect if a website’s production

JavaScript
PRODUCT

has been bundled using webpack.

Explore the results View data

View query

View image Show description of Figure

2.4
CARDINAL

Bar chart showing the percentage of pages that use webpack, in decreasing order of popularity. On mobile, the values are

17%
PERCENT

for the top

1k
CARDINAL

,

15%
PERCENT

for the top

10k
CARDINAL

,

12%
PERCENT

for the top

100k
CARDINAL

,

8%
PERCENT

for the top

1
CARDINAL

M, and

5%
PERCENT

over all websites. Desktop pages trend close to mobile. Figure

2.4
CARDINAL

. Pages that use webpack-bundled

JavaScript
PRODUCT

by rank.

Of the

1,000
CARDINAL

most popular websites,

17%
PERCENT

use webpack as a bundler. This makes sense, as many of the top pages HTTP Archive crawls are likely to be high-profile ecommerce sites that use webpack to bundle and optimize source code. Even so, the fact that

5%
PERCENT

of the all pages in the HTTP Archive dataset use webpack is a significant statistic. However, webpack isn’t the only bundler in use.

Explore the results View data

View query

View image Show description of Figure

2.5
CARDINAL

Bar chart showing the percentage of pages that use Parcel, in decreasing order of popularity. On mobile, the values are

1.3%
PERCENT

for the top

1k
CARDINAL

,

1.9%
PERCENT

for the top

10k
CARDINAL

,

1.5%
PERCENT

for the top

100k
CARDINAL

,

1.2%
PERCENT

for the top

1
CARDINAL

M, and

1.3%
PERCENT

over all websites. Desktop pages trend close to mobile. Figure

2.5
CARDINAL

. Pages that use Parcel-bundled

JavaScript
PRODUCT

by rank.

Parcel is a noteworthy alternative to webpack, and its adoption is significant. Parcel’s adoption is consistent across all ranks, accounting for a range of

1.2% to 1.9%
PERCENT

across rankings.

While

HTTP Archive
ORG

is unable to track the usage of all bundlers in the ecosystem, bundler usage is significant in the overall picture of

JavaScript
PRODUCT

in that they’re not only important to the developer experience, but the overhead they can contribute in the form of dependency management code can be a factor in how much JavaScript is shipped. It’s worth checking how your overall project settings are configured to produce the most efficient possible output for the browsers your users use.

Transpilers are often used in toolchains at build-time to transform newer

JavaScript
PRODUCT

features into a syntax that can be run in older browsers. Because

JavaScript
ORG

has evolved rapidly over

the years
DATE

, these tools are still in use. New to this

year
DATE

’s

Web Almanac
ORG

is an analysis of the usage of

Babel
FAC

in delivering widely compatible, production-ready JavaScript. The singular focus on

Babel
ORG

specifically is due to its wide usage in the developer community over alternatives.

Explore the results View data

View query

View image Show description of Figure

2.6
CARDINAL

Bar chart showing the percentage of pages that use

Babel
PERSON

, in decreasing order of popularity. On mobile pages, the values are

40%
PERCENT

of the top

1k
CARDINAL

,

40%
PERCENT

of the top

10k
CARDINAL

,

32%
PERCENT

fo the top

100k
CARDINAL

,

23%
PERCENT

of the top

1
CARDINAL

M, and

26%
PERCENT

over all websites. Desktop pages trend close to mobile. Figure

2.6
CARDINAL

. Pages that use

Babel
PERSON

by rank.

These results are not a surprising development when you consider how much JavaScript has evolved over

the years
DATE

. In order to maintain broad compatibility for a certain set of browsers,

Babel
PERSON

uses transforms to output compatible

JavaScript
PRODUCT

code.

Transforms are often larger than their untransformed counterparts. When transforms are extensive or duplicated across a codebase, potentially unnecessary or even unused JavaScript may be shipped to users. This can adversely affect performance.

Considering that even

26%
PERCENT

of pages ranked in the top

million
CARDINAL

are transforming their

JavaScript
PRODUCT

source code using

Babel
ORG

, it’s not unreasonable to assume that some of these experiences may be shipping transforms they don’t need. If you use Babel in your projects, carefully review

Babel
ORG

’s available configuration options and plugins to find opportunities to optimize its output.

Since

Babel
ORG

also relies on

Browserslist
ORG

to figure out whether it needs to transform certain features to a legacy syntax, be sure to also review your

Browerslist
ORG

configuration to ensure that your code is transformed to work in the browsers your users actually use.

The manner in which

JavaScript
PRODUCT

is requested may also have performance implications. There are optimal ways you can request JavaScript, and in some cases, there are far less optimal methods. Here, we’ll see how the web is shipping JavaScript overall, and how that aligns with performance expectations.

The async and defer attributes on the HTML <script> element control the behavior of how scripts load. The async attribute will prevent scripts from blocking parsing, but will execute as soon as they are downloaded, so may still block rendering. The defer attribute will delay execution of scripts until the

DOM
ORG

is ready so should prevent those scripts from blocking both parsing and rendering.

The

type="module
PERSON

" and

nomodule
PRODUCT

attributes are specific to the presence (or absence) of ES6 modules being shipped to the browser. When

type="module
PERSON

" is used, the browser expects that the content of those scripts will contain ES6 modules, and will defer the execution of those scripts until the

DOM
ORG

is constructed by default. The opposite nomodule attribute indicates to the browser that the current script does not use ES6 modules.


Feature Desktop Mobile
ORG

async

76%
PERCENT


76%
PERCENT

defer

42%
PERCENT


42%
PERCENT

async and defer

28%
PERCENT


29%
PERCENT

module

4%
PERCENT


4%
PERCENT


nomodule
ORG


0%
PERCENT


0%
PERCENT

Explore the results View data

View query Figure

2.7
CARDINAL

. Percentage of pages using async , defer , async and defer ,

type="module
PERSON

" , and

nomodule
ORG

attributes on <script> elements.

It’s encouraging that

76%
PERCENT

of mobile pages load scripts with async , as that suggests developers are cognizant of the effects of render blocking. However, such a low usage of defer suggests that there are opportunities being left on the table to improve rendering performance.

As noted

last year
DATE

, using both async and defer is an antipattern that should be avoided as the defer part is ignored and async takes precedence.

The general absence of

type="module
PERSON

" and

nomodule
PERSON

is not surprising, as few pages seem to be shipping

JavaScript
PRODUCT

modules. As time goes on, the usage of

type="module
PERSON

" in particular may increase, as developers ship untransformed

JavaScript
PRODUCT

modules to the browser.

Looking at the percentage of overall scripts across all the sites, presents a slightly different view:


Feature Desktop Mobile
ORG

async

49.3%
PERCENT


47.2%
PERCENT

defer

8.8%
PERCENT


9.1%
PERCENT

async and defer

3.0%
PERCENT


3.1%
PERCENT

module

0.4%
PERCENT


0.4%
PERCENT


nomodule
ORG


0%
PERCENT


0%
PERCENT

Explore the results View data

View query Figure

2.8
CARDINAL

. Percentage of scripts using async , defer , async and defer ,

type="module
PERSON

" , and

nomodule
ORG

attributes on <script> elements.

Here we see a much smaller use of both async and defer . Some of these scripts may be being inserted dynamically after the initial rendering, but it’s also likely a good proportion of pages are not setting these attributes on a lot of their scripts that are included in the initial HTML and so are delaying rendering.

Resource hints such as preload , prefetch , and modulepreload are useful in hinting to the browser which resources should be fetched early. Each hint has a different purpose, with preload used to fetch resources needed for the current navigation, modulepreload the equivalent for preloading scripts that contain

JavaScript
PRODUCT

modules, and prefetch used for resources needed in the next navigation.

Resource hint Desktop Mobile preload

16.4%
PERCENT


15.4%
PERCENT

prefetch

1.0%
PERCENT


0.8%
PERCENT

modulepreload

0.1%
PERCENT


0.1%
PERCENT

Explore the results View data

View query Figure

2.9
CARDINAL

. Percentage of pages using various resource hints.

Analyzing the trend of resource hint adoption is tricky. Not all pages benefit from them, and it’s unwise to make a blanket recommendation to use resource hints broadly, as their overuse has their own consequences—especially where preload is concerned. However, the relative abundance of preload hints on

15%
PERCENT

of mobile pages suggests that many developers are aware of this performance optimization, and are trying to use it to their advantage.

prefetch is tricky to use, though it can be beneficial for long, multi-page sessions. Even so, prefetch is entirely speculative, so much so that browsers may ignore it in certain conditions. This means some pages may waste data by requesting resources which go unused. It really “just depends”.

The lack of use of modulepreload makes sense, since adoption of the

type="module
PERSON

" attribute on <script> elements is similarly low. Even so, apps that ship

JavaScript
PRODUCT

modules without transformations could benefit from this resource hint, as it will not fetch just the named resource, but the entire module tree. This could help in certain situations.

Let’s dig into an analysis of how many of each resource hint type is used.

Explore the results View data

View query

View image Show description of Figure

2.10
CARDINAL

Bar chart showing the

10
CARDINAL

,

25
DATE

,

50
DATE

,

75
DATE

, and

90th
ORDINAL

percentiles of prefetch hints for

JavaScript
ORG

resources per page. The values for mobile pages are

1
CARDINAL

,

2
DATE

,

3
DATE

,

7
DATE

, and

16
CARDINAL

, respectively. Desktop values trend higher above the

50th
ORDINAL

percentile by

1-4
CARDINAL

hints per page. Figure

2.10
CARDINAL

. Distribution of prefetch adoption for

JavaScript
ORG

resources per page.

Adoption of prefetch here is somewhat surprising, with

three
CARDINAL

prefetch hints for

JavaScript
ORG

resources per page. However, the number of these hints at the

75th
ORDINAL

and

90th
ORDINAL

percentiles suggests that there may be a fair amount of waste in the form of unused resources for page navigations that never occur.

Explore the results View data

View query

View image Show description of Figure

2.11
CARDINAL

Bar chart showing the

10
CARDINAL

,

25
DATE

,

50
DATE

,

75
DATE

, and

90th
ORDINAL

percentiles of preload hints for

JavaScript
ORG

resources per page. The values for mobile pages are

1
CARDINAL

,

1
CARDINAL

,

2
DATE

,

3
DATE

, and

5
CARDINAL

, respectively. Desktop values are nearly identical to mobile. Figure

2.11
CARDINAL

. Distribution of preload adoption for

JavaScript
ORG

resources per page.

Remember—this analysis tracks how many resource hints are used for

JavaScript
ORG

resources on pages that use

one
CARDINAL

or more preload hints. The median page is delivering

two
CARDINAL

preload hints for

JavaScript
ORG

, which isn’t bad on its face, but it often depends on the size of the script, how much processing scripts can kick off, or whether the script fetched via preload is even needed for the initial page load.

Unfortunately, we see

five
CARDINAL

preload hints for

JavaScript
PRODUCT

resources at the

90th
ORDINAL

percentile, which may be too much. This suggests that pages at the

90th
ORDINAL

percentile are especially reliant on

JavaScript
ORG

, and are using preload to try and overcome the performance issues that result.

Explore the results View data

View query

View image Show description of Figure

2.12
CARDINAL

Bar chart showing the

10
CARDINAL

,

25
DATE

,

50
DATE

,

75
DATE

, and

90th
ORDINAL

percentiles of modulepreload hints for

JavaScript
ORG

resources per page. The values for mobile pages are

1
CARDINAL

,

1
CARDINAL

,

2
DATE

,

6
DATE

, and

14
CARDINAL

, respectively. Desktop values are nearly identical to mobile. Figure

2.12
CARDINAL

. Distribution of modulepreload adoption for

JavaScript
ORG

resources per page.

With modulepreload , we see a staggering

6
CARDINAL

hints at the

75th
ORDINAL

percentile, and

14
CARDINAL

at the

90th
ORDINAL

percentile! This suggests that, while pages using

one
CARDINAL

or more modulepreload hints at upper percentiles are shipping untransformed ES6 modules directly to the browser, the need for so many resource hints suggests an overreliance on

JavaScript
PRODUCT

at the upper range.

Resource hints are great tools for optimizing how we load resources in the browser, but if there’s

one
CARDINAL

piece of advice you can heed when using them, it’s to use them sparingly, and for resources that may not be initially discoverable; for example, a

JavaScript
ORG

file initially loaded in the

DOM
ORG

that requests another one. Rather than preloading loads of scripts, try to whittle down the amount of JavaScript you’re shipping, as that will lead to a better user experience rather than preloading gobs of it.

An old and often-touted best practice for performance has been to load your JavaScript in the footer of the document to avoid render blocking of scripts and to ensure the

DOM
ORG

is constructed before your scripts have a chance to run. In recent times, however, it has been more commonplace in certain architectures to place <script> elements in the document <head> .

This can be a good way to prioritize the loading of

JavaScript
PRODUCT

in web applications, but async and defer attributes should be used where possible to avoid render blocking of the

DOM
ORG

. Render blocking is when the browser must halt all rendering of the page in order to process a resource that the page depends on. This is done to avoid unpleasant effects such as the flash of unstyled content, or

JavaScript
PRODUCT

runtime errors that can occur when the

DOM
ORG

isn’t ready for a script that depends on

DOM
ORG

readiness.


77%
PERCENT

Explore the results View data

View query Figure

2.13
CARDINAL

. The percentage of mobile pages that have render-blocking scripts in the document <head> .

We found that

77%
PERCENT

of mobile pages have

at least one
CARDINAL

render-blocking script in the document <head> , whereas

79%
PERCENT

of desktop pages do this. This is a concerning trend, because when scripts block rendering, page content is not painted as quickly as it could be.

Explore the results View data

View query

View image Show description of Figure

2.14
CARDINAL

Bar chart showing the percent of pages that have render-blocking JavaScript segmented by site popularity.

63%
PERCENT

of the top

1k
CARDINAL

mobile pages have it,

68%
PERCENT

of the top

10k
CARDINAL

,

70%
PERCENT

of the top

100k
CARDINAL

,

73%
PERCENT

of the top

1
CARDINAL

M, and

77%
PERCENT

overall. Desktop pages tend to have more render-blocking JavaScript, especially among the more popular pages. Figure

2.14
CARDINAL

. Pages by rank that have render-blocking scripts in the document <head> .

When looking at the problem by ranked pages, we see a similarly troubling pattern. In particular,

63%
PERCENT

of the top

1,000
CARDINAL

websites accessed on mobile devices ship

at least one
CARDINAL

render blocking script in the <head> , and the proportion of pages increases as we proceed through the ranks.

There are solutions to this: using defer is a relatively safe bet that will unblock the

DOM
ORG

from rendering. Using async (when possible) is a good option, and will allow scripts to run immediately, but those scripts must not have any dependencies on other <script> elements, otherwise errors could occur.

Where possible, render-critical

JavaScript
PRODUCT

can be placed in the footer and preloaded so the browser can get a head start on requesting those resources. Either way, the state of render-blocking

JavaScript
PRODUCT

in tandem with how much JavaScript we ship is not good, and web developers should make more of an effort to curb these issues.

Script injection is a pattern where an HTMLScriptElement is created in

JavaScript
ORG

using document.createElement and injected into the

DOM
ORG

with a

DOM
ORG

insertion method. Alternatively, <script> element markup in a string can be injected into the

DOM
ORG

via the

innerHTML
GPE

method.

Script injection is a fairly common practice used in a number of scenarios, but the problem with it is that it defeats the browser’s preload scanner by making the script undiscoverable as the initial HTML payload is parsed. This can affect metrics such as Largest Contentful Paint (LCP) if the injected script resource is ultimately responsible for rendering markup, which itself can kick off long tasks to parse large chunks of markup on the fly.

Explore the results View data

View query

View image Show description of Figure

2.15
CARDINAL

Bar chart showing the

10
CARDINAL

,

25
DATE

,

50
DATE

,

75
DATE

, and

90th
ORDINAL

percentiles of the percent of scripts per page that are injected. On mobile pages, the values are

0%
PERCENT

,

8%
PERCENT

,

25%
PERCENT

,

50%
PERCENT

, and

70%
PERCENT

respectively. Desktop values are nearly identical. Figure

2.15
CARDINAL

. Distribution of percentage of injected scripts across various percentiles.

At the median, we see that

25%
PERCENT

of a page’s scripts are injected, as opposed to leaving them discoverable in the initial HTML response. More concerning is that the

75th
ORDINAL

and

90th
ORDINAL

percentiles of pages inject

50% and 70%
PERCENT

of scripts respectively.

Script injection has the potential to harm performance when used to render page content the user consumes, and should be avoided in these cases whenever necessary. That script injection is so prevalent in

today
DATE

’s web is a concerning trend. Modern frameworks and tooling may rely on this pattern, which means that some out-of-the-box experiences may rely on this potential anti-pattern to provide functionality for websites.

There are

two
CARDINAL

categories of

JavaScript
PRODUCT

that websites often ship:

First-party scripts that power the essential functions of your website and provide interactivity.

Third-party scripts provided by external vendors that satisfy a variety of requirements, such as

UX
ORG

research, analytics, providing advertising revenue, and embeds for things such as videos and social media functions.

While

first
ORDINAL

-party JavaScript may be easier to optimize,

third
ORDINAL

-party JavaScript can itself be a significant source of performance problems, as

third
ORDINAL

-party vendors may not prioritize the optimization of their

JavaScript
PRODUCT

resources over adding new features to serve additional business functions for their clients. Additionally,

UX
ORG

researchers, marketers, and other non-technical personnel may be hesitant to give up functionality or sources of revenue that these scripts provide.

In this section, we’ll analyze the breakdown of

first
ORDINAL

-party and

third
ORDINAL

-party code, and comment on the current state of how websites

today
DATE

are divvying up how they load

JavaScript
PRODUCT

—and where from.

Explore the results View data

View query

View image Show description of Figure

2.16
CARDINAL

Bar chart showing the

10
CARDINAL

,

25
DATE

,

50
DATE

,

75
DATE

, and

90th
ORDINAL

percentiles of

JavaScript
ORG

requests per mobile page, broken down by whether the script was served by a

first-
ORDINAL

or

third
ORDINAL

-party host. The values for both are nearly identical, at

2
CARDINAL

,

4
DATE

,

10
DATE

,

20
DATE

, and

34
DATE

, respectively. Figure

2.16
CARDINAL

. Distribution of first- versus

third
ORDINAL

-party JavaScript requests by host.

Here, we see a sobering picture. Regardless of the percentile, it seems that all observed hosts are serving an equivalent amount of

first
ORDINAL

and

third
ORDINAL

-party scripts. The median host serves

10
CARDINAL

of each type, the

75th
ORDINAL

percentile serves

20
CARDINAL

of each type, and the

90th
ORDINAL

percentile host serves

34 third
CARDINAL

-party scripts!

This is a problematic and worrying trend.

Third
ORDINAL

-party scripts are responsible for all sorts of damage when it comes to performance.

Third
ORDINAL

-party scripts may do a number of things, such as running expensive timers that orchestrate multitudes of tasks, attach their own event listeners that add extra work which can delay interactivity, and some video and social media

third
ORDINAL

-parties ship exorbitant amounts of scripts to power the services they provide.

Steps for mitigating

third
ORDINAL

-party scripts is often more of a cultural affair than an engineering one. If you’re shipping excessive

third
ORDINAL

-party scripts, conduct an audit of each script, what they do, and profile their activity to find out what performance problems they’re incurring.

If you’re doing considerable

UX
ORG

research, consider collecting your own field data (if the origin sends a proper

Timing-Allow-Origin
ORG

header) to make informed decisions to avoid the performance problems that some

third
ORDINAL

-party scripts can cause. For every

third
ORDINAL

-party script you add, you’re not just incurring loading costs, but also costs during runtime where responsiveness to user input is crucial.

So we know that hosts are shipping a lot of

third
ORDINAL

-party scripts, but what’s the byte cost of

first-
ORDINAL

versus

third
ORDINAL

-party scripts?

Explore the results View data

View query

View image Show description of Figure

2.17
CARDINAL

Bar chart showing the

10
CARDINAL

,

25
DATE

,

50
DATE

,

75
DATE

, and

90th
ORDINAL

percentiles of kilobytes of

JavaScript
PRODUCT

loaded per mobile page, broken down by whether the script was served by a

first-
ORDINAL

or

third
ORDINAL

-party host. The values for

third
ORDINAL

-parties are

34
CARDINAL

,

109
CARDINAL

,

292
CARDINAL

,

595
CARDINAL

, and

1,003 KB
QUANTITY

per page, respectively. First-party scripts are much lower, at

20, 65
DATE

,

109
CARDINAL

,

309
CARDINAL

, and

642 KB
QUANTITY

per page. Figure

2.17
CARDINAL

. Distribution of first- versus

third
ORDINAL

-party

JavaScript
PRODUCT

bytes by host.

At nearly every percentile, the amount of bytes

third
ORDINAL

-party scripts ship exceeds that of

first
ORDINAL

-party scripts. At the

75th
ORDINAL

percentile, it appears that

third
ORDINAL

-party script payloads are twice that of

first
ORDINAL

-party scripts. At the

90th
ORDINAL

percentile, it appears that the amount of

third
ORDINAL

-party scripts sent over the wire is nearly one megabyte.

If you find your website’s

first
ORDINAL

versus

third
ORDINAL

-party script payloads is similar to the graph above, it is key that you should work with your engineering organization to try and get this number down. It can only help your users if you do.

Dynamic import() is a variant of the static import syntax that can be run anywhere in a script, whereas static import expressions must be run at the top of a JavaScript file and nowhere else.

Dynamic import() allows developers to effectively “split” off chunks of

JavaScript
PRODUCT

code from their main bundles to be loaded on-demand, which can improve startup performance by loading less

JavaScript
PRODUCT

upfront.


0.34%
PERCENT

Explore the results View data

View query Figure

2.18
CARDINAL

. The percentage of mobile pages using dynamic import() .

A staggeringly low

0.34%
PERCENT

of all observed mobile pages currently use dynamic import() , while

0.41%
PERCENT

of desktop pages use it. That said, it’s common for some bundlers to transform the dynamic import() syntax into an ES5-compatible alternative. It’s very likely that the feature is in wider use, just less so in production

JavaScript
PRODUCT

files.

It’s tricky, but a balance can be struck, and it involves gauging the user’s intent.

One
CARDINAL

way of deferring loading of

JavaScript
PRODUCT

without delaying interactions is to preload that JavaScript when the user signals intent to make an interaction.

One
CARDINAL

example of this could be to defer loading JavaScript for the validation of a form, and preload that JavaScript once the user has focused a field in that form. That way, when the

JavaScript
ORG

is requested, it will already be in the browser cache.

Another way could be to use a service worker to

precache JavaScript
ORG

necessary for interactions when the service worker is installed. Installation should occur at a point in which the page has fully loaded in the page’s load event. That way, when the necessary functionality is requested, it can be retrieved from the service worker cache without startup costs.

Dynamic import() is tricky to use, but more widespread adoption of it can help shift the performance cost of loading JavaScript from startup to a later point in the page lifecycle, presumably when there will be less network contention for resources. We hope to see increased adoption of dynamic import() , as the amount of JavaScript we see loaded during startup is only increasing.

Web workers are a web platform feature that reduces main thread work by spinning up a specialized

JavaScript
PRODUCT

file without direct access to the

DOM
ORG

on its own thread. This technology can be used to offload tasks that could otherwise overwhelm the main thread by doing that work on a separate thread altogether.


12%
PERCENT

Explore the results View data

View query Figure

2.19
CARDINAL

. The number of mobile pages using web workers.

It’s heartening to see that

12%
PERCENT

of mobile and desktop pages currently use

one
CARDINAL

or more web workers to relieve the main thread of work that could potentially make the user experience worse—but there’s a lot of room for improvement.

If you have significant work that can be done without direct access to the

DOM
ORG

, using a web worker is a good idea. While you have to use a specialized communication pipeline to transfer data to and from a web worker, it’s entirely possible to make your web pages much more responsive to user input by using the technology.

However, that communication pipeline can be tricky to set up and use, though there are open source solutions that can simplify this process. comlink is

one
CARDINAL

such library that helps with this, and can make the developer experience around web workers much more enjoyable.

Whether you manage web workers on your own or with a library, the point is this: if you have expensive work to do, gauge whether or not it needs to happen on the main thread, and if not, strongly consider using web workers to make the user experience of your websites as good as it possibly can be.

Worklets are a specialized type of worker that allows lower-level access to rendering pipelines for tasks such as painting and audio processing. While there are

four
CARDINAL

types of worklets,

only two
CARDINAL

—paint worklets and audio worklets—are currently implemented in available browsers.

One
CARDINAL

distinct performance advantage of worklets is that they run on their own threads, freeing up the main thread from expensive drawing and audio processing work.


0.0013%
PERCENT

Explore the results View data

View query Figure

2.20
CARDINAL

. The percentage of mobile pages that register

at least one
CARDINAL

paint worklet.

With worklets being such niche technologies, it’s not surprising that they’re not widely used. Paint worklets are an excellent way of offloading expensive processing for generative artwork onto another thread—not to mention a great technique for adding a bit of flair to the user experience. For

every 1 million
CARDINAL

websites,

only 13
CARDINAL

of them use a paint worklet.


0.0004%
PERCENT

Explore the results View data

View query Figure

2.21
CARDINAL

. The percentage of mobile pages that register

at least one
CARDINAL

audio worklet.

Adoption of audio worklets is even lower:

only four
CARDINAL

in a

million
CARDINAL

websites use it. It will be interesting to see how adoption of these technologies trends over time.

An equally important aspect of

JavaScript
PRODUCT

performance is how we deliver scripts to the browser, which includes a few common—yet sometimes missed—opportunities for optimization, starting with how we compress JavaScript.

Compression is an often-used technique that applies largely to text-based assets, such as HTML,

CSS
ORG

,

SVG
ORG

images, and yes, JavaScript. There are a variety of compression techniques that are widely used on the web that can speed up the delivery of scripts to the browser, effectively shortening the resource load phase.

Explore the results View data

View query

View image Show description of Figure

2.22
CARDINAL

Bar chart comparing the percent of script requests having either gzip,

Brotli
ORG

, deflate, or no compression method set. On mobile pages, the values are

52%
PERCENT

,

34%
PERCENT

,

0%
PERCENT

, and

13%
PERCENT

respectively. Desktop values are within

1
CARDINAL

percentage point. Figure

2.22
CARDINAL

. Compression of JavaScript by method.

There are a few compression techniques that can be used to reduce the transfer size of a script, with the

Brotli
ORG

(br) method being the most effective. Despite

Brotli
ORG

’s excellent support in modern browsers, it’s still clear that gzip is the most preferred method of compression. This is likely due to the fact that many web servers use it as the default.

When something is the default, that default sometimes remains in place rather than being tuned for better performance. Given that

only 34%
PERCENT

of pages observed are compressing scripts with

Brotli
ORG

, it’s clear that there’s an opportunity on the table to improve the loading performance of script resources, but it’s also worth noting that it is an improvement over

last year
DATE

’s adoption at

30%
PERCENT

.

Explore the results View data

View query

View image Show description of Figure

2.23
CARDINAL

Bar chart showing the percent of script requests on mobile pages that use each compression method, broken down by whether it was served by a

first-
ORDINAL

or

third
ORDINAL

-party host.

60%
PERCENT

of

third
ORDINAL

-party hosts serve scripts compressed with gzip,

29%
PERCENT

with

Brotli
ORG

,

12%
PERCENT

without any compression method, and

0%
PERCENT

with deflate. Among

first
ORDINAL

-party hosts,

45%
PERCENT

serve gzip,

40%
PERCENT

with

Brotli
ORG

,

15%
PERCENT

wtihotu any compression method, and

0%
PERCENT

with deflate. Figure

2.23
CARDINAL

. Compression methods of script resources by host.

The problem is made worse by

third
ORDINAL

-party script providers, which still deploy gzip compression more widely than

Brotli
ORG

at

60%
PERCENT

versus

29%
PERCENT

, respectively. Given that

third
ORDINAL

-party

JavaScript
PRODUCT

is a serious performance issue on the web

today
DATE

, the resource load time of these resources could be reduced by deploying

third
ORDINAL

-party resources using

Brotli
ORG

instead.

Explore the results View data

View query

View image Show description of

Figure 2.24 Histogram
ORG

showing the distribution of kilobytes of uncompressed

JavaScript
PRODUCT

resources on mobile pages, broken down by whether the script was served by a

first-
ORDINAL

or

third
ORDINAL

-party host. Uncompressed

third
ORDINAL

-party scripts skew much more towards the small end,

90%
PERCENT

of requests are less than 5 KB, with

3%
PERCENT

of requests being

5-10
QUANTITY

KB in size, and

2%
PERCENT

being

100
CARDINAL

+ KB on the other end of the spectrum. First-party scripts skew more towards being larger in size, with

only 50%
PERCENT

being less than 5 KB,

12%
PERCENT


between 5 and 10
DATE


KB
ORG

, and

6%
PERCENT

exceeding

100
CARDINAL

KB. Figure

2.24
CARDINAL

. Uncompressed resources by size.

Thankfully, we’re seeing that it’s only mostly the smallest resources, specifically those

third
ORDINAL

-party scripts that have payloads smaller than 5 KB, that are being delivered without compression. This is because compression yields diminishing returns when applied to small resources, and in fact, the added overhead of dynamic compression may cause delayed resource delivery. There are, unfortunately, some opportunities across the spectrum to compress larger resources, such as some

first
ORDINAL

-party scripts with payloads over 100 KB.

Always check your compression settings to ensure you’re delivering the smallest possible script payloads over the network, and remember: compression speeds up resource delivery. Those scripts, once delivered to the browser, will be decompressed and their processing time will not change due to compression. Compression is not a good excuse to deliver huge script payloads that can make interactivity worse during startup.

Minification of text assets is a time-tested practice for reducing file size. The practice involves removing all of the unnecessary spaces and comments from source code in order to reduce their transfer size. A further step known as uglification is applied to

JavaScript
ORG

, which reduces all of the variables, class names, and function names in a script to shorter, unreadable symbols.

Lighthouse
ORG

’s

Minify JavaScript
PRODUCT

audit checks for unminified

JavaScript
PRODUCT

.

Explore the results View data

View query

View image Show description of

Figure 2.25 Histogram
ORG

showing the percent of pages that have various ranges of scores on

Lighthouse
ORG

’s unminified

JavaScript
PRODUCT

audit.

68%
PERCENT

of mobile pages have the best scores in the

0.9
CARDINAL

to

1.0
CARDINAL

range,

4%
PERCENT


between 0.75
CARDINAL

and 0.9,

8%
PERCENT

between 0.5 and

0.75
CARDINAL

,

11%
PERCENT


between 0.25
CARDINAL

and

0.50
CARDINAL

,

2%
PERCENT

between 0.1 and

0.25
CARDINAL

, and

7%
PERCENT

in the worst range of

0.1 or less
CARDINAL

. Desktop pages tend to skew higher in the better ranges, with

79%
PERCENT

of pages above

0.9
CARDINAL

. Figure

2.25
CARDINAL

. Distribution of unminified

JavaScript
PRODUCT

audit scores.

Here,

0.00
CARDINAL

represents the worst score whereas

1.00
CARDINAL

represents the best score.

68%
PERCENT

of mobile pages are scoring between

0.9
CARDINAL

and

1.0
CARDINAL

on

Lighthouse
ORG

’s minified

JavaScript
ORG

audit, whereas the figure for desktop pages is

79%
PERCENT

. This means that on mobile,

32%
PERCENT

of pages have opportunities to ship minified

JavaScript
PRODUCT

, whereas that figure for desktop pages is

21%
PERCENT

.

Explore the results View data

View query

View image Show description of Figure

2.26
CARDINAL

Bar chart showing the

10
CARDINAL

,

25
DATE

,

50
DATE

,

75
DATE

, and

90th
ORDINAL

percentiles of the kilobytes of potential savings with

JavaScript
ORG

minification, broken down by total savings and those only with

third
ORDINAL

-party scripts. The total savings at each percentile are

3
CARDINAL

,

5
DATE

,

12
DATE

,

34
DATE

, and

76
CARDINAL


KB
ORG

respectively. For

only third
CARDINAL

-party scripts, the savings are

0
CARDINAL

,

0
CARDINAL

,

0
CARDINAL

,

3
DATE

, and

19
CARDINAL

KB. Figure

2.26
CARDINAL

. Distribution of the potential savings by

minifying JavaScript
PERSON

.

At the median, we see that pages are shipping around 12 KB of

JavaScript
PRODUCT

that can be minified. By the time we get to the

75th
ORDINAL

and

90th
ORDINAL

percentiles, however, that number jumps quite a bit, from

34
CARDINAL

KB to

about 76
CARDINAL

KB.

Third
ORDINAL

-parties are pretty good throughout, up until we get to the

90th
ORDINAL

percentile, however, where they’re shipping around

19
CARDINAL

KB of unminified

JavaScript
PRODUCT

.

Explore the results View data

View query

View image Show description of Figure

2.27
CARDINAL

Pie chart showing that on average

81.3%
PERCENT

of wasted JavaScript bytes come from

first
ORDINAL

-party scripts and

18.7%
PERCENT

come from

third
ORDINAL

-party scripts. Figure

2.27
CARDINAL

. Average wasted bytes of unminified

JavaScript
PRODUCT

.

Given the data we just presented, wasted bytes of unminified

JavaScript
PRODUCT

isn’t too surprising when you look at the average.

First
ORDINAL

parties are overwhelmingly the biggest culprits in shipping unminified

JavaScript
PRODUCT

at

just over 80%
PERCENT

. The remainder are

just under 20%
PERCENT

that could be doing a bit more to ship less bytes over the wire.

Minification addresses

one
CARDINAL

of the

first
ORDINAL

principles of web performance: ship less bytes. If you’re failing the

Lighthouse
ORG

audit for unminified

JavaScript
PRODUCT

, check your bundler’s configuration to ensure your

first
ORDINAL

party code is as streamlined for production as it can be. If you notice a

third
ORDINAL

-party script that’s unminified, it might be time to have a chat with that vendor to see what they can do to fix it. Refer to the Third Parties chapter for an even deeper look into the state of

third
ORDINAL

parties on the web.

Source maps are a tool that web developers use to map minified and uglified production code to their original sources. Source maps are used in production

JavaScript
PRODUCT

files, and are a useful debugging tool. Source maps can be specified in a comment pointing to a source map file at the end of a resource, or as the

SourceMap
ORG

HTTP response header.


14%
PERCENT

Explore the results View data

View query Figure

2.28
CARDINAL

. The percentage of mobile pages specifying source map comments to publicly accessible source maps.


14%
PERCENT

of

JavaScript
ORG

resources accessed through mobile devices deliver a source map comment to a source map that is publicly accessible, whereas

15%
PERCENT

of

JavaScript
ORG

resources accessed through desktop devices deliver them. However, the story is quite different for pages using a source map HTTP header.


0.12%
PERCENT

Explore the results View data

View query Figure

2.29
CARDINAL

. The number of mobile pages specifying source map headers.


Only 0.12%
PERCENT

of requests for

JavaScript
ORG

resources on mobile devices used a source map HTTP header, whereas the number for desktop devices is

0.07%
PERCENT

.

From a performance perspective, this doesn’t mean much. Source maps are a developer experience enhancement. What you should avoid, however, is the use of inline source maps, which insert a base64 representation of the original source into a production-ready

JavaScript
ORG

asset. Inlining source maps means that you’re not just sending your JavaScript resources to users, but also their source maps, which can lead to oversized JavaScript assets that take longer to download and process.

JavaScript affects more than just startup performance. When we rely on JavaScript to provide interactivity, those interactions are driven by event handlers that take time to execute. Depending on the complexity of interactions and the amount of scripts involved to drive them, users may experience poor input responsiveness.

Many metrics are used to assess responsiveness in both the lab and the field, and tools such as

Lighthouse
ORG

,

Chrome UX Report
ORG

(

CrUX
PRODUCT

), and

HTTP Archive
ORG

track these metrics to provide a data-driven view of the current state of responsiveness on

today
DATE

’s websites. Unless otherwise noted, all of the following graphs depict the

75th
ORDINAL

percentile—the threshold for which

Core Web Vitals
ORG

are determined to be passing—of that metric at the origin level.

The

first
ORDINAL

of these is First Input Delay (

FID
ORG

), which records the input delay of the very

first
ORDINAL

interaction made with a page. The input delay is the time between which the user has interacted with the page and when the event handlers for that interaction begin to run. It’s considered a load responsiveness metric that focuses on the

first
ORDINAL

impression a user gets when interacting with a website.

Explore the results View data

View query

View image Show description of Figure

2.30
CARDINAL

Bar chart showing the

10
CARDINAL

,

25
DATE

,

50
DATE

,

75 and
CARDINAL


90th
ORDINAL

percentiles of origin’s

75th
ORDINAL

percentile

FID
ORG

values. All values are

0 ms
QUANTITY

until the

90th
ORDINAL

percentile, where both desktop and phone are

25 ms
QUANTITY

. Figure

2.30
CARDINAL

. The distribution of websites’ 75th percentile

FID
ORG

values.

This chart shows the distribution of all websites’ 75th percentile

FID
ORG

values. The median website has a

FID
ORG

value of

0 ms
QUANTITY

for

at least 75%
PERCENT

of both desktop and phone user experiences. This “perfect

FID
ORG

” experience even extends into the

75th
ORDINAL

percentile of websites. Only when we get to the

90th
ORDINAL

percentile do we start to see imperfect

FID
ORG

values, but only 25 ms.

Given that the “good” FID threshold is

100 ms
QUANTITY

, we can say that

at least 90%
PERCENT

of websites meet this bar. In fact, we know from the analysis done in the Performance chapter that

100%
PERCENT

of websites actually have “good”

FID
ORG

experiences on desktop devices, and

92%
PERCENT

on mobile devices.

FID
ORG

is an unusually permissive metric.

Explore the results View data

View query

View image Show description of Figure

2.31
CARDINAL

Bar chart showing the

10
CARDINAL

,

25
DATE

,

50
DATE

,

75
DATE

, and

90th
ORDINAL

percentiles of origins’

75th
ORDINAL

percentile

INP
ORG

values. Phone experiences are

75
CARDINAL

,

100
CARDINAL

,

150
CARDINAL

,

250
CARDINAL

, and

400 milliseconds
QUANTITY

, respectively. For desktop experiences, the values are lower across the board at

50, 75
DATE

,

125
CARDINAL

,

225
CARDINAL

, and

350 milliseconds
QUANTITY

. Figure

2.31
CARDINAL

. The distribution of websites’

75th
ORDINAL

percentile

INP
ORG

values.

In order to get a comprehensive view of page responsiveness across the entire page lifecycle, though, we need to look at Interaction to Next Paint (INP), which assesses all keyboard, mouse, and touch interactions made with a page and selects a high percentile of interaction latency that’s intended to represent overall page responsiveness.

Consider that a “good” INP score is

200 milliseconds
TIME

or less. At the median, both mobile and desktop score below this threshold, but the

75th
ORDINAL

percentile is another story, with both mobile and desktop segments well within the “needs improvement” range. This data, quite unlike

FID
ORG

, suggests that there are many opportunities for websites to do everything they can to run fewer long tasks on pages, which are a key contributor to less-than-good

INP
ORG

scores.

Explore the results View data

View query

View image Show description of Figure

2.32
CARDINAL

Bar chart showing the

10
CARDINAL

,

25
DATE

,

50
DATE

,

75
DATE

, and

90th
ORDINAL

percentiles of pages’ synthetic

TBT
PRODUCT

values. Mobile pages have

154
CARDINAL

,

606
CARDINAL

,

1,686
CARDINAL

,

3,596
CARDINAL

, and

6,385 milliseconds
QUANTITY

of

TBT
ORG

, respectively. For desktop pages, the values are

0
CARDINAL

,

1
DATE

,

72
DATE

,

257
CARDINAL

, and

601 milliseconds
QUANTITY

. Figure

2.32
CARDINAL

. The distribution of pages’ lab-based

TBT
ORG

values.


Dovetailing
GPE

into long tasks, there’s

the Total Blocking Time
ORG

(TBT) metric, which calculates the total blocking time of long tasks during startup.

Note that unlike the preceding stats on

FID
ORG

and

INP
ORG

,

TBT
ORG

and

TTI
ORG

(below) are not sourced from real-user data. Instead, we’re measuring synthetic performance in simulated desktop and mobile environments with device-appropriate

CPU
ORG

and network throttling enabled. As a result of this approach, we get exactly

one
CARDINAL

TBT and

TTI
ORG

value for each page, rather than a distribution of real-user values across the entire website.

Considering that

INP
ORG

correlates very well with

TBT
ORG

, it’s reasonable to assume that high TBT scores may produce poorer

INP
ORG

scores. Using our synthetic approach, we see a wide gulf between desktop and mobile segments, indicating that desktop devices with better processing power and memory are outperforming less capable mobile devices by a wide margin. At the

75th
ORDINAL

percentile, a page has

nearly 3.6 seconds
TIME

of blocking time, which qualifies as a poor experience.

Explore the results View data

View query

View image Show description of Figure

2.33
CARDINAL

Bar chart showing the

10
CARDINAL

,

25
DATE

,

50
DATE

,

75
DATE

, and

90th
ORDINAL

percentiles of pages’ synthetic

TTI
ORG

. On mobile pages, the distribution of

TTI
ORG

is

5
DATE

,

9
DATE

,

16
DATE

,

27
DATE

, and

41 seconds
TIME

, respectively. For desktop pages, the values are

3
CARDINAL

,

5
DATE

,

10
DATE

,

20
DATE

, and

32 seconds
TIME

. Figure

2.33
CARDINAL

. The distribution of the

TTI
ORG

scores by origin and percentile.

Finally, we come to

Time to Interactive
ORG

(

TTI
ORG

), which is considered “good” if the metric comes in at

under 5 seconds
TIME

. Given that only the

10th
ORDINAL

percentile barely slips in under the

5 second mark
QUANTITY

, most websites in our simulated environment are relying on

JavaScript
ORG

to such an extent that pages are unable to become interactive within a reasonable timeframe—especially the

90th
ORDINAL

percentile, which takes a staggering

41.2 seconds
TIME

to become interactive.

As you may have gleaned from the previous section, the principal cause of poor interaction responsiveness is long tasks. To clarify, a long task is any task that runs on the main thread for

longer than 50 milliseconds
TIME

. The length of the task beyond

50 milliseconds
TIME

is that task’s blocking time, which can be calculated by subtracting

50 milliseconds
TIME

from the task’s total time.

Long tasks are a problem because they block the main thread from doing any other work until that task is finished. When a page has lots of long tasks, the browser can feel like it’s sluggish to respond to user input. In extreme cases, it can even feel like the browser isn’t responding at all.

Explore the results View data

View query

View image Show description of Figure

2.34
CARDINAL

Bar chart showing the

10
CARDINAL

,

25
DATE

,

50
DATE

,

75
DATE

, and

90th
ORDINAL

percentiles of the number of long tasks per page. For mobile pages, there are

5
CARDINAL

,

10
DATE

,

19
DATE

,

32
DATE

, and

48
CARDINAL

long tasks per page, respectively. There are many fewer long tasks on desktop pages, which have

only 2
CARDINAL

,

3
DATE

,

7
DATE

,

12
DATE

, and

19
CARDINAL

long tasks per page. Figure

2.34
CARDINAL

. The distribution of the number of long tasks per page.

The median page encounters

19
CARDINAL

long tasks on mobile and

7
CARDINAL

long tasks on desktop devices. This makes sense when you consider that most desktop devices have greater processing power and memory resources than mobile devices, and are actively cooled.

However, the picture gets much worse at higher percentiles. Long tasks at the

75th
ORDINAL

percentile per page are

32
CARDINAL

and

12
CARDINAL

on mobile and desktop, respectively.

Explore the results View data

View query

View image Show description of Figure

2.35
CARDINAL

Bar chart showing the

10
CARDINAL

,

25
DATE

,

50
DATE

,

75
DATE

, and

90th
ORDINAL

percentile of the total long task time per page. Mobile pages have

781
CARDINAL

,

1,744
CARDINAL

,

3,590
DATE

,

6,570
CARDINAL

, and

10,856 milliseconds
QUANTITY

of long tasks per page, respectively. The values for desktop are much lower, at

160
CARDINAL

,

349
CARDINAL

,

738
CARDINAL

,

1,419
CARDINAL

, and

2,501 milliseconds
QUANTITY

. Figure

2.35
CARDINAL

. Distribution of long tasks time per page.

It’s not enough to know how many long tasks there are per page—we need to understand the total time those tasks are taking on pages. The median mobile page has

3.59 seconds
TIME

of time dedicated to long tasks, whereas desktop pages have far less at

0.74 seconds
TIME

.

The

75th
ORDINAL

percentile suggests a much worse picture for those on mobile devices, coming in at

nearly 6.6 seconds
TIME

of processing time per page dedicated to handling long tasks. This is a lot of time the browser is spending on intense work that could be optimized or even possibly be moved to web workers on a different thread. In any case, these results spell trouble for the mobile web and responsiveness.

Scheduling JavaScript tasks has historically been deferred to the browser. There are newer methods such as requestIdleCallback and

queueMicrotask
LOC

, but these APIs schedule tasks in a coarse way, and—especially in the case of

queueMicrotask
LOC

—can cause performance issues if misused.

The Scheduler API has recently been released, and gives developers finer control over scheduling tasks based on priority—though it is currently only limited to

Chromium
ORG

-based browsers.


0.002%
PERCENT

Explore the results View data

View query Figure

2.36
CARDINAL

. The percentage of mobile pages using the Scheduler API.


Only 20 per million
CARDINAL

(

0.002%
PERCENT

) mobile pages are currently shipping JavaScript that uses the Scheduler API, whereas

30 per million
CARDINAL

(

0.003%
PERCENT

) desktop pages do. This is not surprising, considering the lack of documentation on this very new feature, and its limited support. However, we expect this number to increase as documentation on the feature becomes available, and especially if it is used in frameworks. We believe that the adoption of this important new feature will eventually result in better user experience outcomes.

AJAX—or usage of the XMLHttpRequest (XHR) method to asynchronously retrieve data and update information on the page without a navigation request—was a very popular method of creating dynamic user experiences. It has largely been replaced by the asynchronous fetch method, but

XHR
ORG

is still supported in all major browsers.


XHR
ORG

has a flag that allows you to make synchronous requests. Synchronous XHR is harmful for performance because the event loop and main thread is blocked until the request is finished, resulting in the page hanging until the data becomes available. fetch is a much more effective and efficient alternative with a simpler API, and has no support for synchronous fetching of data.


2.5%
PERCENT

Explore the results View data

View query Figure

2.37
CARDINAL

. The percentage of mobile pages using synchronous XHR.

While synchronous

XHR
ORG

is only used on

2.5%
PERCENT

of mobile pages and

2.8%
PERCENT

of desktop pages, its continued use—no matter how small—is still a signal that some legacy applications may be relying on this outdated method that harms the user experience.

Avoid using synchronous

XHR
ORG

, and

XHR
ORG

in general. fetch is a much more ergonomic alternative that lacks synchronous functionality by design. Your pages will perform better without synchronous

XHR
ORG

, and we hope someday to see this number fall to

zero
CARDINAL

.

Before the introduction of

DOM
ORG

insertion methods ( appendChild and others, for example), document.write was used to insert content at the position the document.write was made in the document.

document.write is very problematic. For

one
CARDINAL

, it blocks the HTML parser, and is problematic for a number of other reasons the HTML spec itself warns against its use. On slow connections, blocking document parsing to append nodes in this way creates performance problems that are entirely avoidable.


18%
PERCENT

Explore the results View data

View query Figure

2.38
CARDINAL

. The number of mobile pages using document.write .

A staggering

18%
PERCENT

of pages observed are still using document.write to add content to the

DOM
ORG

in lieu of proper insertion methods, whereas

17%
PERCENT

of desktop pages are still doing so. The explanation for this could be legacy applications that haven’t been rewritten to use the preferred

DOM
ORG

methods to insert new nodes into the document, and even some

third
ORDINAL

-party scripts that still use it.

We hope to see a decline in this trend. All major browsers explicitly warn against using this method. While it isn’t deprecated just yet, its existence in browsers in

the years
DATE

to come isn’t guaranteed. If document.write calls are in your website, you should prioritize removing them as soon as possible.

JavaScript has evolved considerably over

the last several years
DATE

. The introduction of new language features has turned

JavaScript
PRODUCT

into a more capable and elegant language that helps developers to write more concise JavaScript, resulting in less JavaScript loaded—provided those features haven’t been unnecessarily transformed into a legacy syntax by using a transpiler such as

Babel
ORG

.


Lighthouse
ORG

currently checks for

Babel
PERSON

transforms that may be unnecessary on the modern web, such as transforming use of async and await , JavaScript classes, and other newer, yet widely supported language features.


67%
PERCENT

Explore the results View data

View query Figure

2.39
CARDINAL

. The percentage of mobile pages that ship legacy JavaScript.


Just over two thirds
CARDINAL

of mobile pages are shipping JavaScript resources that are being transformed, or otherwise contain unnecessary legacy JavaScript.


Transformations
PERSON

can add a lot of extra bytes to production JavaScript for the sake of compatibility, but unless there is a necessity to support older browsers, many of these transforms are unnecessary, and can harm startup performance. That so many pages on mobile—and

68%
PERCENT

of pages on desktop—are shipping these transforms is concerning.


Babel
PERSON

is doing much to solve this problem out of the box, such as through the compiler assumptions feature, but

Babel
PERSON

is still driven by user-defined configurations, and can only do so much in the presence of outdated configuration files.

As mentioned above, we strongly encourage developers to carefully review their

Babel
PRODUCT

and

Browserslist
ORG

configurations to ensure that the minimum amount of transforms are applied to code in order for them to work in required browsers. Doing so can result in large reduction of bytes shipped to end users. Developers have a lot of work to do in this area, and we hope to see this figure decline over time now that the language’s evolution has relatively stabilized.

There’s

more than one
CARDINAL

way to build a web page. While some may opt to use the web platform directly, it’s undeniable that the trend in the web developer industry is to reach for abstractions that make our work easier to do and reason about. As is the case with

previous years
DATE

, we’ll be exploring the role of libraries and frameworks, as well as how frequently those libraries and frameworks present security vulnerabilities that can make the web a riskier place for users.

Libraries and frameworks are a huge part of the developer experience—one that has the potential to harm performance through framework overhead. Though developers have largely accepted this trade-off, understanding what libraries and frameworks are commonly used on the web is extremely important, as it informs our understanding of how the web is built. In this section, we’ll be taking a look at the state of libraries and frameworks across the web in

2022
DATE

.

To understand the usage of libraries and frameworks,

HTTP Archive
ORG

uses

Wappalyzer
PERSON

to detect the technologies used on a page.

Explore the results View data

View query

View image Show description of Figure

2.40
CARDINAL

Bar chart showing the percent of pages that use the top

JavaScript
ORG

libraries and frameworks. Starting with the most popular, jQuery is used by

81%
PERCENT

of mobile pages, followed by core-js on

41%
PERCENT

,

jQuery Migrate
PERSON

on

34%
PERCENT

,

jQuery UI
PERSON

on

23%
PERCENT

,

Modernizr
NORP

on

13%
PERCENT

,

Lodash
ORG

,

LazySizes
ORG

, and OWL Carousel on

9%
PERCENT

, React,

FancyBox
ORG

, Slick, and GSAP on

8%
PERCENT

,

Isotope
ORG

on

7%
PERCENT

, and Underscore.js and Lightbox on

6%
PERCENT

. Desktop adoption is very similar. Figure

2.40
CARDINAL

. Adoption of top libraries and frameworks.

It’s still no surprise that jQuery is by far the most used library on the web

today
DATE

. Part of that is because

WordPress
ORG

is used on

35%
PERCENT

of sites, but even so, the majority of jQuery usage occurs outside of the

WordPress
ORG

platform.

While jQuery is relatively small and reasonably quick at what it does, it still represents a certain amount of overhead in applications. Most of what jQuery offers is now doable with native

DOM
ORG

APIs, and may be unnecessary in

today
DATE

’s web applications.

The usage of core-js is also not surprising, as many web applications transform their code with

Babel
ORG

, which often uses core-js to fill in missing gaps in APIs across browsers. As browsers mature, this figure should drop—and that would be a good thing indeed, as modern browsers are more capable than ever, and shipping core-js code could end up being wasted bytes.

React usage notably remained the same from

last year
DATE

at

8%
PERCENT

, which may be a signal that adoption of the library has plateaued due to an increasing amount of choices in the

JavaScript
ORG

ecosystem.

It’s not an uncommon scenario to see multiple frameworks and libraries used on the same page. As with

last year
DATE

, we’ll examine this phenomenon to gain insight into how many libraries and frameworks have been used together in

2022
DATE

.


Libraries Desktop Mobile
ORG

jQuery

10.19%
PERCENT


10.33%
PERCENT

jQuery, jQuery Migrate

4.30%
PERCENT


4.94%
PERCENT

core-js,

jQuery
CARDINAL

, jQuery Migrate

2.48%
PERCENT


2.80%
PERCENT

core-js, jQuery

2.78%
PERCENT


2.74%
PERCENT

jQuery,

jQuery
ORG


UI
ORG


2.40%
PERCENT


2.07%
PERCENT

core-js,

jQuery
CARDINAL

,

jQuery Migrate
PERSON

, jQuery

UI
ORG


1.18%
PERCENT


1.36%
PERCENT

jQuery,

jQuery Migrate
PERSON

,

jQuery
ORG


UI
ORG


0.88%
PERCENT


0.99%
PERCENT

GSAP,

Lodash
PERSON

,

Polyfill
PERSON

, React

0.48%
PERCENT


0.93%
PERCENT

Modernizr, jQuery

0.87%
PERCENT


0.86%
PERCENT

core-js

0.92%
PERCENT


0.85%
PERCENT

Explore the results View data

View query Figure

2.41
CARDINAL

. Analysis of libraries and frameworks used together on observed pages.

It’s clear though that jQuery has some serious staying power, with some combination of it, its

UI
ORG

framework, and its migration plugin occurring in the top

seven
CARDINAL

spots, with core-js having a prominent role in library usage as well.

Given the wide proliferation of

JavaScript
ORG

on

today
DATE

’s web, and with the advent of installable

JavaScript
PRODUCT

packages, it’s no surprise that security vulnerabilities exist in the

JavaScript
ORG

ecosystem.


57%
PERCENT

Explore the results View data

View query Figure

2.42
CARDINAL

. The percentage of mobile pages that download a vulnerable

JavaScript
ORG

library or framework.

While

57%
PERCENT

of mobile pages serving up a vulnerable

JavaScript
ORG

library or framework is significant, this figure is down from

last year
DATE

’s figure of

64%
PERCENT

. This is encouraging, but there’s quite a bit of work to be done to lower this figure. We hope that as more security vulnerabilities are patched, developers will be incentivized to update their dependencies to avoid exposing their users to harm.

Library or framework

Desktop Mobile
ORG

jQuery

49.12%
PERCENT


48.80%
PERCENT

jQuery

UI
ORG


16.01%
PERCENT


14.88%
PERCENT


Bootstrap
ORG


11.53%
PERCENT


11.19% Moment.js
PERCENT


4.54%
PERCENT


3.91%
PERCENT

Underscore

3.41%
PERCENT


3.11%
PERCENT


Lo-Dash
PERSON


2.52%
PERCENT


2.44%
PERCENT

GreenSock JS

1.65%
PERCENT


1.62%
PERCENT

Handlebars

1.27%
PERCENT


1.12%
PERCENT

AngularJS

0.99%
PERCENT


0.79%
PERCENT

Mustache

0.44%
PERCENT


0.57%
PERCENT

Explore the results View data

View query Figure

2.43
CARDINAL

. The percentage of pages having known JavaScript vulnerabilities among the top

ten
CARDINAL

most commonly used libraries and frameworks.

With jQuery being the most popular library in use on the web

today
DATE

, it’s no surprise that it and its associated

UI
ORG

framework represents a fair amount of the security vulnerabilities that users are exposed to on the web

today
DATE

. This could likely be that some developers are still using older versions of these scripts which don’t take advantage of fixes to known vulnerabilities.

A notable entry is

Bootstrap
ORG

, which is a

UI
ORG

framework that helps developers to quickly prototype or build new layouts without using CSS directly. Given the release of newer CSS layout modes such as Grid or

Flexbox
ORG

, we may see usage of

Bootstrap
ORG

decrease over time, or in lieu of that, see developers update their

Bootstrap
ORG

dependencies to ship more safe and secure websites.

Regardless of what libraries and frameworks you use, be sure to regularly update your dependencies wherever possible to avoid exposing your users to harm. While package updates do result in some amount of refactoring or code fixes from time to time, the effort is worth the reduction in liability and increase in user safety.

For some time, web development has been driven by a componentization model employed by numerous frameworks. The web platform has similarly evolved to provide encapsulation of logic and styling through web components and the shadow

DOM
ORG

. To kick off this

year
DATE

’s analysis, we’ll begin with custom elements.


2.0%
PERCENT

Explore the results View data

View query Figure

2.44
CARDINAL

. The percentage of desktop pages that used custom elements.

This figure is down a bit from

last year
DATE

’s analysis of custom element usage on desktop pages, which was

3%
PERCENT

. With the advantages that custom elements provide and their reasonably broad support in modern browsers, we’re hoping that the web component model will compel developers to leverage web platform built-ins to create faster user experiences.


0.39%
PERCENT

Explore the results View data

View query Figure

2.45
CARDINAL

. The percentage of mobile pages that used shadow

DOM
ORG

.


Shadow
PRODUCT

DOM allows you to create dedicated nodes in a document that contain their own scope for sub-elements and styling, isolating a component from the main

DOM
ORG

tree. Compared to

last year
DATE

’s figure of

0.37%
PERCENT

of all pages using shadow

DOM
ORG

, adoption of the feature has remained much the same, with

0.39%
PERCENT

of mobile pages and

0.47%
PERCENT

of desktop pages using it.


0.05%
PERCENT

Explore the results View data

View query Figure

2.46
CARDINAL

. The percentage of mobile pages that use templates.

The template element helps developers reuse markup patterns. Their contents render only when referenced by

JavaScript
ORG

. Templates work well with web components, as the content that is not yet referenced by

JavaScript
ORG

is then appended to a shadow root using the shadow

DOM
ORG

.


Roughly 0.05%
PERCENT

of web pages on both desktop and mobile are currently using the template element. Though templates are well supported in browsers, their adoption is currently scant.


0.08%
PERCENT

Explore the results View data

View query Figure

2.47
CARDINAL

. The percentage of mobile pages that used the is attribute.

The HTML is attribute is an alternate way of inserting custom elements into the page. Rather than using the custom element’s name as the HTML tag, the name is passed to any standard HTML element, which implements the web component logic. The is attribute is a way to use web components that can still fall back to standard HTML element behavior if web components fail to be registered on the page.

This is

the first year
DATE

we are tracking usage of this attribute, and unsurprisingly, its adoption is lower than custom elements themselves. Due to the lack of support in

Safari
ORG

, this means that browsers on iOS and

Safari
ORG

on macOS can’t make use of the attribute, possibly contributing to the attribute’s limited usage.

The state of

JavaScript
ORG

is largely continuing the way trends would have suggested

last year
DATE

. We’re shipping more of it, for sure, but we’re also trying to mitigate the ill effects of excessive JavaScript through increased usage of techniques such as minification, resource hints, compression, and even down to the libraries we use.

The state of

JavaScript
ORG

is a constantly evolving phenomenon. It’s clear that we have an increased reliance on it more than ever, but that spells trouble for the collective user experience of the web. We need to do all we can—and more—to stem the tide of how much JavaScript we ship on production websites.

As the web platform matures, we’re hoping that we see increased direct adoption of its various APIs and features where it makes sense to do so. For those experiences that require frameworks for a better developer experience, we’re hoping to see additional optimizations and opportunities for framework authors to adopt new APIs to help them deliver on both a better developer experience and better experiences for users.

Let’s hope that

next year
DATE

signals a shift in the trend. In the meantime, let’s continue to do all we can to make the web as fast as we possibly can, while keeping an eye on both lab and field data along the way.