diff --git a/src/static/css/2019.css b/src/static/css/2019.css index 2a5fb00d7ac..c2e9dab8aef 100644 --- a/src/static/css/2019.css +++ b/src/static/css/2019.css @@ -15,6 +15,7 @@ body { h1, h2, h3, h4, h5, h6, .subtitle { font-family: 'Poppins', sans-serif; + line-height: 1.2em; } b { @@ -216,7 +217,6 @@ header .btn + .language-switcher { .main a, .main a:visited { color: #0b1423; - word-break: break-all; } h2, h3, h4 { @@ -374,9 +374,9 @@ p.copyright { } } -.visually-hidden { +.visually-hidden { position: absolute !important; - height: 1px; + height: 1px; width: 1px; overflow: hidden; clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ diff --git a/src/static/css/methodology.css b/src/static/css/methodology.css index ee7f063e7a9..0e251e0631b 100644 --- a/src/static/css/methodology.css +++ b/src/static/css/methodology.css @@ -8,7 +8,7 @@ #methodology p, #methodology li { - font-size: 18px; + font-size: 17px; line-height: 30px; } .decorative-line { diff --git a/src/static/css/page.css b/src/static/css/page.css index 53b60328bc7..88018a75f7f 100644 --- a/src/static/css/page.css +++ b/src/static/css/page.css @@ -4,16 +4,22 @@ grid-template-areas: 'index content'; grid-template-columns: 300px auto; } -.table-wrap, +.table-wrap-container, .floating-card { border-radius: 16px; box-shadow: 0 0 16px 0 rgba(78, 85, 100, 0.2); } .table-wrap { - display: inline-block; - margin: 10px 0; + display: flex; + margin: 0 auto; + padding: 16px; max-width: 100%; + justify-content: center; +} +.table-wrap-container { overflow: auto; + display: inline-block; + margin: 0 -16px; } .code-block { @@ -107,7 +113,6 @@ margin-top: 0; padding-top: 0; min-width: 320px; - font-size: 18px; } .content > section { margin-bottom: 64px; @@ -173,7 +178,7 @@ } .authors .tagline{ - font-size: 18px; + font-size: 16px; } .authors .avatar{ @@ -271,14 +276,13 @@ figure iframe { margin: 0 auto; } figcaption { - margin-top: 20px; + margin-top: 8px; text-align: center; } table { margin: 0 auto; max-width: 100%; border-collapse: collapse; - display: block; } thead { font-family: 'Poppins', sans-serif; @@ -354,7 +358,9 @@ figure .big-number { max-height: 100%; transition: max-height 0.25s ease-in; } - + .table-wrap { + justify-content: left; + } table { font-size: .8em; } diff --git a/src/templates/en/2019/chapters/accessibility.html b/src/templates/en/2019/chapters/accessibility.html index e83d1584ff8..d241d8f9615 100644 --- a/src/templates/en/2019/chapters/accessibility.html +++ b/src/templates/en/2019/chapters/accessibility.html @@ -39,9 +39,9 @@ "headline": "{{ metadata.get('title') }}", "image": { "@type": "ImageObject", - "url": "https://almanac.httparchive.org/static/images/{{ year }}/{{ get_chapter_image_dir(metadata) }}/hero_sm.jpg", - "height": 163, - "width": 326 + "url": "https://almanac.httparchive.org/static/images/{{ year }}/{{ get_chapter_image_dir(metadata) }}/hero_lg.jpg", + "height": 433, + "width": 866 }, "publisher": { "@type": "Organization", @@ -265,7 +265,7 @@

Ease of reading

Color contrast

There are many cases in which website visitors may not be able to see a website perfectly. Visitors may be colorblind and unable to distinguish between the font and background color (1 in every 12 men and 1 in 200 women of European descent). Perhaps they’re simply reading while the sun is out and creating tons of glare on their screen—significantly impairing their vision. Or maybe they’ve just grown older, and their eyes can't distinguish colors as well as they used to.

To allow your users to be able to read your website under these conditions, be sure that your text has sufficient color contrast with its background.

-

Figure 1. Four colored boxes of orange and gray shades with white text overlayed inside creating two columns. The left column says Too lightly colored and has the orange background color written as #FCA469. The right column says Recommended and the orange background color is written as #F56905. The top box in each column has an orange background with white text #FFFFFF and the bottom box has a gray background with white text #FFFFFF. The grey background shows the orange color in grayscale. Courtesy of LookZook.

+

Figure 1. Four colored boxes of orange and gray shades with white text overlayed inside creating two columns. The left column says Too lightly colored and has the orange background color written as #FCA469. The right column says Recommended and the orange background color is written as #F56905. The top box in each column has an orange background with white text #FFFFFF and the bottom box has a gray background with white text #FFFFFF. The grey background shows the orange color in grayscale. Courtesy of LookZook.

Figure 1. Example of what text with insufficient color contrast looks like. Courtesy of LookZook

So how well did the sites we analyzed do? Only 22.04% of sites gave all of their text sufficient color contrast. Or in other words: 4 out of every 5 sites have text that easily blends into the background, making it unreadable.

@@ -365,7 +365,7 @@

Other HTML elements used for na

A skip link is a link placed at the top of a page which allows screen readers or keyboard-only users to jump straight to the main content. It effectively "skips" over all navigational links and menus at the top of the page. Skip links are especially useful to keyboard users who don't use a screen reader, as these users don’t usually have access to other modes of quick navigation (like landmarks and headings). 14.19% of the pages in our sample were found to have skip links.

If you’d like to see a skip link in action for yourself, you can! Just do a quick Google search and hit "tab" as soon as you land on the search result pages. You’ll be greeted with a previously hidden link just like the one in Figure 7.

-

Figure 7. Screenshot of Google search results page for search "http archive". The visible “Skip to main content” link is surrounded by a blue focus highlight and a yellow overlayed box with a red arrow pointing to the skip link reads “A skip link on google.com”.

+

Figure 7. Screenshot of Google search results page for search "http archive". The visible “Skip to main content” link is surrounded by a blue focus highlight and a yellow overlayed box with a red arrow pointing to the skip link reads “A skip link on google.com”.

Figure 7. What a skip link looks like on google.com

Note: It’s hard to accurately determine what a skip link is when analyzing sites. For this analysis, if we found an anchor link (href=#heading1) within the first 3 links on the page, we defined this as a page with a skip link. So, this 14.19% we reported is an upper bound and could be far worse. diff --git a/src/templates/en/2019/chapters/caching.html b/src/templates/en/2019/chapters/caching.html index 89cfa1e870d..468d4d56869 100644 --- a/src/templates/en/2019/chapters/caching.html +++ b/src/templates/en/2019/chapters/caching.html @@ -39,9 +39,9 @@ "headline": "{{ metadata.get('title') }}", "image": { "@type": "ImageObject", - "url": "https://almanac.httparchive.org/static/images/{{ year }}/{{ get_chapter_image_dir(metadata) }}/hero_sm.jpg", - "height": 163, - "width": 326 + "url": "https://almanac.httparchive.org/static/images/{{ year }}/{{ get_chapter_image_dir(metadata) }}/hero_lg.jpg", + "height": 433, + "width": 866 }, "publisher": { "@type": "Organization", @@ -222,10 +222,10 @@

Overview of HTTP Caching

< expires: Mon, 14 Oct 2019 07:36:57 GMT < etag: "1566748830.0-3052-3932359948"

The tool RedBot.org allows you to input a URL and see a detailed explanation of how the response would be cached based on these headers. For example, a test for the URL above would output the following:

-

+

If no caching headers are present in a response, then the client is permitted to heuristically cache the response. Most clients implement a variation of the RFC’s suggested heuristic - which is 10% of the time since last modified. However some may cache the response indefinitely. So it is important to set specific caching rules to ensure that you are in control of the cacheability.

According to the HTTP Archive, in July 2019 72% of responses were served with a Cache-Control header, and 56% of responses were served with an Expires header. However 27% of responses did not use either header, and are subject to heuristic caching! This was consistent across both desktop and mobile sites.

-

+

What Type of Content Are We Caching

A cacheable resource is stored by the client for a period of time and available for reuse on a subsequent request. Across all HTTP requests, 80% of responses are considered cacheable, meaning that a cache is permitted to store them. Out of these,

The remaining responses are not permitted to be stored in browser caches.

-

+

The table below details the cache TTL values for desktop requests by type. Most content types are being cached, however CSS resources appear to be consistently cached at high TTLs.

While most of the median TTLs are high, the lower percentiles highlight some of the missed caching opportunities. For example, the median TTL for images is 28 hours, however the 25th percentile is just 1-2 hours and the 10th percentile indicates that 10% of cacheable image content is cached for less than 1 hour.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Desktop Cache TTL Percentiles (Hours)
typep10p25p50p75p90
audio

12

24

720

8760

8760

css

720

8760

8760

8760

8760

font

< 1

3

336

8760

87600

html

< 1

168

720

8760

8766

image

< 1

1

28

48

8760

other

< 1

2

336

8760

8760

script

< 1

< 1

1

6

720

text

21

336

7902

8357

8740

video

< 1

4

24

24

336

xml

< 1

< 1

< 1

< 1

< 1

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Desktop Cache TTL Percentiles (Hours)
typep10p25p50p75p90
audio

12

24

720

8760

8760

css

720

8760

8760

8760

8760

font

< 1

3

336

8760

87600

html

< 1

168

720

8760

8766

image

< 1

1

28

48

8760

other

< 1

2

336

8760

8760

script

< 1

< 1

1

6

720

text

21

336

7902

8357

8740

video

< 1

4

24

24

336

xml

< 1

< 1

< 1

< 1

< 1

+

By exploring the cacheability by content type in more detail, we can see that approximately half of all HTML responses are considered non-cacheable. Additionally, 16% of images and scripts are non-cacheable.

-

+

The same data for mobile is shown below. The cacheability of content types is consistent between desktop and mobile.

-

+

Cache-Control vs Expires

In HTTP/1.0, the Expires header was used to indicate the date/time after which the response is considered stale. It’s value is an HTTP-date timestamp, such as:

Expires: Thu, 01 Dec 1994 16:00:00 GMT

@@ -350,71 +352,73 @@

Cache-Control vs Expires

  • Private indicates a response should only be cached by a browser, and not by an intermediary that would serve multiple clients.
  • 53% of HTTP responses include a Cache-Control header with the max-age directive, and 54% include the Expires header. However, 41% of these responses use both headers, which means that 13% of responses are caching solely based on the Expires header.

    -

    +

    Cache-Control Directives

    The HTTP/1.1 specification includes multiple directives that can be used in the Cache-Control response header and are detailed below. Note that multiple can be used in a single response.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    DirectiveDescription
    max-ageIndicates the number of seconds that a resource can be cached for
    publicAny cache may store the response.
    no-cacheA cached entry must be revalidated prior to it's use
    must-revalidateA stale cached entry must be revalidated prior to its use
    no-storeIndicates that a response is not cacheable
    privateThe response is intended for a specific user and should not be stored by shared caches.
    no-transformNo transformations or conversions should be made to this resource
    proxy-revalidateSame as must-revalidate, but applies to shared caches.
    s-maxageSame as max age, but applies to shared caches only
    immutableIndicates that the cached entry will never change, and that revalidation is not necessary.
    stale-while-revalidateIndicates that the client is willing to accept a stale response while asynchronously checking in the background for a fresh one.
    stale-if-errorIndicates that the client is willing to accept a stale response if the check for one fails.
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    DirectiveDescription
    max-ageIndicates the number of seconds that a resource can be cached for
    publicAny cache may store the response.
    no-cacheA cached entry must be revalidated prior to it's use
    must-revalidateA stale cached entry must be revalidated prior to its use
    no-storeIndicates that a response is not cacheable
    privateThe response is intended for a specific user and should not be stored by shared caches.
    no-transformNo transformations or conversions should be made to this resource
    proxy-revalidateSame as must-revalidate, but applies to shared caches.
    s-maxageSame as max age, but applies to shared caches only
    immutableIndicates that the cached entry will never change, and that revalidation is not necessary.
    stale-while-revalidateIndicates that the client is willing to accept a stale response while asynchronously checking in the background for a fresh one.
    stale-if-errorIndicates that the client is willing to accept a stale response if the check for one fails.
    +

    For example, the below header indicates that a cached entry should be stored for 43200 seconds and it can be stored by all caches.

    cache-control: public, max-age=43200

    The graph below illustrates the top 15 Cache-Control directives in use.

    -

    +

    There are a few interesting observations about the popularity of these cache directives:

    Placing these into our same chart as above for perspective looks something like this (again, it varies slightly based on the dataset)

    - +
    Figure 10. Other popular elements in the context of product-specific and native elements with under 5% adoption.

    The interesting thing about these results is that they also introduce a few other ways that our tool can come in very handy. If we're interested in exploring the space of the data, a very specific tag name is just one possible measure. It's definitely the strongest indicator if we can find good "slang" developing. However, what if that's not all we're interested in?

    diff --git a/src/templates/en/2019/chapters/media.html b/src/templates/en/2019/chapters/media.html index b69170a80d3..77ef6620295 100644 --- a/src/templates/en/2019/chapters/media.html +++ b/src/templates/en/2019/chapters/media.html @@ -39,9 +39,9 @@ "headline": "{{ metadata.get('title') }}", "image": { "@type": "ImageObject", - "url": "https://almanac.httparchive.org/static/images/{{ year }}/{{ get_chapter_image_dir(metadata) }}/hero_sm.jpg", - "height": 163, - "width": 326 + "url": "https://almanac.httparchive.org/static/images/{{ year }}/{{ get_chapter_image_dir(metadata) }}/hero_lg.jpg", + "height": 433, + "width": 866 }, "publisher": { "@type": "Organization", @@ -158,123 +158,127 @@

    Images

    It is rare to find a webpage that does not utilize images. Over the years, many different file formats have emerged to help present content on the web - each addressing a different problem. Predominantly there are 4 main universal image formats: JPEG, PNG, GIF, and SVG. In addition, Chrome has enhanced the media pipeline and added support for a fifth image format - WebP. Other browsers have likewise added support for JPEG2000 (Safari), JPEG-XL (IE and Edge) and HEIC (WebView only in Safari)

    Each format has its own merits and has ideal uses for the web. A very simplified summary would break down as:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FormatHighlightsDrawbacks
    JPEG* ubiquitously supported
    * ideal for photographic content
    * there is always quality loss
    * most decoders cannot handle high bit depth photographs from modern cameras (> 8 bits per channel)
    * no support for transparency
    PNG - * like JPEG and GIF, shares wide support
    - *it is lossless
    - * supports transparency, animation, and high bit depth -
    - * much bigger files compared to JPEG
    - * not ideal for photographic content -
    GIF* the predecessor to PNG, is most known for animations
    * lossless
    * because of the limitation of 256 colors, there is always visual loss from conversion
    *very large files for animations
    SVG - * A vector based format that can be resized without increasing filesize
    - * It is based on math rather than pixels and creates smooth lines -
    * not useful for photographic or other raster content
    WebP - * a newer file format that can produce lossless images like PNG and lossy images like JPEG
    - * It boasts a 30% average file reduction compared to JPEG, while other data suggests that median file reduction is between 10-28% based on pixel volume. -
    - * Unlike JPEG, it is limited to chroma-subsampling which will make some images appear blurry.
    - *not universally supported. Only Chrome, Firefox and Android ecosystems.
    - * fragmented feature support depending on browser versions -
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FormatHighlightsDrawbacks
    JPEG* ubiquitously supported
    * ideal for photographic content
    * there is always quality loss
    * most decoders cannot handle high bit depth photographs from modern cameras (> 8 bits per channel)
    * no support for transparency
    PNG + * like JPEG and GIF, shares wide support
    + *it is lossless
    + * supports transparency, animation, and high bit depth +
    + * much bigger files compared to JPEG
    + * not ideal for photographic content +
    GIF* the predecessor to PNG, is most known for animations
    * lossless
    * because of the limitation of 256 colors, there is always visual loss from conversion
    *very large files for animations
    SVG + * A vector based format that can be resized without increasing filesize
    + * It is based on math rather than pixels and creates smooth lines +
    * not useful for photographic or other raster content
    WebP + * a newer file format that can produce lossless images like PNG and lossy images like JPEG
    + * It boasts a 30% average file reduction compared to JPEG, while other data suggests that median file reduction is between 10-28% based on pixel volume. +
    + * Unlike JPEG, it is limited to chroma-subsampling which will make some images appear blurry.
    + *not universally supported. Only Chrome, Firefox and Android ecosystems.
    + * fragmented feature support depending on browser versions +
    +

    Image Formats

    In aggregate, across all page, we indeed see the prevalence of these formats. JPEG, one of the oldest formats on the web, is by far the most commonly used image formats at 60% of the image requests and 65% of all image bytes. Interestingly, PNG is the second most commonly used image format 28% of image requests and bytes. The ubiquity of support along with the precision of color and creative content are likely explanations for its wide use. In contrast SVG, GIF and WebP share nearly the same usage at 4%. (figure image formats by % of totla requests) Of course, web pages are not uniform in their use of image content. Some depend on images more than others. Look no further than the home page of Google.com and you will see very little imagery compared to a typical news website. Indeed, the median website has 13 images and 61 at the 90th percentile and a whopping 229 at the 99th percentile. (figure image frequency per page)

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Formatp10p25p50p75p90p99
    jpg0392039119
    png044101849
    webp0000028
    svg0000219
    gif0001214
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Formatp10p25p50p75p90p99
    jpg0392039119
    png044101849
    webp0000028
    svg0000219
    gif0001214
    +

    While the median page has 9 jpegs and 4 pngs, and only in the top 25% pages where use gifs, this doesn’t report the adoption rate. The use and frequency of each format per page doesn’t provide insight into the adoption of the more modern formats. Specifically, what % of pages include at least one image in each format?

    (figure % of pages using at least 1 image)

    @@ -282,117 +286,121 @@

    Image Formats

    Image File Sizes

    There are two ways to look at image file sizes: absolute bytes per resource and bytes per pixel. Looking at the absolute bytes per resource, and we can look at the frequency of file sizes. (figure image format file size)

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Formatp10p25p50p75p90
    jpg4 KB9 KB24 KB68 KB166 KB
    png2 KB4 KB11 KB43 KB152 KB
    webp4 KB7 KB17 KB41 KB90 KB
    gif2 KB3 KB6 KB17 KB87 KB
    svg0 KB0 KB1 KB2 KB8 KB
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Formatp10p25p50p75p90
    jpg4 KB9 KB24 KB68 KB166 KB
    png2 KB4 KB11 KB43 KB152 KB
    webp4 KB7 KB17 KB41 KB90 KB
    gif2 KB3 KB6 KB17 KB87 KB
    svg0 KB0 KB1 KB2 KB8 KB
    +

    From this we can start to get a sense of how large or small a typical resource is on the web. However, this doesn’t give us a sense of the volume of pixels represented on screen for these file distributions. To do this we can divide each resource bytes by the natural pixel volume of the image. A lower Bytes-Per-Pixel indicates a more efficient transmission of visual content. (figure Bytes per pixel)

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    imageTypeBytes Per Pixel: p10Bytes Per Pixel: p25Bytes Per Pixel: p50Bytes Per Pixel: p75Bytes Per Pixel: p90
    jpg0.11750.18480.29970.54560.9822
    png0.11970.28740.69181.45482.5026
    gif0.17020.36410.79672.5158.5151
    webp0.05860.10250.1830.32720.6474
    svg0.02930.1740.67661.92614.1075
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    imageTypeBytes Per Pixel: p10Bytes Per Pixel: p25Bytes Per Pixel: p50Bytes Per Pixel: p75Bytes Per Pixel: p90
    jpg0.11750.18480.29970.54560.9822
    png0.11970.28740.69181.45482.5026
    gif0.17020.36410.79672.5158.5151
    webp0.05860.10250.1830.32720.6474
    svg0.02930.1740.67661.92614.1075
    +

    While previously it appeared that GIF files were smaller than JPEG, we can now clearly see that the cause of the larger JPEG resources is due to the pixel volume. It is probably not a surprise that GIF shows a very low pixel density compared to the other formats. Additionally, PNG, while it can handle high bit depth and doesn’t suffer from chroma subsampling blurriness, is about twice the size of JPG or WebP for the same pixel volume.

    Of note, the pixel volume used for SVG is the size of the DOM element on screen (in CSS pixels). While considerably smaller for file sizes, this hints that SVGs are generally used in smaller portions of the layout. This is why the bytes per pixel appears worse than PNG.

    diff --git a/src/templates/en/2019/chapters/mobile-web.html b/src/templates/en/2019/chapters/mobile-web.html index b14ea51d3c8..2354f0febfe 100644 --- a/src/templates/en/2019/chapters/mobile-web.html +++ b/src/templates/en/2019/chapters/mobile-web.html @@ -39,9 +39,9 @@ "headline": "{{ metadata.get('title') }}", "image": { "@type": "ImageObject", - "url": "https://almanac.httparchive.org/static/images/{{ year }}/{{ get_chapter_image_dir(metadata) }}/hero_sm.jpg", - "height": 163, - "width": 326 + "url": "https://almanac.httparchive.org/static/images/{{ year }}/{{ get_chapter_image_dir(metadata) }}/hero_lg.jpg", + "height": 433, + "width": 866 }, "publisher": { "@type": "Organization", @@ -211,26 +211,28 @@

    The page loading experience

    Let's start with what phone the typical mobile user has. The average Android phone is ~$250, and one of the most popular phones in that range is a Samsung Galaxy S6. So this is likely the kind of phone they use, which is actually 4x slower than an iPhone 8. This user doesn't have access to a fast 4G connection, but rather a 2G connection (29% of the time) or 3G connection (28% of the time). And this is what it all adds up to:

    - - - - - - - - - - - - - - - - - - - -
    Connection type2G or 3G
    Latency300 - 400ms
    Bandwidth0.4 - 1.6Mbps
    PhoneGalaxy S64x slower than iPhone 8 (Octane V2 score)
    +
    + + + + + + + + + + + + + + + + + + + +
    Connection type2G or 3G
    Latency300 - 400ms
    Bandwidth0.4 - 1.6Mbps
    PhoneGalaxy S64x slower than iPhone 8 (Octane V2 score)
    +
    Figure 1. Technical profile of a typical mobile user.
    @@ -239,7 +241,7 @@

    Pages bloated with JavaScript

    The state of JavaScript on the mobile web is terrifying. According to HTTP Archive's JavaScript report, the median mobile site requires phones to download 375 KB of JavaScript. Assuming a 70% compression ratio, this means that phones have to parse, compile, and execute 1.25 MB of JavaScript at the median.

    Why is this a problem? Because sites loading this much JS take upwards of 10 seconds to become interactive. Or in other words, your page may appear fully loaded, but when a user clicks any of your buttons or menus, nothing happens because the JavaScript hasn't finished executing. Users are forced to keep clicking the button for upwards of 10 seconds, just waiting for that magical moment where something actually happens. Think about how confusing and frustrating that can be.

    - +
    Figure 2. Example of how painful of an experience waiting for JS to load can be.

    Let's delve deeper and look at another metric that focuses more on how well each page utilizes JavaScript. For example, does it really need as much JavaScript as it's loading? We call this metric the JavaScript Bloat Score, based on the web bloat score. The idea behind it is this:

    @@ -259,7 +261,7 @@

    Shifting content while loading

    One of the most beautiful parts of the web is how web pages load progressively by nature. Browsers download and display content as soon as they are able, so users can engage with your content as soon as possible. However, this can have a detrimental effect if you don't design your site with this in mind. Specifically, content can shift position as resources load and impede the user experience.

    - A video showing a website progressively load. The text is displayed quickly, but as images continue to load the text gets shifted further and further down the page each time—making it very frustrating to read. The calculated CLS of this example is 42.59%. Image courtesy of LookZook + A video showing a website progressively load. The text is displayed quickly, but as images continue to load the text gets shifted further and further down the page each time—making it very frustrating to read. The calculated CLS of this example is 42.59%. Image courtesy of LookZook
    Figure 3. Example of shifting content distracting a reader. CLS total of 42.59%. Image courtesy of LookZook
    @@ -295,7 +297,7 @@

    Color contrast

    To help us mitigate this problem, there are accessibility guidelines we can follow when choosing our text and background colors. So how are we doing in meeting these baselines? Only 22.04% of sites give all their text sufficient color contrast. This value is actually a lower limit, as we could only analyze text with solid backgrounds. Image and gradient backgrounds were unable to be analyzed.

    - Four colored boxes of orange and gray shades with white text overlayed inside creating two columns, one where the background color is too lightly colored compared to the white text and one where the background color is recommended compared to the white text. The hex code of each color is displayed, white is #FFFFFF, the light shade of orange background is #FCA469, and the recommended shade of orange background is #F56905. Image courtesy of LookZook + Four colored boxes of orange and gray shades with white text overlayed inside creating two columns, one where the background color is too lightly colored compared to the white text and one where the background color is recommended compared to the white text. The hex code of each color is displayed, white is #FFFFFF, the light shade of orange background is #FCA469, and the recommended shade of orange background is #F56905. Image courtesy of LookZook
    Figure 4. Example of what text with insufficient color contrast looks like. Courtesy of LookZook
    @@ -318,7 +320,7 @@

    Zooming and scaling

    - +
    Vertical grouped bar chart titled "Are zooming and scaling enabled?" measuring percentage data, ranging from 0 to 80 in increments of 20, vs. the device type, grouped into desktop and mobile. Desktop enabled: 75.46%; Desktop disabled 24.54%; Mobile enabled: 67.79%; Mobile disabled: 32.21%.
    Figure 5. Percent of desktop and mobile websites that enable or disable zooming/scaling.
    @@ -331,7 +333,7 @@

    Tap targets

    Designing tap targets appropriately to mitigate this issue can be difficult because of how widely fingers vary in size. However, lots of research has now been done and there are safe standards for how large buttons should be and how far apart they need to be separated.

    - A diagram displaying two examples of difficult to tap buttons. The first example shows two buttons with no spacing between them; An example below it shows the same buttons but with the recommended amount of spacing between them (8px or 1-2mm). The second example shows a button far too small to tap; An example below it shows the same button enlarged to the recommended size of 40-48px (around 8mm). Image courtesy of LookZook + A diagram displaying two examples of difficult to tap buttons. The first example shows two buttons with no spacing between them; An example below it shows the same buttons but with the recommended amount of spacing between them (8px or 1-2mm). The second example shows a button far too small to tap; An example below it shows the same button enlarged to the recommended size of 40-48px (around 8mm). Image courtesy of LookZook
    Figure 6. Standards for sizing and spacing tap targets. Image courtesy of LookZook
    @@ -349,26 +351,28 @@

    New input types

    When analyzing sites containing an email input, 56.42% use type="email". Similarly, for phone inputs, type="tel" is used 36.7% of the time. Other new input types have an even lower adoption rate.

    - - - - - - - - - - - - - - - - - - - -
    TypeFrequency (pages)
    phone1,917
    name1,348
    textbox833
    +
    + + + + + + + + + + + + + + + + + + + +
    TypeFrequency (pages)
    phone1,917
    name1,348
    textbox833
    +
    Figure 7. Most commonly used invalid input types
    @@ -392,7 +396,7 @@

    Conclusion

    How well are we doing catering to mobile users? According to our research, even though 71% of sites make some kind of effort to adjust their site for mobile, they're falling well below the mark. Pages take forever to load and become usable thanks to an abuse of JavaScript, text is often impossible to read, engaging with sites via clicking links or buttons is error-prone and infuriating, and tons of great technologies invented to mitigate these problems (Service Workers, autocomplete, zooming, new image formats, etc) are barely being used at all.

    The mobile web has now been around long enough for there to be an entire generation of kids where this is the only internet they've ever known. And what kind of experience are we giving them? We're essentially taking them back to the dial-up era. (Good thing I hear AOL still sells those CDs providing 1000 hours of free internet access!)

    - A 1000 hour free-trial CD for America Online + A 1000 hour free-trial CD for America Online
    1000 hours of America Online for free, from archive.org.