tab切換引起瀏覽器卡頓
最近寫了基於 index 索引關聯進行切換的tab組件,誰知道頻繁點擊后,幾個瀏覽器都卡死,連查看 performance 都看不了。在嘗試幾次后,沒能在 chrome 的 performance下看到原因,因為卡的動不了。反而在 firefox 下看到原因了。
本地代碼業務邏輯大致如下
<!-- tab header -->
<div data-type="one"><button>one</button></div>
<div data-type="two"><button>two</button></div>
<div data-type="three"><button>three</button></div>
<!-- tab content -->
<components :is="type"></components>
通過上面按鈕點擊,動態更改type,從而更新組件。但是由於點擊時,不一定點擊的是 div,有可能是 button,因而無論點擊哪一個都需要找到div,拿到data-type的參數。於是自己便寫了一個查找父元素的function。
function findTargetByClassNameAndTarget (target = {}, className = '') {
let el = target
while (!el.classList.contains(className) && el) {
el = target.parentNode
}
return el
}
初步點擊時,並沒有任何問題,都能及時響應,但是快速頻繁之后就開始。firefox顯示這段js一直在運行。我也是醉了。於是換成了下面這樣的才得以解決。
function closest (ele, selector) {
const matches = ele.matches
|| ele.webkitMatchesSelector
|| ele.mozMatchesSelector
|| ele.msMatchesSelector
if (matches) {
while (ele) {
if (matches.call(ele, selector)) {
return ele
} else {
ele = ele.parentNode
}
}
}
return null
}
思考
之前為了解決上訴問題,以為是頻繁地更新DOM
,導致頁面重繪重排,從而性能有了影響。但是 el-tab
卻沒有。看了下代碼沒有找到明顯的優化之處。然后嘗試給 點擊事件加延遲,component
加 keep-alive
。一樣沒有效果。因而以為是不是使用 v-if
導致的。切換為v-show
進行處理依舊沒有效果。參考網上做法,開啟硬件加速 transform: translateZ(0)
依舊沒有任何效果,反而還引發其他問題(彈框的fixed定位不准)
因為tab切換引起的性能問題,網上有很多,我個人覺得這兩個將來值得借鑒一二,原理都是 dom
更新完再進行。
-
加一個開發,在dom更新完后再進行下一步
<div id="first" v-if="flag"></div> <div id="last" v-else></div> <script> ... function handleTab () { if (this.flag) { first.show() last.hide() this.flag = false } else { first.hide() last.show() this.flag = true } } ... </script>
-
使用
vue
的update
來進行處理。因為updated
也是dom
更新完再執行
針對上面的代碼,嘗試了之前寫的另一種方式
function findElementUpward (el, className) {
let parent = el
let name = Array.from(parent.classList || [])
while (parent && (!name.length || !name.includes(className))) {
parent = parent.parentNode
if (parent) name = Array.from(parent.classList || [])
}
return parent
}
依舊是沒問題。因而對比兩者的差距,只是這次取巧使用了自帶的 contains
這個方法而已,卻沒想到導致這么大的問題。只是目前還無法判斷是不是這個 contains
導致的性能問題。需要找個方式進行研究一下方可。