Whether you’ve noticed it or not, in recent years, the topic of optimization and performance of websites has become a hot topic. The topic primarily focuses on the loading time of websites and is achieved by reducing the overall weight of the files, server-level optimization, and other techniques.
But what about optimization after the page has loaded? In the past, there were no suitable tools for analyzing Frontend Performance, and the need for them was not obvious.
However, the way we access the internet has changed drastically in recent years, and a very respectable percentage of the population finds itself browsing the internet on mobile devices of various kinds.
Although the hardware of mobile devices has been upgraded over these years, it’s important to remember that in terms of hardware specifications, mobile devices are significantly inferior to desktops and laptops, which means that your website’s performance on these devices is lower and may frustrate users, and worse, cause them to abandon the site.
As the websites we develop become more complex, we need to ensure a proper user experience through optimization for animations and website scrolling performance (Scrolling Performance) among others.
To do this, we need to achieve a frame rate of 60fps, a number that approximates the refresh rate of the screens on those devices, to provide as smooth performance as possible.
On mobile devices, and sometimes even on laptops and desktops, the way to provide these performances can be challenging, especially on complex sites. In this article, I’ll try to explain a bit about how to approach this issue on your site and improve Frontend performance.
This topic is broad and there’s a lot to say about it, but I’ll try to maintain focus in this guide and explain in a straightforward way one method to improve Frontend performance with an emphasis on site scrolling performance.
About Frontend Performance and the Repainting Action in Browsers
If you’re changing the layout, i.e., changing the position of elements on the page, then the browser is forced to work to repaint the pixels on the screen, an action called repainting.
Repaint occurs with any attribute change to an element on the page that isn’t a change in opacity
or transform
if I’m not mistaken. When the browser changes layout, it will always perform a repaint because every geometric change of an element means pixels need to change.
In most cases, the action of “arranging” the pixels on your screen is the most time-consuming action in the pipeline and should be avoided as much as possible.
If we use images that Google provided us, the work that the browser performs (the pipeline we’re talking about) is done in the following way:
By the way, there are situations in which we change non-geometric attributes such as changing backgrounds, text color, shadows, etc. In these situations, there is no need to perform the layout process and the pipeline will look like this:
Using Chrome Dev Tools to Identify Bottlenecks in the Repainting Process
You can use Chrome Developer Tools to quickly identify areas that are repainted on your site. Go to the developer tools and open the Rendering tab. Then select the option “Paint flashing” as shown in the following image:
When this option is enabled, Chrome will flash green areas that are being repainted (Repainting). Scroll through your site’s page while this option is enabled and I assume you will discover several elements that are repainted during the scroll even though at first glance, it is not clear why these areas are being repainted.
If you find that there are such areas, you will need to investigate a bit and check why they are being repainted again and again.
Let’s give an example to better understand what we’re talking about and let’s look at Savvy Blog. Here is a video showing which areas are repainted when I scroll through the site (this is no longer the case after optimization):
Notice several things seen in the video during the scroll:
- The top part of the page (header) is painted green.
- The share buttons on the right are painted green.
- The box with another article (at the bottom of the page on the left) is painted green.
All these parts are repainted and load the browser every time a user scrolls through the site. Do you have an idea what these three have in common? I assume you guessed it… they all have the attributeposition:fixed
.
If you encounter situations where scrolling is not smooth and there are kind of “stutters” during scrolling, it is likely that the Repainting action in those sites is heavy. As we noted, this could be due to elements being fixed
, various animations, and the like.
Of course, we do not want to change the design of our site because of these stutters, so let’s see how to fix them to create smoother scrolling.
It might also be that many do not care about Frontend performance, but as a WordPress developer who emphasizes performance, it really bothers me when I encounter sites where I experience these stutters.
Let’s see how we can avoid situations (potential) of scrolling problems and animations by creating new layers for certain elements.
The idea is to reach a state where ideally the site operates at 60FPS. The lower the number of frames per second, the higher the chance you will experience stutters in animations and scrolling. We won’t expand on this topic, but you are welcome to understand how to measure frames in the following article.
Creating New Layers for Those Elements
There is no requirement for the browser to treat what we see on the screen as a single image in memory.
In fact, you can cause the browser to treat different elements as a separate layer, or in other words, as a number of separate images. You can create a separate layer for certain elements, thus causing them to be independent and not dependent on other elements on the page.
Think about it for a moment, when a certain element is in position:fixed
and we are looking at a single layer containing all the elements including that element in fixed, the browser has to (theoretically) repaint the single layer every time because the position of that element is different each time relative to the other elements on the page.
Fortunately, the browser already knows how to perform optimization for these situations but sometimes it needs a little help.
So, as we noted, you can cause the Repainting action not to take place every time just because the browser treats all elements as a single image but you can determine that certain elements will be in a separate layer. This action is called layer promotion.
The advantage of this approach is that elements that are repainted, or those that perform some movement on the screen using CSS transforms, can be managed without affecting other elements on the page. The idea is very similar to the way Photoshop works, where individual layers are managed one above the other to create the final image.
The WILL-CHANGE Property
The best way to create a new layer for a particular element is to use the will-change property in CSS. The will-change
property provides an indication to the browser about changes that may occur in a particular element so that the browser can perform a sort of optimization for that element before it actually changes on the screen.
This property will work in all modern browsers (at least in their latest version) and when you give this property the value transform
, a new layer or new layer will be created for that element.
.moving-element {
will-change: transform;
}
By the way, if you are interested in support for older browsers – you can use a kind of hack that has existed for years and it is the use of translateZ
as in the following example:
.moving-element {
transform: translateZ(0);
}
But pay attention to a few points in the context of the will-change property before you run to use it:
- Do not add the will-change property to too many elements. The browser tries to perform optimization on its own for elements on the page and excessive use of this property can lead to high resource consumption and even slow down the page.
- Adding the property in CSS causes the browser to keep the optimization in memory long beyond what is really necessary. It is preferable to use Javascript to add the property just before the element changes and remove it after completion.
- Do not use the will-change property just because you think there might be performance problems of any kind. Use this property only when you are experiencing performance issues and as a last resort.
Anyway, let’s see the result on Savvy Blog after I used the will-change
property for those problematic elements we mentioned:
As you can see, all those green squares disappeared because those elements received a new layer and do not “interfere” with other elements on the screen. I can assure you here and now that you will never experience scrolling performance problems on Savvy Blog 😉
How to Add the will-change property Using Javascript?
For the purpose of the article, I added the will-change
property using CSS on Savvy Blog. But as I mentioned, it is preferable to use this property using Javascript precisely before the change is made and to remove it after the change.
Here is an example describing how to do this for a particular element using JavaScript:
var el = document.getElementById('element');
// Set will-change when the element is hovered
el.addEventListener('mouseenter', hintBrowser);
el.addEventListener('animationEnd', removeHint);
function hintBrowser() {
// The optimizable properties that are going to change
// in the animation's keyframes block
this.style.willChange = 'transform, opacity';
}
function removeHint() {
this.style.willChange = 'auto';
}
Several Tips for Better Frontend Performance
There are several things you can do to improve the scrolling and animations on your site. As a result of these changes, the CPU/GPU will not have to work as hard and this will even translate to more satisfied visitors and lower battery consumption on mobile devices. Let’s give a few tips:
- Avoid using background images that have the property
background-attachment:fixed
. In certain browsers, these will cause repainting during scrolling and poor performance. - If you are using sliders or animations on your site, make sure you create a separate layer for them using the will:change CSS property.
- If there are many effects of CSS3, for example – many rounded corners, features like linear-gradients, and shadows, consider removing them or reducing their use. There is no problem using them but remember that if they exist excessively on your site – it will have an impact on Frontend performance.
- Always use the exact image size that the browser needs to display and save it from changing the size of the image on the screen itself. If you work with WordPress, take a look at the guide I wrote that explains about creating image sizes on these sites.
- Although we did not touch on this part, if you are using animations – try to use requestAnimationFrame. Using this method can improve the performance of animations and FPS dramatically.
In Summary
Chrome’s developer tools provide many ways to analyze and discover performance issues on your site, whether it’s Frontend performance or site performance in terms of loading time.
The truth is that in this guide we did not mention these methods beyond the use of the Paint Flashing option that helps to discover performance issues in terms of scrolling and animations.
Creating a separate layer for certain elements is the right action to take if you are experiencing performance problems in animations and scrolling.
The will-change property is an excellent solution, especially in complex sites so don’t be afraid to use it when necessary. In the same breath, I say that care should be taken when using this property excessively.
And if we’re talking about scrolling, take a look at the post I wrote about CSS driven scroll animations.
I hope I didn’t get too confused, this is a complex topic. In any case, if you have any comments or additions in your head, I would be happy if you comment and share with us in the comments.