We’ve all seen the trend by now: a large hero image that serves as sort of the proverbial handshake of a website. Big pretty picture, some tagline or hook, and a call-to-action.
The traditional way of handling the styling of a hero image would be to fix the background image and use the cover background size.
The basic code for this looks like this:
With a centered tagline, and some body content for context, here’s what the result looks like:
Everything looks well enough, but when we inspect the performance of this background, here’s what we see:
The result of this performance hit is something close to 10FPS when the user is scrolling. What this looks like to the user is a jagged, laggy behavior with both the background image as well as any content that exists within that div.
The reason this occurs is the background-attachment: fixed, which causes a paint operation every time the user scrolls. The logic behind this is the page must reposition the content as well as the background image since it’s supposed to look like it’s holding still. So the browser needs to repaint the image in a new location relative to its DOM elements.
What’s the solution?
The simplest way to improve this performance is by giving what we’re calling our hero div in these examples its own element that can move independent from the surrounding elements.
So what we do is swap GPU-intensive properties like background-size:cover and background-attachment: fixed from the selector itself over to the pseudo class and give that pseudo a few more properties so that when painting happens on scroll it only occurs once; in its own layer.
This is what our simple example looks like:
And here’s what it looks like applied:
If all goes well, you won’t see any design changes. But you should notice a performance increase.
Here’s how the Vehikl site improved:
The key to getting this to all play nicely is the will-change: transform property on the pseudo. What this does is it tells the browser to render the element separate from everything around it, so we don’t see repainting of anything but the image, which should be imperceptible since the eye should be focusing on our new clean and smooth content within our hero.