首页 > 其他分享 >7.如何在保证页面运行流畅的情况下处理海量数据

7.如何在保证页面运行流畅的情况下处理海量数据

时间:2023-03-04 20:55:06浏览次数:57  
标签:流畅 渲染 海量 列表 let FPS 屏幕 setTimeout 页面

一般有两种做法

1.时间分片

setTimeout是宏任务,先执行完所有的微任务,才会触发渲染线程对页面进行渲染,

而setTimeout的触发时间是渲染完成,在下一次eventloop中执行的。

 

 

 根据以上两次log,js运算并不是性能的瓶颈,瓶颈主要在渲染阶段。

怎么办呢?

使用定时器,在这里,我们使用setTimeout来实现分批渲染

前置知识:

FPS表示的是每秒钟画面更新次数。我们平时所看到的连续画面都是由一幅幅静止画面组成的,每幅画面称为一FPS是描述变化速度的物理量。

大多数电脑显示器的刷新频率是60Hz,大概相当于每秒钟重绘60次,FPS为60frame/s,为这个值的设定受屏幕分辨率、屏幕尺寸和显卡的影响。

  • 帧率能够达到 50 ~ 60 FPS 的动画将会相当流畅,让人倍感舒适;
  • 帧率在 30 ~ 50 FPS 之间的动画,因各人敏感程度不同,舒适度因人而异;
  • 帧率在 30 FPS 以下的动画,让人感觉到明显的卡顿和不适感;
  • 帧率波动很大的动画,亦会使人感觉到卡顿。
简单聊一下 setTimeout 和闪屏现setTimeout的执行时间并不是确定的。在JS中,setTimeout任务被放进事件队列中,只有主线程执行完才会去检查事件队列中的任务是否需要执行,因此setTimeout的实际执行时间可能会比其设定的时间晚一些。刷新频率受屏幕分辨率和屏幕尺寸的影响,因此不同设备的刷新频率可能会不同,而setTimeout只能设置一个固定时间间隔,这个时间不一定和屏幕的刷新时间相同。以上两种情况都会导致setTimeout的执行步调和屏幕的刷新步调不一致。

setTimeout中对dom进行操作,必须要等到屏幕下次绘制时才能更新到屏幕上,如果两者步调不一致,就可能导致中间某一帧的操作被跨越过去,而直接更新下一帧的元素,从而导致丢帧现象。

因此使用requestAnimationFrame

setTimeout相比,requestAnimationFrame最大的优势是由系统来决定回调函数的执行时机。

//需要插入的容器
let ul = document.getElementById('container');
// 插入十万条数据
let total = 100000;
// 一次插入 20 条
let once = 20;
//总页数
let page = total/once
//每条记录的索引
let index = 0;
//循环加载数据
function loop(curTotal,curIndex){
    if(curTotal <= 0){
        return false;
    }
    //每页多少条
    let pageCount = Math.min(curTotal , once);
    window.requestAnimationFrame(function(){
        for(let i = 0; i < pageCount; i++){
            let li = document.createElement('li');
            li.innerText = curIndex + i + ' : ' + ~~(Math.random() * total)
            ul.appendChild(li)
        }
        loop(curTotal - pageCount,curIndex + pageCount)
    })
}
loop(total,index);

再优化的话,使用DocumentFragment

DocumentFragment,文档片段接口,表示一个没有父级文件的最小文档对象。它被作为一个轻量版的Document使用,用于存储已排好版的或尚未打理好格式的XML片段。最大的区别是因为DocumentFragment不是真实DOM树的一部分,它的变化不会触发DOM树的(重新渲染) ,且不会导致性能等问题。
可以使用document.createDocumentFragment方法或者构造函数来创建一个空的DocumentFragment

2.虚拟列表

虚拟列表其实是按需显示的一种实现,即只对可见区域进行渲染,对非可见区域中的数据不渲染或部分渲染的技术,从而达到极高的渲染性能。

实现

虚拟列表的实现,实际上就是在首屏加载的时候,只加载可视区域内需要的列表项,当滚动发生时,动态通过计算获得可视区域内的列表项,并将非可视区域内存在的列表项删除。

  • 计算当前可视区域起始数据索引(startIndex)
  • 计算当前可视区域结束数据索引(endIndex)
  • 计算当前可视区域的数据,并渲染到页面中
  • 计算startIndex对应的数据在整个列表中的偏移位置startOffset并设置到列表上

 

 

有图片怎么办?

那就使用ResizeObserver

 

标签:流畅,渲染,海量,列表,let,FPS,屏幕,setTimeout,页面
From: https://www.cnblogs.com/alwaysrun/p/17179095.html

相关文章

  • 记录--在Vue3这样子写页面更快更高效
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助前言在开发管理后台过程中,一定会遇到不少了增删改查页面,而这些页面的逻辑大多都是相同的,如获取列表数据,分......
  • 从输入URL到Web页面呈现的全过程
    当用户在浏览器的地址栏中输入URL并点击回车后,页面是如何呈现的。简单来说,当用户在浏览器的地址栏中输入URL并点击回车后,浏览器从服务端获取资源,然后将内容显示在页面......
  • 微信小程序组件页面方法
    //组件使用Component声明Component({//properties:用来接收父组件传递的内容,类似vue中propsproperties:{title:{type:String,value:'默认......
  • js如何准确获取当前页面url网址信息
    在WEB开发中,时常会用到javascript来获取当前页面的url网址信息,在这里是我的一些获取url信息的小总结。下面我们举例一个URL,然后获得它的各个组成部分:http://i.jb51.net/Ed......
  • vue获取不到页面图片实际宽高
    在某些情况下需要页面图片的宽高,使用Image获取加载图片获取图片宽高时为0,是因为图片未加载完返回宽高为0如果未获取到宽高需要使用定时器定时获取图片,直到获取到后再清除......
  • vue实现app页面切换效果
    pageAninmatevue-router实现webApp切换效果快速集成1.复制PageTransittion.vue到项目目录。2.修改router配置。Router.prototype.goBack=function(){this.isB......
  • 使用 CSS 实现页面加载的淡入效果
    可以使用CSS过渡让文本段落在页面加载时淡入吗?我真的很喜欢它在http://dotmailapp.com/上的样子,并且很想使用CSS来使用类似的效果。该域名已被购买,不再具有提及的......
  • Servlet-thymeleaf入门与渲染index页面
    资料来源于:B站尚硅谷JavaWeb教程(全新技术栈,全程实战),本人才疏学浅,记录笔记以供日后回顾由于是多个视频内容混合在一起,因此只放了第一个链接视频链接知识点Thymel......
  • 登录页面练习
    主页面1<?xmlversion="1.0"encoding="utf-8"?>2<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"3android:layout_width="m......
  • web页面设计核心
    段落语言组织字体大小颜色粗细与斜体行距阴影div大小圆角背景色背景图边框阴影渐变线长度颜色弹出框headerbodyfooter其他复合组件多选框单选框下拉框lo......