我為 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.值}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
不會被移動。但我找不到任何具體內容。
我希望有人能跟我解釋一下:)
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是對的。