惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
SegmentFault 最新的问题
MongoDB | Blog
MongoDB | Blog
J
Java Code Geeks
Stack Overflow Blog
Stack Overflow Blog
The GitHub Blog
The GitHub Blog
博客园 - Franky
博客园 - 叶小钗
大猫的无限游戏
大猫的无限游戏
V
Visual Studio Blog
IT之家
IT之家
美团技术团队
博客园 - 司徒正美
Martin Fowler
Martin Fowler
Last Week in AI
Last Week in AI
酷 壳 – CoolShell
酷 壳 – CoolShell
Vercel News
Vercel News
雷峰网
雷峰网
B
Blog
WordPress大学
WordPress大学
aimingoo的专栏
aimingoo的专栏
D
Docker
P
Proofpoint News Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
爱范儿
爱范儿

Simply Explained

Converting a Tuya Thermostat to ESPHome Bringing Foam Monsters to Life: How I Wrote and Illustrated a Children's Book Using AI How I Built an NFC Movie Library for my Kids Analyzing Link Rot in My Newsletter (After 31 Editions) How I Use Alfred to Search My Obsidian Notes Faster (with Spotlight!) Year in review: 2022 Smart lights behind a wall switch (Shelly, Z-Wave, ESPHome) Serverless Anagram Solver with Cloudflare R2 and Pages Integrate Home Assistant with Apple Reminders How WebP Images Reduced My Bandwidth Usage by 50% Tracking gas usage with ESPHome, Home Assistant, and TCRT5000 My Sixth Year as YouTube Creator (statistics + retrospective) EZStore: a tiny serverless datastore for IoT data (DynamoDB + Lambda) ESP-IDF: Storing AWS IoT certificates in the NVS partition (for OTA) How to securely access your home network with Cloudflare Tunnel and WARP I Built a CO2 Sensor and It Terrifies Me Filtering spam on YouTube with TensorFlow & AI Building a killer NAS with an old Rackable Server How I Structure My ESPHome Config Files Howto Virtualize Unraid on a Proxmox host MAX17043: Battery Monitoring Done Right (Arduino & ESP32) Migrating This Blog From Jekyll to Eleventy Good Home Automation Should be Boring ESP32 Cam: cropping images on device Retrospective: My Fifth Year on YouTube Secure Home Assistant Access with Cloudflare and Ubiquiti Dream Machine Shelly 2.5 + ESPHome: potential fire hazard + fix Impact of Adblockers on Google Analytics (vs. Plausible) Shelly 2.5: Flash ESPHome Over The Air! Tuya IR Hub: control Daikin AC (Home Assistant + ESPHome)
Preventing Cumulative Layout Shifts with lazy loaded imag...
Xavier Decuy · 2021-04-26 · via Simply Explained

There's nothing more annoying than a website shifting down just as you're about to click on a button or link. This is called a layout shift, and Google has declared war on them. They've added layout shifts to the Core Web Vitals, and if your website has a lot of them, it will get penalized in the search results.

Here's how to prevent (lazy loaded) images from triggering layout shifts.

What's a layout shift?

Just to make it clear, here's what a layout shift looks like: Layout shift demonstrated with "Sagan Ipsum"

Browsers try to render web pages as soon as possible, and sometimes they start displaying content before all images have been downloaded. Then, as soon as the image does finish loading, the browser needs to make room for it and shifts the entire content down.

The problem is not a slow-loading image. It's that the browser doesn't know how much space it has to reserve for that image. So it reserves no space at all, which results in a layout shift when it finally finished downloading.

Modern web development

This is partly to blame on modern and responsive web development. For websites to work on various screen sizes, we stopped giving our images a width and height attribute. Instead, we use CSS like this:

img {
   max-width: 100%;
}

This tells the browser that no image can be wider than its container. Preventing horizontal scrolling and results in a better mobile experience.

But that doesn't tell the browser anything about the image dimensions. The height of the image is unknown, so the browser cannot reserve vertical space for it. Also, the image width is uncertain as well. An image can be smaller, bigger, or equal to the container's width.

Fixing this is easy: add a width and height attribute to your images. Like in the good old days!

<img src="/my-image.jpg" width="800" height="600">

Now that the browser knows the image's dimensions, it can reserve the correct amount of space before the image is even loaded.

Fitting an image of 800x600 into a container that's 700px wide is not possible. It has to be scaled. And now, the browser can calculate the height of the scaled image before it has been downloaded.

Calculate it with the rule of three! (Or use the image aspect ratio)

Boom! The browser knows it should reserve 525 pixels to accommodate the image. The page is rendered out, so you can start reading or interacting with it. When the images finish downloading, they are put in the correct placeholders without shifting the layout.

This excellent post from Barry Pollard gives a more in-depth explanation about the width and height attributes and how modern browsers use them.

How to implement it in Eleventy

Manually adding width and height attributes to all your images is not a fun task. Here's how I automate it with Eleventy (static site generator).

I use the markdown-it-image-lazy-load plugin to make sure that all images in my posts are lazy loaded by adding the loading attribute:

<img src="/logo.png" loading="lazy">

Because lazy loading causes layout shifts, I decided to contribute to the plugin and add an image_size option that automatically fetches and inserts the dimensions of an image.

You enable it like this:

const markdownLib = markdownIt(markdownOptions)
        // Lazy load all images by default (browser support needed)
        .use(require('markdown-it-image-lazy-load'), {
            image_size: true,
            base_path: __dirname + 'src/',
        });

eleventyConfig.setLibrary("md", markdownLib);

Make sure to set the base_path correctly. In my case, the source code of my site is stored in the src/ directory.

Re-generate your website, and now all images should have a loading attribute and an explicit width and height.

It uses image-size behind the scenes to extract dimensions from the first few bytes of the image. In my case, it barely has any impact on build performance.

Effect of Lazy Loading

Implementing lazy loading can save you some bandwidth. In my case, I saw a reduction of about 30%.

This site went from consuming 700-800MB per day to 500-700MB per day. Not bad!

Conclusion

Let's give the width and height attributes some love. They help the browser, they provide a better user experience, and they'll give you a better position on Google ;)