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 :)
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
So I went a step further and changed the code to write CSS custom properties directly to the element viaelement.style.setProperty('--posx', ${posx.value}px);
element.style.setProperty('--posx', ${posx.value}px);
Testing the opposite way by. The results are the same as Figure 2.
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 propertytransform:translate3d
So I guessdoes not.
@S.Visser is right.