Home  >  Q&A  >  body text

JavaScript updates CSS custom properties slower than using element styles: performance comparison

I created a calendar slider for vue 3 that uses mousemove and touchmove events to implement sliding animation, as well as functions to perform some speed animations. The project can be tested here: https://stackblitz.com/github/Der-Alex/vue-calendar-slider?file=src/components/VueCalendarSlider.vue

My first idea was to use css custom properties --posx to store the slide position document.documentElement.style.setProperty('--posx', ${posx. value}px);. In my styles section, I set transform:translate3d(var(--posx), 0, 0) to move my elements. Then, on the mouseup / touchend, I used a speed animation so that the slider slides more based on the sliding speed.

After everything was normal, I tested the slider in the mobile Chrome browser and found that the slider was very stuck. After some digging and fiddling, I found that other sliders write the transform attribute directly to the element via element.style.transform = translate3d(${posx.value}px, 0, 0); and then I've done this too. Slider performance is much better after the change.

To test this behavior, you can edit the following line in the src/components/VueCalendarSlider.vue file: const testCssCustomProperties = ref(false); When set to true, Write the css custom property document.documentElement.style.setProperty through . When set to false, element.style.transform is used.

After learning that style changes can traverse the DOM, I directly set css custom properties at the specific elements to be transformed, but the performance is still much worse than using style.transform.

My question now is: Can anyone explain why document.documentElement.style.setProperty('--posx', ${posx.value}px); has better performance than element .style is much different. transform = translate3d(${posx.value}px, 0, 0);? I guess this has to do with how javascript handles these parts internally, and the engine may have moved the element.style content to GPU, and document.documentElement.style will not be moved. But I can't find anything concrete.

I hope someone can explain it to me :)

P粉235202573P粉235202573286 days ago369

reply all(1)I'll reply

  • P粉299174094

    P粉2991740942024-01-08 00:47:47

    Updated on September 13, 2022

    I did another performance check using Chrome Dev Tools and measured the following:

    Figure 1 shows the performance between mousedown and mouseup for this variant, where I write the new clientX position directly to the element via element.style.transform:

    Figure 2 shows the performance of the same event. Here I write the clientX position into a CSS custom property through element.style.setProperty('--posx', ${posx.value}px);

    So I went a step further and changed the code to write CSS custom properties directly to the element via

    element.style.setProperty('--posx', ${posx.value}px); . The results are the same as Figure 2.

    Testing the opposite way by

    element.style.setProperty('transform',translate3d(${posx.value}px, 0, 0)); writing the clientX position gives me the same result as in Figure 1.

    As I understand it, changing the CSS custom property via JavaScript forces the style to be recalculated every frame, while changing the CSS property

    transform:translate3d does not.

    So I guess

    @S.Visser is right.

    reply
    0
  • Cancelreply