PageSpeed: Use efficient CSS selectors


Avoiding inefficient key selectors that match large numbers of elements can speed up page rendering.

How does your site score on this recommendation?

Details from Google

As the browser parses HTML, it constructs an internal document tree representing all the elements to be displayed. It then matches elements to styles specified in various stylesheets, according to the standard CSS cascade, inheritance, and ordering rules. In Mozilla's implementation (and probably others as well), for each element, the CSS engine searches through style rules to find a match. The engine evaluates each rule from right to left, starting from the rightmost selector (called the "key") and moving through each selector until it finds a match or discards the rule. (The "selector" is the document element to which the rule should apply.)

According to this system, the fewer rules the engine has to evaluate the better. So, of course, removing unused CSS is an important step in improving rendering performance. After that, for pages that contain large numbers of elements and/or large numbers of CSS rules, optimizing the definitions of the rules themselves can enhance performance as well. The key to optimizing rules lies in defining rules that are as specific as possible and that avoid unnecessary redundancy, to allow the style engine to quickly find matches without spending time evaluating rules that don't apply.

The following categories of rules are considered to be inefficient:

  • Rules with descendant selectors
  • Rules with child or adjacent selectors
  • Rules with overly qualified selectors
  • Rules that apply the :hover pseudo-selector to non-link elements



PageSpeed recommends:

Avoid a universal key selector

Allow elements to inherit from ancestors, or use a class to apply a style to multiple elements.

Make your rules as specific as possible

Prefer class and ID selectors over tag selectors.

Remove redundant qualifiers

These qualifiers are redundant:

  • ID selectors qualified by class and/or tag selectors
  • Class selectors qualified by tag selectors (when a class is only used for one tag, which is a good design practice anyway).
Avoid using descendant selectors, especially those that specify redundant ancestors

For example, the rule body ul li a {...} specifies a redundant body selector, since all elements are descendants of the body tag.

Use class selectors instead of descendant selectors

For example, if you need two different styles for an unordered list item and an ordered list item, instead of using two rules:

ul li {color: blue;}
ol li {color: red;}

You could encode the styles into two class names and use those in your rules; e.g:

.unordered-list-item {color: blue;}
.ordered-list-item {color: red;}

If you must use descendant selectors, prefer child selectors, which at least only require evaluation of one additional node, not all the intermediate nodes up to an ancestor.

Avoid the :hover pseudo-selector for non-link elements for IE clients

If you use :hover on non-anchor elements, test the page in IE7 and IE8 to be sure your page is usable. If you find that :hover is causing performance issues, consider conditionally using a JavaScript onmouseover event handler for IE clients.

Read More