JavaScript 更新 CSS 自定义属性比使用元素样式慢:性能比较
P粉235202573
P粉235202573 2024-01-07 09:42:03
0
1
408

我为 vue 3 创建了一个日历滑块,它使用 mousemove 和 touchmove 事件来实现滑动动画,以及执行一些速度动画的函数。该项目可以在这里测试:https://stackblitz.com/github/Der-Alex/vue-calendar-slider?file=src/components/VueCalendarSlider.vue

我的第一个想法是使用css自定义属性 --posx 来存储幻灯片位置 document.documentElement.style.setProperty('--posx', ${posx.value}px); 。在我的样式部分,我设置 transform:translate3d(var(--posx), 0, 0) 来移动我的元素。然后,在 mouseup / touchend 上,我使用了速度动画,以便滑块根据滑动速度滑动得更多。

一切正常后,我在移动 Chrome 浏览器中测试了滑块,发现滑块卡顿得非常严重。经过一番挖掘和摆弄后,我发现其他滑块通过 element.style.transform = translate3d(${posx.value}px, 0, 0); 直接将转换属性写入元素,然后我也这样做做过。更改后滑块性能好多了。

要测试此行为,您可以在 src/components/VueCalendarSlider.vue 文件中编辑以下行: const testCssCustomProperties = ref(false); 当设置为 true 时,通过 写入 css 自定义属性document.documentElement.style.setProperty。当设置为 false 时,使用 element.style.transform

得知样式更改可以遍历 DOM 后,我直接在要转换的特定元素处设置 css 自定义属性,但性能仍然比使用 style.transform 差很多。

我现在的问题是:谁能解释一下为什么 document.documentElement.style.setProperty('--posx', ${posx.value}px); 的性能比 element.style 差很多。变换 = translate3d(${posx.value}px, 0, 0);?我想这与javascript如何在内部处理这些部分有关,并且引擎可能将 element.style 内容移动到GPU,而 document.documentElement.style 不会被移动。但我找不到任何具体内容。

我希望有人能向我解释一下:)

P粉235202573
P粉235202573

全部回复(1)
P粉299174094

2022年9月13日更新

我使用 Chrome 开发工具进行了另一次性能检查并测量了以下内容:

图 1 显示了该变体的 mousedown 和 mouseup 之间的性能,其中我通过 element.style.transform 将新的 clientX 位置直接写入元素:

图 2 显示了相同事件的表现。这里我通过 element.style.setProperty('--posx', ${posx.value}px); 将 clientX 位置写入 CSS 自定义属性:

所以我更进一步,更改了代码,以便通过 element.style.setProperty('--posx', ${posx.value}px); 直接将 CSS 自定义属性写入元素。 。结果与图 2 相同。

通过 element.style.setProperty('transform',translate3d(${posx.value}px, 0, 0)); 编写 clientX 位置来测试相反的方式给我结果与图 1 相同。

据我了解,通过 JavaScript 更改 CSS 自定义属性会强制对每个帧重新计算样式,而更改 CSS 属性 transform:translate3d 则不会。

所以我猜@S.Visser是对的。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板