Text-wrap: balance; a CSS versus JS web performance comparison

Text-wrap: balance; a CSS versus JS web performance comparison

Let's support my previous claims by actually researching the performance impact of using a JS and CSS-only solution for headline text balancing

It should make sense that using a CSS-only solution for headling text balancing should have less performance impact than a solution that involves JavaScript. But it's way more fun to actually run the numbers. And that's exactly what I did by creating a demo page for myself and open up DevTools' performance panel.

Below are different tests and their outcomes.

Testing conditions

I decided to test with both CPU throttling (x4) and no throttling. Tests were done in incognito mode. This prevents Chrome plugins from running on the same main thread. Do note that your actual audience often won't use incognito mode when visiting your site, so numbers might be worse in real life.

To be able to properly test this, I created a listing page containing multiple headings as that's a common scenario where the absence of balanced headlines will be noticed the most. One could think of blog or product listing pages.

The comparison script

I then created a script:

  • where I could easily increase or decrease the amount of listed items and thus headings;
  • containing buttons to apply balanced text on the fly via either CSS or JS;
  • applying it via a setTimeout to prevent profiling overhead ending up in the critical part of my research

Here's the demo page

By using setTimeout, it involves JS time for the CSS solutions (as the setTimeout can be seen in the timeline). However, text-wrap: balance; would typically be applied from the start instead of via a JS timer/handler. So I ignored script time and only looked at rendering + painting work.

For the JS version, I ended up looking at loading + scripting + rendering + painting work.

The CSS versus JS outcomes

incognito, no throttling:

  • 12 headings:
    JS: 49ms, CSS: 2ms
  • 24 headings:
    JS: 95ms, CSS: 2ms
  • 48 headings:
    JS: 208ms, CSS: 3ms
  • 96 headings:
    JS: 461ms, CSS: 5ms

incognito, 4x CPU throttling:

  • 12 headings:
    JS: 295ms, CSS: 8ms (screenshots below)
  • 24 headings:
    JS: 613ms, CSS: 9ms
  • 48 headings:
    JS: 1346ms, CSS: 15ms
  • 96 headings:
    JS: 3178ms, CSS: 25ms

Performance timeline screenshots

Screenshots of performance timeline for my CSS and JS test can be found below. Both are from same testing conditions: 12 headings with 4x CPU throttling.

In both tests, I used performance.measure to mark and highlight the JS duration in my script for calling the function that is responsible for balancing the text on the fly. This can be seen in the yellow bar in the "Timings" lane, either called css-balance or js-balance.

CSS-only solution

The timeline below is zoomed in quite a lot. We're seeing a total of only 20 milliseconds! As a result, it might look like the result of the setTimeout ("Timer Fired") and encapsulated "balanceTextViaCSS" function call is taking a lot of time. But it's only 4ms and as explained above, excluded from the comparison.

What you're seeing:

  • I created a function called balanceTextViaCSS which is responsible for applying text-wrap: balance;.
  • Then, the browser needs to re-paint portions.
  • Based on the Summary numbers, we can see it's all done quite fast.

JavaScript solution

I used an existing JavaScript library here to apply text-balancing via JavaScript. As one might expect, the performance timeline of the JavaScript equivalent is way busier.

And below, we're seeing a total of 300 milliseconds. That's because I didn't need to zoom in as much, so it's containing 15 times more.. time.

What you're seeing:

  • A timer is fired and the balanceText function is called;
  • All other work is done within that function and thus also attributed to the timer (Timer Fired);
  • It's then quite clear to spot the individual work for each heading;
  • Once done, the final rendering + painting work isn't that much anymore.

But by this point too much work went to scripting, causing one long tasks and blocking the browser's main thread for a very long time.

Web performance conclusion

The conclusion should be quite clear. We were able to confirm that the CSS-only solution to balance your text is better for performance compared to using a JavaScript solution.

Moreover, the duration of JS solution expectedly growths with the amount of elements that needs to be adjusted.

In general, this test is proving that:

  • it's a good thing that browser vendors continue to evolve the web by introducing new CSS properties and values when it seems that such features are wanted by the web community
  • when a CSS equivalent is available, it should by used by platforms and developers.