How to Write CSS with Performance in Mind
Slow load times can seriously hamper the effectiveness of your page. Nearly half of web users nowadays expect a page to load in two seconds or less. If it doesn’t, many users will simply abandon the page and search for other sources and thereby missing out on the content you are hosting.
Even if they don’t, they will start off with a negative perception, which can be hard to dislodge. Furthermore, because of the halo effect, their negative opinion of your page will transfer over to a negative opinion of your products – which is obviously the last thing you want. For that reason, it is important to think about how to improve your website’s loading speed.
Of course one obvious way is to migrate your website to faster and more powerful server, and possibly using CDN which can be expensive. Another way is to check out the many tips to dramatically Improve a Website speed, as I discussed in several tutorials on my Blog. I also discussed using HTML5 to speed up performance on mobiles.
Today I am going to look at how to use CSS to improve performance and thus enhancing User Experience. Remember, every bit helps.
We will begin by taking a look at the workflow of how a webpage render. From there we will then be able to focus on the performance problems that CSS can solve.
The Webpage Flow of Operations
- Style recalculation: The browser begins by computing the styles that will be applied to different elements of the DOM tree. A render tree is formed with the exception of some nodes (e.g. elements with
display: none;
and pseudo-elements). - Reflow (i.e. Layout): With the computed style from step one, the browser now calculates the position and geometry of different elements on the page.
- Repaint: With the layout map completed, pixels are drawn to the screen.
- Composite Layers: During repainting, the paint might be done in the different layers separately, after which all layers are combined into one.
Next let’s explore how we can write the CSS code to enhance website performance and thereby making your website load faster and thus improve user experience. Here are the 3 steps:
1. Reduce the Number of Style Calculations
As every calculation takes time, the easiest way to reduce page load time is to reduce style calculations. The first step to do so is during the style recalculation stage.
During this stage the browser begins by finding all the CSS selectors which point to element nodes in the DOM tree. From there it processes all the style rules that it finds and works out which ones will be applied to the element.
So how do you use this knowledge to reduce style calculations? The first step is as much as possible reduce complex selectors that are deeply nested, so that the browser has an easier time figuring out which element a selector is being referred to.
Next steps are: remove the style rules are not being using, and cutting down as much as possible on redundancy overrides, so as to reduce the amount of code the browser has to process. Simpler is better.
Another way to reduce style calculation cost is to cut the DOM tree size.
Further Reading
- Reduce the scope and complexity of style calculations
2. Reduce Reflows
You should also consider reducing Reflows (or layout changes) of an element, as this takes up a great deal of processor time.
Reflows are caused whenever there are changes to the layout of an element. For example – when the geometric properties, such as height or font size of an elements is modified, or when classes are removed or added to an element, to name few.
Here just like we talked about in the first section, what you want to do is avoid complex selectors that will take the browser longer time to calculate, as well as deep DOM trees.
The best way to change layout styles of a component is therefore to target the element that is the lowest in the hierarchy of elements that the component is made of, as this will trigger almost no Reflows.
Also, if you are animating an element (something we discuss in more detail in this tutorial) take it out of the page flow and instead absolutely position it (position: absolute;). Since Reflow in absolutely positioned elements won’t affect the rest of the elements on the page.
Further Reading
- Minimizing browser reflow
- What are reflows and repaints and how to avoid them
3. Reduce Repaints
As repaints can also be expensive and significantly reduce performance, here too the mantra less is more should be obeyed. This goes double for more expensive repaint elements, such as shadows.
Also, when you have an element that has to be repainted frequently, make sure that it is on its own layer, so that not all other elements on that layer need to be repainted along with it. Also, consider using hardware acceleration, which will vent the process over to the GPU, thereby freeing up the CPU and also making everything just go a bit faster.
So how do you force an element into a new layer and use hardware acceleration? Here are two techniques.
- First you can add the transform:
translate3d(0, 0, 0);
to it, thereby making the browser trigger the hardware acceleration for transitions as well as animations. - Alternatively, add the
will-change
property, as this tells the browser that this property is likely to change in the future.
Final Thoughts
I did not discuss reducing CSS file size. But What I have talked about instead is reducing the DOM elements and style rules, as this will make your page perform significantly better.
Simply through CSS code reduction: writing better selectors and getting rid of unused CSS, the size of your CSS file will decrease.
You should avoid making too many big changes to an element’s style in JavaScript. Instead, it is far better to add a class element in JavaScript that holds the new styles and then use the class to make these changes, thereby avoiding unnecessary Reflows.
Another thing you will want to avoid is forced synchronous Reflows also known as Layout Thrashing.