软件教程 2025年08月6日
0 收藏 0 点赞 498 浏览 2356 个字
摘要 :

文章目录 一、懒加载 二、延迟加载 requestAnimationFrame requestIdleCallback setTimeout 三、虚拟加载 四、canvas渲染 五、异步分片 前端开发中,大数据量场景较……




  • 一、懒加载
  • 二、延迟加载
    • requestAnimationFrame
    • requestIdleCallback
    • setTimeout
  • 三、虚拟加载
  • 四、canvas渲染
  • 五、异步分片

前端开发中,大数据量场景较为常见,若处理不当,会严重影响用户体验。为提升用户使用感受,可从接口层、数据层、渲染层等多方面进行优化。本文主要讲解关于渲染层优化,探讨多种优化方式。

一、懒加载

懒加载的原理是在初始化时仅渲染首屏数据,当用户滚动页面时,再逐步渲染额外数据。这种方式的优势在于能显著加快首屏加载速度,让用户快速看到页面主体内容。不过,它也存在一些弊端。随着用户持续滚动页面,真实DOM元素会不断增加,导致内存占用越来越大。而且,当用户滚动速度过快时,页面可能出现白屏现象,影响用户体验。

二、延迟加载

延迟加载与懒加载有所不同。它是在首屏正常渲染完成后,通过异步方式渲染页面的其他部分。为确保异步渲染不会干扰用户交互,通常会借助requestAnimationFramerequestIdleCallbacksetTimeout等方法。下面对这几种方法的特性进行详细分析:

requestAnimationFrame

  • 优点:该方法由浏览器进行优化,每帧会执行一次,能保证动画流畅,不会出现丢帧情况。而且,当页面处于非激活状态时,动画会自动暂停,节省系统资源。
  • 缺点:它无法设置执行时间间隔,动画的开始和取消都需要手动控制,并且在兼容性方面不如setTimeout

requestIdleCallback

  • 优点:会在浏览器空闲时执行任务,不会对用户交互和动画产生影响,同时还能设置超时时间。
  • 缺点:兼容性较差,执行时机难以控制,甚至有可能永远不会执行。

setTimeout

  • 优点:使用方法简单,兼容性良好,可灵活设置延迟时间。
  • 缺点:执行精度不高,容易导致丢帧,在嵌套调用时还可能引发调用栈溢出问题。

延迟加载在很大程度上解决了懒加载存在的一些问题,但它也有自身的不足,比如一开始就会占用较大内存。

三、虚拟加载

虚拟加载技术的核心是,无论用户滚动到页面的哪个位置,都仅渲染用户可视区域内的内容。这样做的好处是,页面中的真实DOM元素数量较少,内存占用固定且相对较低。然而,它也存在与懒加载类似的问题,当用户滚动速度过快时,同样可能出现白屏现象。

四、canvas渲染

canvas渲染是一种较为特殊的优化方式,它直接摒弃了传统的真实DOM渲染方式。使用canvas进行渲染,性能非常强劲,渲染速度极快。不过,这种方式的实现过程异常复杂,对开发者的技术能力要求较高。

五、异步分片

在面对大量真实DOM渲染或者canvas形式的渲染任务时,可以将其拆分成多个渲染子任务。以canvas渲染为例,可以拆分成多个栅格,进而形成多个渲染子任务。由于JavaScript是单线程运行,如果一次性执行所有这些子任务队列,会导致线程卡顿。因此,需要合理控制每一帧中执行子任务的时间。比如,每一帧时间为16ms,可以分配10ms来执行子任务,剩余6ms用于响应用户交互,这样就能有效避免JavaScript单线程卡顿。下面通过代码示例来进一步理解异步分片的实现原理:

// 模拟一个耗时任务队列
// 这里创建了一个包含10000个任务的数组,每个任务都是一个函数
// 每个函数内部通过循环计算随机数之和来模拟任务执行
const tasks = new Array(10000).fill(0).map((_, index) => () => {
    // 模拟每个任务的执行
    let result = 0;
    for (let i = 0; i < 10000; i++) {
        result += Math.random();
    }
    console.log(`完成任务 ${index}`);
});

// TimeSliceExecutor类用于管理任务队列的执行
class TimeSliceExecutor {
    constructor(tasks) {
        // 接收外部传入的任务队列
        this.tasks = tasks;
        // 设置每帧分配10ms执行任务
        this.timeLimit = 10; 
    }

    // 执行任务队列的方法
    execute() {
        // 如果任务队列已空,说明所有任务执行完成,打印提示信息并返回
        if (this.tasks.length === 0) {
            console.log(\'所有任务执行完成\');
            return;
        }

        // 获取当前时间,用于记录任务执行开始时间
        const startTime = performance.now();

        // 循环执行任务,直到任务队列空或者达到时间限制
        while (this.tasks.length > 0) {
            // 检查是否超过当前帧的时间限制
            if (performance.now() - startTime > this.timeLimit) {
                // 超过时间限制,在下一帧继续执行
                requestAnimationFrame(() => this.execute());
                break;
            }

            // 从任务队列中取出一个任务并执行
            const task = this.tasks.shift();
            task();
        }
    }

    // 开始执行任务队列的方法
    start() {
        // 通过requestAnimationFrame启动任务执行
        requestAnimationFrame(() => this.execute());
    }
}

// 使用示例
// 创建TimeSliceExecutor实例并传入任务队列
const executor = new TimeSliceExecutor(tasks);
// 启动任务执行
executor.start();

在前端大数据量场景下,渲染层的优化中懒加载、延迟加载、虚拟加载、canvas渲染以及异步分片等技术各有优劣,大家需要根据实际项目需求,选择合适的优化方案,以提升前端性能和用户体验。

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/6869.html

管理员

相关推荐
2025-08-06

文章目录 一、Promise基础回顾 二、Promise 与 axios 结合使用场景及方法 (一)直接返回 axios …

268
2025-08-06

文章目录 一、模块初始化时的内部机制 二、常见导出写法的差异分析 (一)写法一:module.exports…

106
2025-08-06

文章目录 一、ResizeObserver详解 (一)ResizeObserver是什么 (二)ResizeObserver的基本用法 …

682
2025-08-06

文章目录 一、前期准备工作 (一)下载相关文件 (二)安装必要工具 二、处理扣子空间生成的文件…

336
2025-08-06

文章目录 一、官方文档 二、自动解包的数据类型 ref对象:无需.value即可访问 reactive对象:保持…

369
2025-08-06

文章目录 一、Hooks的工作原理 二、在if语句中使用Hook会出什么岔子? 三、React官方的Hook使用规…

842
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号