前端优化之快速响应用户界面(一)

我们在写一个网页的时候,可能会遇到这种情况,当数据过多的时候,可能会阻塞UI的渲染,导致给我们一种视觉感受,页面空白时间太长,这种情况怎么处理呢?

浏览器UI线程

用于执行javascript和更新用户界面的进程通常被称为“浏览器UI线程”。UI线程基于队列,任务会保存在队列中,直到队列空闲。一旦空闲,队列中的下一个任务就会被提出来执行,这些任务要么是js代码,要么是UI更新,然而我们每输入一个字符都可能会导致一个或多个任务加入队列。

// html
<button onclick="handle()">点击</button>
// js
function handle(){
    let div = document.createElement('div');
    div.innerHTML = '你好啊';
    document.body.appendChild(div)
}
复制代码

在点击按钮的时候,会触发UI线程来创建两个任务添加到对列中:更新按钮的UI,表示按钮被点击了;执行js。

会在UI线程空闲的时候将第一个任务取出来更新UI,然后,js任务被提取出来执行,在js这段代码中,创建了元素,并把他添加到界面中,这就表明页面需要更新,所以会在队列中添加一个任务,更新UI,在js运行完成后,更新UI

这就意味着我们要等待js运行完成才可以更新UI,如果js要运行很长时间,那么页面就会出现空白状态

解决办法----善于使用定时器

  • 先来看一个例子
let arr = new Array(1000);
for(let i = 0; i < arr.length; i++) {
    let p = document.createElement('p');
    p.innerHTML = i + 1;
    document.body.appendChild(p)
}
复制代码

在这个例子中,创建一个长度为1000的数组,循环数组,在循环的时候我们创建元素并添加到页面中,但浏览器并不是按顺序执行的,他会先循环1000次,循环完成以后,才会添加元素到页面上(如果不信可以在浏览器中跑一下,在控制台看一下元素什么时候会被添加到页面上,是不是一次性添加到页面上)

  • 再看另一种方法
let todo = arr.concat(); //克隆数组
function renderArray() {
    // 从数组中拿出第一个
    let task = todo.shift()
    setTimeout(function() {
        let p = document.createElement('p');
        p.innerHTML = todo.length;
        document.body.appendChild(p)
        if(todo.length > 0) {
            setTimeout(arguments.callee, 25)
        }
    },25)
}
renderArray()
复制代码

虽然写的代码比上边的多,但是你可以在浏览器中看出来,并不是在最后一次行渲染出来的,而是一条一条的渲染出来的

基本思路
  • 创建一个数组的克隆,并将它作为数组队列来处理
  • 第一次调用setTimeout创建一个定时器处理数组中的第一个条目,处理完成后判断还有没有条目需要处理,如果有的话就重新启动一个定时器
  • 因为下一个定时器要运行同样的代码,所以第一个参数为arguments.callee,只想当前正在运行的函数。

为什么要用定时器

  • 定时器可以用来将耗时较长的脚本拆分成较短的片段
  • 用定时器会告诉javascript引擎先等待一段时间,然后添加一个javascript任务到UI队列中
  • 第二个参数表示什么时候被添加到队列中,而不是在这个时候立即执行,他会在队列中其他任务执行完毕才会执行

你们担心的问题在这里

定时器与性能

  • 定时器过度使用可能会对性能产生影响,BUT: 在我们写的这个定时器中,同一时间只有一个定时器存在,当这个定时器结束时才会重新创建一个,所以不会到值性能问题

转载于:https://juejin.im/post/5bdbefa151882516d85b345b

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值