Do Unused CSS Styles Affect Load Times

Do unused CSS styles affect load times

Any unused CSS or JS that is passed over the wire to the client will hurt the sites performance at the least to a small degree. The unused CSS increases the size of the page, therefore increasing the time it takes to download a page. A few characters here and there will not have a huge impact on your download times, however if there is a large amount of unused styling there may be an impact. This is why many people compress their CSS and JS.

What is the performance impact of having many unused CSS selectors/rules?

The only real impact will come from the css file size being slightly larger, resulting in longer download and parse times.

But for the most part, there are a few million other things with much bigger impact.

Is it worth removing unused CSS?

Is it worth removing unused CSS rules?

I would say yes. To have any unused code in your production build is not cool .

However, unless something has gone very wrong, it is highly unlikley that your CSS is the reason for slow page loads, in fact the impact of loading a couple pages of unused css rules will be almost neglible. It's more likley to be images/ media, or maybe scripts.

You should probably investigate whats slowing down your page. Have a look in the network tab of your dev tools to start debugging why page load is slow, Google Page Load Insights may also help. Have a look at this blog series, about speeding up your web apps too.

If you've not done so already you should probably minify and bundle your CSS and JS for production also.


How to find and remove unused CSS rules

Removing unused CSS is a common task, and there are a lot of packages and tools out there which make it strait-forward. There are several options, going forwards:

1. Manually remove unused CSS.

If your app is still quite small, this will probably be the easiest approach.

  1. Open Chrome DevTools
  2. Open the command menu with: cmd + shift + p
  3. Type in “Coverage” and click on the “Show Coverage” option
  4. Select a CSS file from the Coverage tab which will open the file up in the Sources tab

Source: Google Developer, Chrome 59

2. Use an online tool

There are tools out there, where you can just feed it a link to your site, and it will search and find unused CSS. The drawback here, is that this won't work locally.

  • The best tool available it probably UnusedCSS, however it only
    allows you to do one site for free.
  • UnCSS it totally free, but not as comprehensive.
  • PureifyCSS is also good, and free.

3. Automate CSS removal

uncss allows you to automate unused CSS removal, either at built-time, or complile-time. It also works with Grunt and Babel.


A word of warning, some of your CSS might be detected as unused, when actually you are using it later on, such as when a request has finished loading. Be sure not to delete classes that are indirectly used.

Edit:

Be careful when using coverage for CSS usage, it considers media
queries, hover effects and others as useless since they're not applied
when loading your page

See also: https://css-tricks.com/unused/

Which CSS selectors or rules can significantly affect front-end layout / rendering performance in the real world?

The first thing that comes to mind here is: how clever is the rendering engine you're using?

That, generic as it sounds, matters a lot when questioning the efficiency of CSS rendering/selection. For instance, suppose the first rule in your CSS file is:

.class1 {
/*make elements with "class1" look fancy*/
}

So when a very basic engine sees that (and since this is the first rule), it goes and looks at every element in your DOM, and checks for the existence of class1 in each. Better engines probably map classnames to a list of DOM elements, and use something like a hashtable for efficient lookup.

.class1.class2 {
/*make elements with both "class1" and "class2" look extra fancy*/
}

Our example "basic engine" would go and revisit each element in DOM looking for both classes. A cleverer engine will compare n('class1') and n('class2') where n(str) is number of elements in DOM with the class str, and takes whichever is minimum; suppose that's class1, then passes on all elements with class1 looking for elements that have class2 as well.

In any case, modern engines are clever (way more clever than the discussed example above), and shiny new processors can do millions (tens of millions) of operations a second. It's quite unlikely that you have millions of elements in your DOM, so the worst-case performance for any selection (O(n)) won't be too bad anyhow.


Update:

To get some actual practical illustrative proof, I've decided to do some tests. First of all, to get an idea about how many DOM elements on average we can see in real-world applications, let's take a look at how many elements some popular sites' webpages have:

Facebook: ~1900 elements (tested on my personal main page).

Google: ~340 elements (tested on the main page, no search results).

Google: ~950 elements (tested on a search result page).

Yahoo!: ~1400 elements (tested on the main page).

Stackoverflow: ~680 elements (tested on a question page).

AOL: ~1060 elements (tested on the main page).

Wikipedia: ~6000 elements, 2420 of which aren't spans or anchors (Tested on the Wikipedia article about Glee).

Twitter: ~270 elements (tested on the main page).

Summing those up, we get an average of ~1500 elements. Now it's time to do some testing. For each test, I generated 1500 divs (nested within some other divs for some tests), each with appropriate attributes depending on the test.



The tests

The styles and elements are all generated using PHP. I've uploaded the PHPs I used, and created an index, so that others can test locally: little link.



Results:

Each test is performed 5 times on three browsers (the average time is reported): Firefox 15.0 (A), Chrome 19.0.1084.1 (B), Internet Explorer 8 (C):

                                                                        A      B      C
1500 class selectors (.classname) 35ms 100ms 35ms
1500 class selectors, more specific (div.classname) 36ms 110ms 37ms
1500 class selectors, even more specific (div div.classname) 40ms 115ms 40ms
1500 id selectors (#id) 35ms 99ms 35ms
1500 id selectors, more specific (div#id) 35ms 105ms 38ms
1500 id selectors, even more specific (div div#id) 40ms 110ms 39ms
1500 class selectors, with attribute (.class[title="ttl"]) 45ms 400ms 2000ms
1500 class selectors, more complex attribute (.class[title~="ttl"]) 45ms 1050ms 2200ms


Similar experiments:

Apparently other people have carried out similar experiments; this one has some useful statistics as well: little link.



The bottom line:

Unless you care about saving a few milliseconds when rendering (1ms = 0.001s), don't bother give this too much thought. On the other hand, it's good practice to avoid using complex selectors to select large subsets of elements, as that can make some noticeable difference (as we can see from the test results above). All common CSS selectors are reasonably fast in modern browsers.

Suppose you're building a chat page, and you want to style all the messages. You know that each message is in a div which has a title and is nested within a div with a class .chatpage. It is correct to use .chatpage div[title] to select the messages, but it's also bad practice efficiency-wise. It's simpler, more maintainable, and more efficient to give all the messages a class and select them using that class.



The fancy one-liner conclusion:

Anything within the limits of "yeah, this CSS makes sense" is okay.



Related Topics



Leave a reply



Submit