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事件来做到懒加载。

相关推荐
dreams_dream1 天前
vue中axios与fetch比较
前端·javascript·vue.js
沐怡旸1 天前
【底层机制】右值引用是什么?为什么要引入右值引用?
c++·面试
梦鱼1 天前
Vue 项目图标一把梭:Iconify 自用小记(含 TS/JS 双版本组件)
前端·javascript·vue.js
给月亮点灯|1 天前
Vue基础知识-脚手架开发-初始化目录解析
前端·javascript·vue.js
周小码1 天前
CesiumJS详解:打造专业级Web 3D地球仪与地图的JavaScript库
前端·javascript·3d
前端小巷子1 天前
JS 打造丝滑手风琴
前端·javascript·面试
程序员清风1 天前
贝壳一面:年轻代回收频率太高,如何定位?
java·后端·面试
Mintopia1 天前
多模态 AIGC 在 Web 内容创作中的技术融合实践:把“创作引擎”装进浏览器
前端·javascript·aigc
Mintopia1 天前
Next.js 的 Web Vitals 监测与 Lighthouse 分析:从底层到实战的快乐科学
前端·javascript·next.js
一枚前端小能手1 天前
「周更第2期」实用JS库推荐:Rsbuild
前端·javascript