Simon Hearne bio photo

Simon Hearne

Web Performance Consultant at NCC Group

Email Twitter LinkedIn Github

Webpage jank can harm the user experience, here's an easy way to measure it on your pages

Published


Here’s the bookmarklet: Jank Meter Drag it to your bookmarks bar or just add as a bookmark.

What is jank?

Our eyes can’t perceive visual changes at around 60 frames per second (FPS). As such, for smooth visual experiences most modern screens have a refresh rate of 60FPS. In order for our webpages to appear smooth to a user while interacting, all frames must render within 16ms (1000ms / 60 FPS).

What causes jank?

Anything that is expensive to process and causes the browser to repaint can cause jank. Common causes include large background images that move on scroll (parallax effect) and Javascript functions bound to scroll events. Paul Lewis (@aerotwist) wrote a good post on some of the causes of jank back in 2013.

Here’s an example of the jank meter on a web design agency’s homepage. They use a jQuery plugin to create a parallax effect on large (but barely visible) background images.

Jank Meter showing poor scroll performance

Conversely, here’s jankfree.org with a near-perfect scrolling experience:

Jank Meter showing good scroll performance

How do you detect jank?

You can detect jank using the Timeline tab in Chrome Developer Tools. Simply hit the record button and scroll, then stop the recording and look for slow frames:

Dev Tools showing Jank

You can also enable the framerate overlay in Chrome to show the live render performance:

Dev Tools showing FPS meter

This can all be a bit time consuming though, recently I’ve found myself spending a lot of time in the timeline view just to detect jank. The framerate meter also makes it difficult to identify exactly where in the page the jank is coming from.

I figured that there must be an easier way to do this. requestAnimationFrame has been around for a few years now, it lets you make timer-based animations more efficient by synchronising reflow and repaint events. This also gives us a clue as to how fast the browser can synchronise these events: ideally requestAnimationFrame should call your function every 16ms to get that silky-smooth 60FPS you want. If, however, it calls your function after 50ms you know that there has been something hogging the browser’s time when it should have been repainting. I created a small Javascript bookmarklet around this concept, scrolling down a page and measuring the effective framerate.

The bookmarklet produces a small overlay on the top-right of the screen showing the framerates achieved while scrolling the page. It also adds a bar to the left of the page showing what framerate was achieved for that scroll movement.

Jank meter limitations

  • Style is inherited, so it may look funny
  • It depends on being able to scroll, so the page has to be longer than 2 x viewport height
  • It relies on performance.now() and requestAnimationFrame() so it won’t work in all browsers (latest Firefox and Chrome are fine)
  • The chart image may not load on secure sites

There are probably a few more limitations, give it a go and let me know if you have any issues. The code is in a gist so feel free to fork.

How to fix jank?

Paul Lewis has a great live demo on youtube of debugging and fixing jank in realtime.

There are a number of resources available, jankfree.org is a great place to start.