How to Avoid DOM Blocking in JavaScript
JavaScript programs run on a single thread in the browser and in runtimes such as Node.js. When code is executing in a browser tab, everything else stops: menu commands, downloads, rendering, DOM updates and even GIF animations.
This is rarely evident to the user because processing occurs quickly in small chunks. For example: a button is clicked which raises an event that runs a function which makes a calculation and updates DOM. Once complete, the browser is free to handle the next item on the processing queue.
JavaScript code can’t wait for something to occur; imagine the frustration if an app froze every time it made an Ajax request. JavaScript code therefore operates using events and callbacks: a browser or OS-level process is instructed to call a specific function when an operation has completed and the result is ready.
In the following example, a handler function is executed when a button click event occurs which animates an element by applying a CSS class. When that animation completes, an anonymous callback removes the class:
// raise an event when a button is clicked
document.getElementById('clickme').addEventListener('click', handleClick);
// handle button click event
function handleClick(e) {
// get element to animate
let sprite = document.getElementById('sprite');
if (!sprite) return;
// remove 'animate' class when animation ends
sprite.addEventListener('animationend', () => {
sprite.classList.remove('animate');
});
// add 'animate' class
sprite.classList.add('animate');
}
ES2015 provided Promises
and ES2017 introduced async
/await
to make coding easier, but callbacks are still used below the surface. For more information, refer to “Flow Control in Modern JS”.
Blocking Bandits
Unfortunately, some JavaScript operations will always be synchronous, including:
- running calculations
- updating the DOM
- using localStorage or IndexedDB to store and retrieve data.
The following pen shows an invader which uses a combination of CSS animation to move and JavaScript to wave the limbs. The image on the right is a basic animated GIF. Hit the write button with the default 100,000 sessionStorage operations
:
See the Pen
DOM-blocking animation by SitePoint (@SitePoint)
on CodePen.
DOM updates are blocked during this operation. The invader will halt or stutter in most browsers. The animated GIF animation will pause in some. Slower devices may show a “script unresponsive” warning.
This is a convoluted example, but it demonstrates how front-end performance can be affected by basic operations.
The post How to Avoid DOM Blocking in JavaScript appeared first on SitePoint.
Comments
Post a Comment