DEV Community

Cover image for Implementing a Practical Server-Side Solution for Cumulative Layout Shift
Ben Halpern
Ben Halpern

Posted on

Implementing a Practical Server-Side Solution for Cumulative Layout Shift

☝️☝️☝️ Pictured in the cover image is what happens when app visitors run into cumulative layout shift.

Cumulative layout shift is when the content of a webpage changes places when you least suspect it... Ahhh!


Sometimes it's an advertisement — ughhh! But the worst offender in general is images. Images load async so that the webpage can load and get the image when it's available... But when the image shows up, it can push the rest of the content out of the way unless we reserve space for it.

You reserve space for images by including height and width attributes. These are old school HTML attributes which are generally overridden by CSS, but they are still used by the browser to determine aspect ratios and ultimate reserve space for images.

Include accurate height and width attributes: Easy enough, right? Well not really: Who wants to sit around inputing that information, and generally who can be trusted to get it right. This seems like something the computer can do for us...

The computer can do this for us, but you have to be clever. In order to get image metadata, the image needs to be inspected. This could cause latency in the content saving process.

Long story, short: Forem now automatically detects image size by inspecting image data, and it does so asynchronously so height and width attributes are updated after initially saving the post.

DEV is an instance of Forem, so that is why if you refresh this page, the above gif will not cause text to jump. Even if you disable cache, crank network settings way down, you will still not see cumulative layout shift. Forem is open source, so it's all there for your learning pleasure. Here is the pull request where this all went down.

Forem uses FastImage to quickly and minimally inspect images for their height and width attributes as well as whether they are animated gifs. This is used to help with issues pertaining to prefers-reduced-motion in our efforts to provide the most accessible experience.

Attempting to do too much of this on the client would bog down the experience. Doing it at save time ensures our capacity to make best use of basic browser functionality.

If you are working with Ruby, you could most likely implement FastImage exactly as we have. If you are using different tools, this pattern is still likely to be an effective way to generally handle enriching and progressively enhancing content as it changes. Generally content is consumed far more often than it changes, so it is efficient to do this at the moment of change and allow the consumption experience to be as unencumbered as possible.

For more on CLS, here is the de facto guide. That's where the gif came from.

DEV runs on Forem, which anyone else can use to run their own content-based communities like ours, so it is important to us that we continually refine the core experience for the most possible collective benefit.

If you are interested in chipping in, this functionality could be slightly optimized. We currently inspect images twice. Once for size and once for animated?... PRs absolutely welcome if you can improve this and include a test along the way.

Happy coding! ❤️

Top comments (4)

canrau profile image
Can Rau

Oooh how I very much dislike those shifts, also happens in Android notifications, a new one arrives just when I'm about to swipe one away which leads me to accidentally remove the wrong one 😭😤

Thanks for adding this feature and talking about it 🙏

noone73273758 profile image
No one

I love to do programming. I am student of computer science and love to do code. This website help me a lot in making this, Please check my website and let me know how good I made it. You people really help me a lot. Thank you!

highcenburg profile image
Vicente G. Reyes

ahhhh! This is probably what's happening to my studio's website or perhaps I just need a loading animation to make it look nice when my site loads. Thanks for sharing, Ben!

ky1e_s profile image
Kyle Stephens

Twitter mobile web suffers from this a lot.