当前位置: 首页 > article >正文

JavaScript 第17章:性能优化

在JavaScript第17章中讨论的性能优化是一个重要的主题,因为它直接影响到Web应用的表现。下面是一些关键点以及如何进行性能优化的方法。

性能度量:性能监控工具

工具
  • 浏览器开发者工具(如Chrome DevTools)中的Performance面板可以用来记录页面加载时间和各个资源加载的时间。
  • Lighthouse 是一个开源的自动化工具,可以审计网页并提供改进建议。
  • WebPageTest 允许你在不同的浏览器和网络条件下测试网站性能。
指标
  • First Contentful Paint (FCP) - 页面上首次绘制内容的时间。
  • Largest Contentful Paint (LCP) - 大型内容元素渲染完成的时间,是衡量首屏加载的关键指标。
  • First Input Delay (FID) - 用户首次与页面交互的时间延迟。
  • Cumulative Layout Shift (CLS) - 页面布局变化的累积分数,用于评估页面稳定性。

代码优化:减少DOM操作、避免重绘与回流

技巧
  • 批量操作 - 将多个DOM操作组合在一起,使用DocumentFragment来减少重绘。
  • 使用requestAnimationFrame - 对于动画效果,使用requestAnimationFrame代替setTimeout或setInterval。
  • 事件委托 - 使用事件委托来减少事件监听器的数量。
  • 属性优化 - 避免修改style属性,而是使用CSS类来控制样式更改。

资源加载优化:懒加载、图片优化

方法
  • 懒加载 - 只有当元素进入视口时才加载图片或其他资源。
  • 使用WebP格式 - WebP是一种现代图像格式,可以在保持高质量的同时减小文件大小。
  • 图片尺寸匹配 - 确保图片尺寸与显示尺寸相匹配,避免不必要的下载和缩放。

首屏加载时间优化:预加载、关键CSS

措施
  • 预加载 - 使用<link rel="preload">来提前加载关键资源。
  • 关键CSS - 提取首屏所需CSS,将其内联在HTML文档中,避免额外的HTTP请求。

实战案例:性能优化策略的应用

示例
  • 电商网站 - 通过将首页的图片设置为懒加载,并且只加载用户当前浏览区域内的图片,可以显著提高首页的加载速度。
  • 博客平台 - 通过提取关键CSS,并将非关键部分的CSS异步加载,可以加速首屏内容的显示时间。
  • 在线视频播放器 - 利用requestAnimationFrame优化视频播放的流畅性,并通过懒加载技术加载视频中的广告或推荐内容。

性能优化是一个持续的过程,需要不断地测试、分析和调整。了解你的用户群体和他们的网络环境可以帮助你做出更明智的决策。同时,随着Web技术的发展,新的工具和技术也会不断出现,所以保持学习和实践是非常重要的。

代码优化:减少DOM操作、避免重绘与回流

减少DOM操作

当你需要频繁地更新DOM时,可以先创建一个DocumentFragment,然后将所有的DOM变动都添加到这个片段中,最后一次性将它添加到DOM树中。

function updateDom() {
    const fragment = document.createDocumentFragment();
    for (let i = 0; i < 1000; i++) {
        const div = document.createElement('div');
        div.textContent = `Item ${i}`;
        fragment.appendChild(div);
    }
    document.body.appendChild(fragment);
}
避免重绘与回流

尽量避免在循环中修改DOM元素的样式或结构,因为这会导致浏览器进行多次重绘和回流。

// 不好的做法
function badPractice() {
    const div = document.getElementById('myDiv');
    for (let i = 0; i < 100; i++) {
        div.style.backgroundColor = 'red';
        div.style.backgroundColor = 'blue';
    }
}

// 好的做法
function goodPractice() {
    const div = document.getElementById('myDiv');
    div.classList.add('red');
    div.classList.remove('blue');
}

资源加载优化:懒加载、图片优化

图片懒加载

使用 Intersection Observer API 来检测图片何时进入可视区,只有当图片进入可视区时才加载它们。

<img src="placeholder.png" data-src="real-image.jpg" class="lazy"/>

<script>
document.addEventListener('DOMContentLoaded', () => {
    const images = document.querySelectorAll('.lazy');
    const observer = new IntersectionObserver(entries => {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                entry.target.src = entry.target.dataset.src;
                observer.unobserve(entry.target); // 停止观察已经加载的图片
            }
        });
    }, {threshold: 0.5});

    images.forEach(img => observer.observe(img));
});
</script>

首屏加载时间优化:预加载、关键CSS

关键CSS

将首屏需要的CSS内联到HTML中,避免额外的HTTP请求。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>关键CSS示例</title>
<style>
    .main {
        /* 这里放置首屏需要的关键CSS */
        background-color: #f4f4f4;
        padding: 10px;
    }
</style>
</head>
<body>
<div class="main">
    <!-- 页面内容 -->
</div>
<!-- 非关键CSS异步加载 -->
<link rel="stylesheet" href="styles.css" onload="this.rel='preload'; this.οnlοad=null;">
</body>
</html>
预加载

使用<link rel="preload">来告诉浏览器提前加载重要的资源。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Preload Example</title>
<link rel="preload" href="styles.css" as="style" onload="this.rel='stylesheet'">
</head>
<body>
<!-- 页面内容 -->
</body>
</html>

这些示例展示了如何通过不同的技术来优化JavaScript应用程序的性能。实际应用中,可能需要根据具体情况调整代码逻辑和优化策略。

当然,让我们继续探讨更多的性能优化技巧,并结合具体的源代码示例。

实战案例:性能优化策略的应用

1. 动画优化

问题:动画卡顿,尤其是在移动设备上。

解决方案:使用requestAnimationFrame代替setTimeoutsetInterval,并且尽可能利用硬件加速。

function animate(element, duration, targetPosition) {
    let start = null;
    function step(timestamp) {
        if (!start) start = timestamp;
        const progress = Math.min(1, (timestamp - start) / duration);
        element.style.transform = `translateX(${progress * targetPosition}px)`;
        if (progress < 1) {
            requestAnimationFrame(step);
        }
    }
    requestAnimationFrame(step);
}

const box = document.getElementById('box');
animate(box, 2000, 200);

在这个例子中,我们使用了requestAnimationFrame来确保动画帧是在屏幕刷新周期之间执行,从而获得更平滑的动画效果。

2. 事件处理优化

问题:大量的事件监听器导致性能下降。

解决方案:使用事件委托来减少事件监听器的数量。

<ul id="list">
    <li data-id="1">Item 1</li>
    <li data-id="2">Item 2</li>
    <!-- 更多列表项 -->
</ul>

<script>
document.getElementById('list').addEventListener('click', event => {
    if (event.target.tagName === 'LI') {
        const id = event.target.getAttribute('data-id');
        console.log(`Clicked on item with ID: ${id}`);
    }
});
</script>

在这个例子中,我们不是给每个列表项单独添加事件监听器,而是给包含所有列表项的容器添加了一个监听器,并检查事件的目标元素是否是我们关心的类型。

3. CSS 优化

问题:过多的CSS选择器计算导致重绘和回流。

解决方案:简化选择器,尽量使用类名而不是ID或标签名。

/* 不好 */
#content .list li.active {
    color: red;
}

/* 好 */
.list-item.active {
    color: red;
}

在CSS中,尽量避免使用过于复杂的嵌套选择器,并使用类名来标识状态或样式,这样可以减少浏览器计算样式规则的时间。

4. 数据处理优化

问题:大数据集处理导致页面卡顿。

解决方案:使用Web Workers来处理数据,避免阻塞主线程。

// main.js
if (window.Worker) {
    const worker = new Worker('worker.js');
    worker.postMessage([1, 2, 3, 4, 5]); // 发送数据到Worker
    worker.onmessage = function(event) {
        console.log('Received:', event.data);
    };
} else {
    console.error('Web Workers are not supported in this browser.');
}

// worker.js
self.onmessage = function(event) {
    const result = event.data.map(x => x * 2);
    postMessage(result); // 发送结果回主线程
};

在这个例子中,我们使用Web Workers来处理复杂的数据操作,从而释放主线程进行UI渲染和其他任务。


http://www.kler.cn/news/355511.html

相关文章:

  • Chapter09
  • perl替换文件中的特定内容
  • 海南聚广众达电子商务咨询有限公司靠谱吗怎么样?
  • Uptime Kuma: 全面的开源网站监控解决方案
  • 青少年编程能力等级测评CPA C++(二级)试卷(2)
  • JavaScript的第三天
  • VSCode C/C++跳转到定义、自动补全、悬停提示突然失效
  • Rocky Linux 9安装Asterisk 20和freepbx 17脚本——筑梦之路
  • Rust各个方面完胜C++吗?
  • Threejs 实现3D 地图(01)创建基本场景
  • Parameter-Efficient Fine-Tuning for Large Models: A Comprehensive Survey阅读笔记
  • LeetCode1658.将x减到0的最小操作数
  • PHP爬虫API:获取商品详情的新利器
  • uniapp uni.uploadFile errMsg: “uploadFile:fail
  • PTA L1系列题解(C语言)(L1_073 -- L1_080)
  • php常用设计模式之单例模式
  • HikariPool连接池报错(Possibly consider using a shorter maxLifetime value)
  • 健康推荐新动力:SpringBoot智能系统
  • PostgreSQL与MySQL在语法上的区别
  • 【飞腾加固服务器】全国产化解决方案:飞腾FT2000+/64核,赋能关键任务保驾护航