Skip to content

HTML5 feature: lazy loading images #6197

@gwern

Description

@gwern

There is a newly-standardized HTML5 feature, image lazy loading, which allows images in a web page to be loaded only shortly before they would come on screen, potentially greatly reducing bandwidth consumption and page loading speed (and which replaces the many nasty JS hacks used before*). One simply adds an attribute loading="lazy" to tags such as <img> tags.

I think Pandoc should generate HTML5 which does lazy loading by default. There are few downsides, and a huge upside, and users should receive the benefit of it automatically**. It is

  1. fully backwards-compatible; it does not break any existing browsers or degrade any functionality in browsers that do not recognize it

  2. fully standardized & accepted (discussion)

  3. already widely available: Chrome shipped it by default in Chrome 76 ~August 2019, and Firefox 75 ~February 2020 (current global availability: >63%)

  4. saves a potentially enormous amount of bandwidth, particularly for mobile users, who pay the most for bandwidth while benefiting the most from lazy-loading due to small screens

    For example, on one gwern.net page it saves something like 20MB. It also results in a much more pleasant browsing experience in my experience. I've become much more willing to include images in my pages now that I know lazy loading works.

  5. reliable and bug-free

    I am not aware of any use-cases that lazy loading breaks other than printing in Chrome (see below).

    I've had it enabled on all gwern.net pages/images since 19 Sep 2019 (see staticImg in hakyll.hs), hundreds of thousands of page loads ago, and no problems have been reported to me, nor have I noticed any in my own browsing, aside from sometimes (with a 4k fullscreened browser in portrait orientation) images flashing into view when I page down too fast for it. (But it's rare and at first I wasn't sure I had enabled lazy loading correctly until I set up the network monitor to check when the image requests were made.)

  6. easy to add: it's just adding an attribute to all generated figures, with no IO or any logic involved. Just add an attribute in src/Text/Pandoc/Writers/HTML.hs's image-handling.

    I think it might go something like this (I actually implemented my rewrite in Tagsoup as a post-processing step, because I didn't want to reinstall my entire Pandoc stack just to check this would work):

    img <- inlineToHtml opts (Image attr [Str ""] (s,tit))
    

    to

    img <- inlineToHtml opts (Image (attr++[("loading", "lazy")]) [Str ""] (s,tit))
    

The main drawback I've found so far is that

  1. printing: in Chrome, printing may omit images which haven't been seen yet, which is an open bug.

    They acknowledge it's a bug, so I hope they'll fix it since Wikimedia is complaining about it, and printing partially-loaded pages in Chrome is a pretty narrow and specific edge case with an easy workaround for the user of just scrolling to the bottom before printing. (There aren't any mentions of a bug like this for Firefox or Edge; I guess no one ever tries to print image-heavy gwern.net pages from Chrome, because it hasn't come up.)

* nasty because most of them required breaking image loading entirely for people without JS enabled. And then didn't even work very well - I assume because they generally didn't use IntersectionObservers to properly start fetching the image well before the user scrolled it into visibility.
** It can be stripped out of the HTML, if necessary somehow, with as simple a rewrite as a call to sed.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions