不要再回答使用分页或者文档碎片了
回答分页 ,不是很贴切考官的问题,考官也不会想听到这样的答案,
第二 ,文档碎片 ,这是使用js 操作dom 的时候需要用到,需要动态生成原生dom,在vue的项目里使用比较不方便。能回答到这个勉强可以。
我推荐的是:window.requestAnimationFrame
requestAnimationFrame
是HTML5中提供的动画API,简称rAF,即请求动画帧。可以让浏览器优化并行的动画动作,更合理的重新排列动作序列,并把能够合并的动作放在一个渲染周期内完成,从而呈现出更流畅的动画效果。
浏览器每次渲染一秒钟渲染60次 1000ms/60s , 即 每毫秒16.6次 。
当我们页面的数据超级多的时候,一次性就渲染全部的数据,就会造成页面卡顿
我们来看下一个例子:
右边是渲染的dom 每个div盒子里面包含了n个div块,数量其实并不多。但是等待页面却花了十秒钟的时间
通过性能调试面板可以看到 浏览器装载只需要1毫秒 执行js 脚本花了 5秒多 ,渲染也花了四秒多,总计 10秒左右。
看看代码如何写的,可以看到就是嵌套了两个循环一个 ,两个循环一百次 ,总的差不多是百万循环了,js一次性就加载,是需要十秒,这个时候浏览器是一直白屏的,需要等待差不多九秒,页面才出来东西
看看使用了 requestAnimationFrame
优化之后 前后对比,速度不是一般的快.
实际上就是 浏览器分开渲染,n毫秒内渲染前面几个div盒子。一直在渲染,直到渲染完毕。相当是把十秒钟拆分成每一秒渲染前多少个div,以此类推。这样用户一进来就能看到前半段的东西,剩余的浏览器会慢慢加载,并不会影响前面的显示,这样一样来就能解决这种性能的问题,也不会影响用户体验。
完整的代码示例
<!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">
<!-- 默认显示优化后的代码 -->
<!-- 使用没有用requestAnimationFrame优化之前的渲染代码可以将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>