JS考题-你给我渲染一百万条数据(拿捏面试官版)

首先,当我们要同时渲染大量的数据,例如我用一个for循环去给一个节点增加十万条子项,并打印出时间如下:

js 复制代码
let start = new Date();
for (let i = 0; i < total; i++) {
  let li = document.createElement('li');
  li.innerText = i;
  ul.appendChild(li)
}
let end = new Date();
console.log(start-end)

但是这样打印时间是不对的,因为这打印出的只是主线程执行的时间,我们的页面还得进行渲染。

这是由于事件循环机制,页面渲染通常发生在微任务完成后。我们事件循环的机制是这样的(引导面试官问事件循环): 1.Script主线程 2.清空微任务队列 3.执行渲染 4.执行宏任务中的一个任务,并进入下一轮事件循环。

我们的渲染发生在主线程之后,所以我们应该在宏任务中完成定时。

js 复制代码
let start = new Date();
for (let i = 0; i < total; i++) {
  let li = document.createElement('li');
  li.innerText = i;
  ul.appendChild(li)
}
let end = new Date();
settimeout(() = > console.log(start-end),0)

我通过浏览器的performance工具(展示实力)查看之后发现,主要是页面的计算样式和渲染占据的时间长(引导面试官问渲染相关知识)。

造成了页面的卡顿,因为js交互为宏任务,无法继续循环。并且一次性渲染过多数据,页面渲染时间长。

因此我们采用分批次递归加入宏任务队列的方法,这样js事件也能从中间穿插,用户仍然能进行交互。

js 复制代码
        let ul = document.getElementById('container');
        let total = 100000;
        let once = 20;
        let times = Math.ceil(total / once);
        let index = 0;
        function render() {
            for (let i = 0; i < once; i++) {
                let li = document.createElement('li');
                li.innerText = 1;
                ul.appendChild(li);
            }
        }
        function loop() {
            setTimeout(() => {
                render();
                index++;
                if (index < times) {
                    loop();
                }
            }, 0); 
        }
        loop();

但是这时候还有问题,我们的浏览器刷新页面是60帧,也就是将近16.7ms每次,但是 某部分行为,例如查看滚动位置,(详情看我之前的文章事件循环)。这时候会立即的执行一次渲染。因为他要获取准确的计算结果。这种情况会造成大量的重排,就会引起卡顿。

这时候可以利用 嵌套 requestAnimationFrame 函数,避免中间渲染。提高浏览器的性能。 当嵌套 requestAnimationFrame 函数时候,他会在每帧前执行

或者我们也可以通过懒加载的方式,监听用户的onScreen事件来做到懒加载。

相关推荐
烛阴1 小时前
精简之道:TypeScript 参数属性 (Parameter Properties) 详解
前端·javascript·typescript
开发者小天2 小时前
为什么 /deep/ 现在不推荐使用?
前端·javascript·node.js
恋喵大鲤鱼2 小时前
Golang 后台技术面试套题 1
面试·golang
why技术2 小时前
也是震惊到我了!家里有密码锁的注意了,这真不是 BUG,是 feature。
后端·面试
找不到工作的菜鸟4 小时前
Three.js三大组件:场景(Scene)、相机(Camera)、渲染器(Renderer)
前端·javascript·html
定栓4 小时前
vue3入门-v-model、ref和reactive讲解
前端·javascript·vue.js
binqian5 小时前
【异步】js中异步的实现方式 async await /Promise / Generator
开发语言·前端·javascript
前端李二牛5 小时前
异步任务并发控制
前端·javascript
你也向往长安城吗6 小时前
推荐一个三维导航库:three-pathfinding-3d
javascript·算法
karrigan6 小时前
async/await 的优雅外衣下:Generator 的核心原理与 JavaScript 执行引擎的精细管理
javascript