Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the use of CSS generated content (i.e. pseudo elements) more efficient (i.e. parsed/rendered faster) than adding more DOM elements?

Tags:

In order to keep my mobile web app lean and efficient, I'm trying to limit the number of elements on the DOM at any given time. One way in which I intend to limit the use of DOM elements, is by using the pseudo :before and :after elements to generate content where possible.

For example, rather than representing a list-item with metadata like this:

<dd class="item">     <div class="name">Name</div>     <div class="desc">Description</div>     <div class="location">Location</div>     <div class="genre">Genre</div> </dd> 

I could represent it like this (& use the content: property to display the metadata):

<dd class="child"      data-name="Name"      data-desc="Description"      data-location="Location"      data-genre="Genre"> </dd> 

So, one DOM element with data attributes as opposed to 5 separate elements and arguably cleaner markup.
Demo here: http://jsfiddle.net/quc8b/2/

Will this technique actually improve performance? My thought is that with fewer DOM elements javascript should parse faster and I should be able to add/remove the list-item nodes faster. But will rendering (i.e. painting, layout, & reflows) occur faster? In other words, is CSS generated content rendered/parsed faster or more efficiently than traditional elements and text nodes?

How browsers internally handle CSS generated content in the render tree and document tree is an unknown to me (shadow DOM maybe?). Are there any articles that discuss this?

like image 311
BigMacAttack Avatar asked Apr 15 '13 20:04

BigMacAttack


People also ask

What is the purpose of the content pseudo-element?

A CSS pseudo-element is used to style specified parts of an element. For example, it can be used to: Style the first letter, or line, of an element. Insert content before, or after, the content of an element.

What is a pseudo-element in CSS?

A CSS pseudo-element is a keyword added to a selector that lets you style a specific part of the selected element(s). For example, ::first-line can be used to change the font of the first line of a paragraph. /* The first line of every <p> element. */ p::first-line { color: blue; text-transform: uppercase; }

What does content do in CSS?

The content CSS property replaces an element with a generated value. Objects inserted using the content property are anonymous replaced elements.

Why we use before and after in CSS?

The ::before selector inserts something before the content of each selected element(s). Use the content property to specify the content to insert. Use the ::after selector to insert something after the content.


1 Answers

I was also interested in figuring this out. So I did a simple litte test case.

I created two html pages for comparison:

A. Pseudo-selectors:

  • HTML: 50.000 of these: <p>paragraph</p>

  • CSS: p:before { display: inline-block; width: 10px; height: 10px; margin-right: 5px; background-color: red; content: ""; }

B. Many DOM-elements:

  • HTML: 50.000 of these: <p><span class="icon"></span> paragraph</p>

  • CSS: .icon { display: inline-block; width: 10px; height: 10px; margin-right: 5px; background-color: red; }


Tests:

I used the Chrome Devtools Performance monitor running on a 2015 Macbook Pro.

Test1: "Start profiling and reload page"

Option B was the loser by ~400ms. It took 2452ms to parse while the "pseudo" variant took 2033ms. I ran this test three times with similar results.

screenshot

Test2: Resizing the window

To measure re-layout I started a separate recording where I resized the browser window 3 times by changing from full-screen to half-screen (using shortcut keys in a window manager)

"Many DOM-elements" was the winner, clocking in at 1136ms of rendering time, while "pseudo-elements" took 1463ms.

enter image description here

Test3: Reflows

I tried to cause reflows by measuring the page height using this piece of Javascript: document.body.offsetHeight;

But that never took more than 4ms to execute... not enough time to reliably measure performance.

Apparently 50.000 elements isn't enough to cause any significant slowdown in that area.

PS: The test selection wasn't all that scientific, they just happened to be the first ones I thought of

like image 115
Drkawashima Avatar answered Sep 20 '22 13:09

Drkawashima