vue3 高性能無縫滾動插件的實現

起因

vue3大屏開發過程中,列表長度不定,需要做在滾動顯示的設計,於是乎在npmjs上找到了下載量超高的無縫滾動的插件,集成簡單快捷,體驗也很好,不得不說是一個非常優秀的插件,但其有一個致命的缺陷,就是性能問題,當單個基於element-ui編寫的組件使用該插件,cpu增加30%左右,當超過4個組件使用,cpu會飆升至120%左右,後期穩定在107~154%之間(chrome使用shift+esc鍵可打開監控,查看資源佔用情況),此刻配置差一點的機器是無法正常工作的,無奈之下只能選擇自己造輪子了。

項目中使用

目前該組件已經發布至npmjs倉庫,進行了多次補丁升級,歡迎大家使用

安裝

npm install --save tank-vue3-seamless-scroll

導入

import TankSeamlessScroll from "tank-vue3-seamless-scroll"

使用組件


<div style="height:300px;">
    <tank-seamless-scroll :step-length="25" :debug="true" :reverse="false">
        <div class="demo">
            <div v-for="i in 2" :key="i">測試{{ i }}</div>
        </div>
    </tank-seamless-scroll>
</div>

git 倉庫

https://github.com/curry-trooper/tank-vue3-seamless-scroll

效果展示

造輪子的過程

渲染問題

首先我們要考慮基於fps幀渲染的,那麼我們必定會優先考慮 requestAnimationFrame 對象,爲快速解決問題,我們使用了d3-timer 插件,默認幀率限制在了(1000/32)ms,也就是32幀。

性能

偏移量更新採用了js設置 css3 3d 模式,保證了性能可利用

ref_warp.value.style.setProperty("transform", `translate3d(0px ,${translateY}px,0px)`)

顯示分析

有限複製

複製的目的是爲解決連續滾動時,當超出當前容器,繼續可視連續的滾動畫面,這就預示着我們至少需要×3容器容納倍數的內容,才能實現無縫滾動,爲了提高性能,最後決定最多把這個數字限定爲3,考慮到內容高度有可能小於或大於容器高度,所以引出了以下公式:

  • 複製總量 = 向上四捨五入(容器高度/ 內容高度) ×3 PS:
  • 越小的內容複製數量越多,越大的內容填充數量越少,目的只是爲了避免視覺白屏的閃爍
  • 無限複製會降低開發難度,但是vue組件無限複製性能問題無法解決,dom複製,無法繼承源內容的事件熟悉

限定位Y

當畫面滾動到第三頁時,若繼續滾動,則畫面會出現空白內容,因爲沒有第四頁了,所以我們要把第二頁的最後一個內容底座標作爲限定位Y,可理解爲最終一直循環播放第一頁2th內容塊到第三頁倒數第二個內容塊之間內容,但用戶是無感知的。

位置計算公式

如果Y軸偏移量大於限定位Y 則需要重新恢復到首個內容塊 + 取偏移餘Y的位置,進行循環滾動 偏移Y = 偏移Y<限定位Y?符號*(絕對值(偏移Y%內容高度)+內容高度):偏移Y

補充

  • 插件增加了debug模式,開啓後會實時顯示幀率、偏移量、複製總量
  • 插件增加了反向滾動模式,需要開啓 reverse 模式
  • 插件增加了滾動步長速度控制,需要配置 step-length ,該屬性值 代表:Y軸偏移量 (像素/秒)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章