Eric
Eric

Reputation: 6345

What is the most efficient way in JavaScript to dynamically set multiple CSS styles so it applies to a node?

I have some code where I need to set multiple styles on a single DOM element and I am worried it is not going to have good performance if the number of styles becomes to large because it has to access the dom node each time. Is there a better way to handle this?

Here is what I have so far (which functionally works and is the most efficient way I could think of).

const rootStyle = document.documentElement.style,
      cssVars = getCssVars();
for (var key in cssVars) { // eslint-disable-line no-restricted-syntax
    rootStyle.setProperty(key, cssVars[key]);
}

Upvotes: 0

Views: 322

Answers (1)

jayms
jayms

Reputation: 4018

Questions like "What is the fastest/efficient way to ..." can only really be answered for specific versions of browsers and not in general. Browser-vendors constantly optimize their browsers for all kinds of things.

It is safe to assume in this case, that most major browsers understand what you are doing here and wait until you are done, before they render the result.

Here is an excerpt from Google's description of the "pixel pipeline", to give you an idea what is going on:

  1. JS / CSS > Style > Layout > Paint > Composite The full pixel pipeline

If you change a “layout” property, so that’s one that changes an element’s geometry, like its width, height, or its position with left or top, the browser will have to check all the other elements and “reflow” the page. Any affected areas will need to be repainted, and the final painted elements will need to be composited back together.

  1. JS / CSS > Style > Paint > Composite The pixel pipeline without layout.

If you changed a “paint only” property, like a background image, text color, or shadows, in other words one that does not affect the layout of the page, then the browser skips layout, but it will still do paint.

  1. JS / CSS > Style > Composite The pixel pipeline without layout or paint.

If you change a property that requires neither layout nor paint, and the browser jumps to just do compositing.

This final version is the cheapest and most desirable for high pressure points in an app's lifecycle, like animations or scrolling.

So if you encounter performance problems, you can attempt to avoid changing css that triggers a "reflow". Your for-loop is probabably not the bottleneck, but many browsers offer profiling tools which allow you to test the performance of certain parts of your code.

Upvotes: 1

Related Questions