#ASKTHEINDUSTRY 29: When is it ok to read and write layout properties in JavaScript?

Reading and writing layout properties are scary things to do in front end JavaScript, if you care at all about performance. Bad words like layout thrashing and forced synchronous layout start haunting you at night.

Let’s clear things up a bit, shall we?

There is no intrinsic harm involved in reading and writing layout in JavaScript. As I understand it, the main issue is related to when you do it.

There is no intrinsic harm involved in reading and writing layout in JavaScript.

Take a look at this code, is it going to affect performance?

// some code
readLayout();
writeLayout();
// some other code

Maybe. During the course of a frame, JavaScript is executed last, after the browser calculated where things are supposed to be painted.

Simplified frame:  
| Layout | Paint | JavaScript |

The problem that arises with that piece of code is that, since we are writing layout, the browser is forced to recompute layout and repaint, extending the current frame beyond an acceptable duration.

| Layout | Paint | JavaScript | Layout | Paint |

The standard-compliant solution would be to request the browser to execute your layout-writing JavaScript at the beginning of the next frame, before it computes layout. How? Through requestAnimationFrame.

requestAnimationFrame( function() {
readLayout();
writeLayout();
} );

Here is where a rAF callback is executed:

| rAF | Layout | Paint | JavaScript |

Much better. Take particular notice of the readLayout() call, though. Since we are at the beginning of a frame, we can exploit this unique position to access information relative to the previous frame. However, if we invalidated that information by writing layout before reading it, we would force the browser to trigger the layout and styles processes before its time.

Anyway, as a rule of thumb, one can simply keep in mind the following:

  1. Batch your writes in a requestAnimationFrame callback
  2. Batch your reads before any of your writes

If you’ve found this post useful at all, press the ❤ button! I read each and every comment, so be sure to contribute to the conversation with your thoughts!