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

相关推荐
海绵宝龙8 分钟前
Vue中nextTick
前端·javascript·vue.js
三川69818 分钟前
面试题目记录
面试·职场和发展
H_z_q240140 分钟前
Web前端制作一个评论发布案例
前端·javascript·css
摘星编程1 小时前
React Native + OpenHarmony:useId唯一标识生成
javascript·react native·react.js
2603_949462101 小时前
Flutter for OpenHarmony社团管理App实战:消息中心实现
android·javascript·flutter
萧曵 丶2 小时前
JavaScript 函数各种写法和场景
开发语言·javascript·ecmascript
Yolanda943 小时前
【项目经验】钉钉免密登录实现
前端·javascript·钉钉
摘星编程3 小时前
在OpenHarmony上用React Native:collapsable节点优化策略
javascript·react native·react.js
Beginner x_u3 小时前
JavaScript 原型、原型链与原型继承的核心机制解析
开发语言·javascript·原型模式·原型原型链
Mr Xu_4 小时前
Vue3 + Element Plus 实战:App 版本管理后台——动态生成下载二维码与封装文件上传
前端·javascript·vue.js