不要再回答使用分頁或者文檔碎片了
回答分頁 ,不是很貼切考官的問題疲扎,考官也不會想聽到這樣的答案昵时,
第二 ,文檔碎片 椒丧,這是使用js 操作dom 的時候需要用到壹甥,需要動態(tài)生成原生dom,在vue的項目里使用比較不方便壶熏。能回答到這個勉強可以句柠。
我推薦的是:window.requestAnimationFrame
requestAnimationFrame
是HTML5中提供的動畫API,簡稱rAF棒假,即請求動畫幀溯职。可以讓瀏覽器優(yōu)化并行的動畫動作帽哑,更合理的重新排列動作序列谜酒,并把能夠合并的動作放在一個渲染周期內(nèi)完成,從而呈現(xiàn)出更流暢的動畫效果妻枕。
瀏覽器每次渲染一秒鐘渲染60次 1000ms/60s , 即 每毫秒16.6次 僻族。
當我們頁面的數(shù)據(jù)超級多的時候,一次性就渲染全部的數(shù)據(jù)屡谐,就會造成頁面卡頓
我們來看下一個例子:
image.png
右邊是渲染的dom 每個div盒子里面包含了n個div塊述么,數(shù)量其實并不多。但是等待頁面卻花了十秒鐘的時間
通過性能調(diào)試面板可以看到 瀏覽器裝載只需要1毫秒 執(zhí)行js 腳本花了 5秒多 愕掏,渲染也花了四秒多碉输,總計 10秒左右。
image.png
看看代碼如何寫的亭珍,可以看到就是嵌套了兩個循環(huán)一個 ,兩個循環(huán)一百次 枝哄,總的差不多是百萬循環(huán)了肄梨,js一次性就加載,是需要十秒挠锥,這個時候瀏覽器是一直白屏的众羡,需要等待差不多九秒,頁面才出來東西
image.png
看看使用了 requestAnimationFrame
優(yōu)化之后 前后對比蓖租,速度不是一般的快.
實際上就是 瀏覽器分開渲染羊壹,n毫秒內(nèi)渲染前面幾個div盒子。一直在渲染齐婴,直到渲染完畢。相當是把十秒鐘拆分成每一秒渲染前多少個div情妖,以此類推。這樣用戶一進來就能看到前半段的東西诱担,剩余的瀏覽器會慢慢加載毡证,并不會影響前面的顯示,這樣一樣來就能解決這種性能的問題蔫仙,也不會影響用戶體驗。
image.png
完整的代碼示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>defer</title>
<style>
* {
margin: 0;
padding: 0;
}
.box {
width: 100vw;
height: 100vh;
display: flex;
flex-wrap: wrap;
}
.block {
width: 400px;
margin: 20px;
height: 400px;
border: 1px solid red;
display: flex;
flex-wrap: wrap;
}
.item {
width: 6px;
height: 6px;
background: #000;
margin: 1px;
}
</style>
</head>
<body>
<div id="app" class="box">
<template v-for="(item,index) in 1000">
<!-- 默認顯示優(yōu)化后的代碼 -->
<!-- 使用沒有用requestAnimationFrame優(yōu)化之前的渲染代碼可以將v-if="defer(index)" 刪掉即可 -->
<div class="block" v-if="defer(index)">
<div class="item" v-for="(sub,index) in 1000"></div>
</div>
</template>
</div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.2.6/vue.js"></script>
<script>
new Vue({
el: '#app',
data() {
return {
frameCount: 0,
}
},
mounted() {
const refreshFrameCount = (maxFrameCount) => {
requestAnimationFrame(() => {
this.frameCount++
if (this.frameCount < maxFrameCount) {
refreshFrameCount(maxFrameCount)
}
})
}
refreshFrameCount(500)
},
methods: {
defer(showInFrameCount) {
return this.frameCount >= showInFrameCount
}
}
})
</script>
</html>