Your eyes, your computer screen, your browser and the JavaScript event loop!
By: Rishabh Rao
Tags: JavaScript, Vision, Browsers, Event Loop, Eyes

Your eyes, your computer screen, your browser and the JavaScript event loop!

Your eyes

For the human eye & brain to perceive smooth motion, the screen must be redrawn at least 24 times per second¹.

In our childhood, we used draw pictures in a flip book² and run it by with our thumb. It used to feel like the pictures are moving.

1886 illustration of the kineograph

“The Horse in Motion”³ was one the first real sequence photographed in real-time, rather than consisting of a series of posed photographs, was created in the US in 1878 by British photographer Eadweard Muybridge⁴.

“The Horse in Motion” by Eadweard Muybridge on Wikipedia

If you go in your monitor settings, then you’ll see a setting called refresh rate. It’s usually 60Hz. It means that the monitor redraws your screen 60 times in a second or 60fps.

Movies are played at 24fps, 25fps or 30fps. Persistence of vision creates an illusion of smooth motion in our brain.

Your computer screen

For computer screens, the refresh rate must be at least 60Hz otherwise we’ll experience a headache & eye strain. Some screens have 80Hz etc.; but anything more than 60Hz is good.

Let’s do some math, shall we? 60Hz means that the monitor needs to draw 60 frames in 1000 milliseconds. So How many milliseconds would it take the monitor to draw 1 frames?

Cross multiplying, we get…

1 frame

× 1000ms

÷ 60 frames

= ~16.667ms

Thus, each frame is redrawn every ~16.667ms, also known as a render cycle.

Your browser

Now, in every render cycle, the monitor sends a signal to the OS to redraw the screen. This is achieved via the display driver software. The OS, in turn, refreshes all the applications on the screen. The applications are also notified of the redraw event.

Your browser also receives this event and it schedules a new repaint event every render cycle on the browser’s the render queue.

The JavaScript event loop

This repaint is handled by the event loop⁵. Its job is to look at the JavaScript call stack, browser’s render queue & browser’s callback queue and execute all the queued functions, at every ~16.667ms interval.

Here’s a simplified algorithm in pseudo code…

for each render cycle, the event loop does the following…

if the JavaScript call stack is not empty

then execute code in the JavaScript call stack if the browser’s render queue is not empty

then execute paint events in the browser’s render queue if the browser’s callback queue is not empty

then execute functions in the browser’s callback queue

Now, if the functions inside the JavaScript call stack do not complete their execution within that render cycle, then there isn’t enough time remaining to execute the repaint events.

In the next render cycle, if the JavaScript call stack is still not empty, then the event loop has to again execute code in the JavaScript call stack. This again leaves not enough time to execute the repaint events.

This way, if the screen is not repainted for few a render cycles, what users perceive “jank” on the screen.

This also affects functions queued in the browser’s callback queue. The event loop does not have enough time to execute the event listeners queued in the browser’s callback queue. Users perceive this as “an unresponsive user interface”.

You can view and measure the performance in the Chrome dev tools — Performance panel⁶. Learn how to use the Performance panel in the article, “Get Started With Analyzing Runtime Performance”⁷, by Kayce Basques. For example, here’s a screenshot of measuring the performance of the hamburger menu animation in my CSS theme, Voxel⁸ (source: GitHub⁸).