前端项目性能优化(全面解析)

前端性能优化全解析
本文探讨了为何Web性能优化至关重要,涉及流量增长、转化率和用户体验。Amazon的研究表明延迟100ms可能导致1%的销量损失。文章详细介绍了性能瓶颈识别、测量工具如Chrome DevTools和WebPageTest,以及RAIL模型,强调了加载速度、交互反馈和动画流畅性。还提供了优化模型和具体指标,如SpeedIndex和TTFB,以及如何使用Lighthouse和APIs进行评估和改进。

前言

为什么要进行Web性能优化?

流量

搜索

转换率

用户体验

Amazon 发现每100ms延迟导致1%的销量损失

寻找性能瓶颈

  • 了解性能指标 - 多快才算快
  • 利用测量工具和APIs
  • 优化问题,重新测量(迭代)

性能优化指标和测量工具

行业标准

性能优化-加载
  • 理解加载瀑布图

  • 基于HAR存储于重建性能信息

  • 重要测量指标

  • 速度指数(Speed Index)4秒

  • TTFB 衡量请求到响应一共多少时间

  • 页面加载时间,页面加载完一共要用多久

  • 首次渲染 不能一直是白屏,然后在后来的某一刻突然都出来,要给用户一个渐进的体验,第一次出现内容的时间就是首次渲染很重要,让用户很快感觉到你的网站有内容出现了

性能优化-响应
  • 交互动作的反馈时间 : 交互的反馈要及时
  • 帧率FPS :60fps
  • 异步请求的完成时间:尽量在1秒内完成,完成不了加loading动画

优化模型

RAIL测量模型

什么是RAIL?

Response 响应 : 对于用户的响应

Animation 动画 : 对于用户动画的流畅

Idle 空闲 : 让浏览器有足够的空闲时间

Load 加载 : 给用户一个直观的体验

RAIL的目标

让良好的用户体验成为性能优化的目标

RAIL评估标准

相应:处理事件应在 50ms 以内完成

动画:每 10ms 产生一帧

空闲:尽可能增加空闲时间

加载:在 5s 内完成内容加载并可以交互

测量工具(需要外网)

  • Chrome DevRools 开发调试、性能评测
  • Lighthouse 网站整体质量评估
  • WebPageTest 多测试地点、全面性能报告
使用 WebPageTest 评估Web网站性能

在线进行网站分析

WebPageTest.org

waterfall chart 请求瀑布图

first view 首次访问

repeat view 二次访问

如何在本地部署WebPageTest工具

一、下载docker https://docs.docker.com/docker-for-windows/install/

二、在终端使用官方提供的docker镜像

docker pull webpagetest/server

docker pull webpagetest/agent

三、运行

docker run -d -p 4000:80 webpagetest/server

docker run -d -p 4001:80 --network=“host” -e “SERVER_URL=http://localhost:4000/work” -e “LOCATION=Test” webpagetest/agent

使用LightHouse分析性能

安装

npm install -g lighthouse

使用

lighthouse 加上你要测试的网站地址

在chrome DevTools 中使用

查看该文件有没有被使用 ctrl + shift + p

搜索Show Network request blocking

使用chrome DevTools分析性能

Audit(Lighthouse)

Throttling 调整网络吞吐

Performance 性能分析

Network 网络加载分析

性能相关APIs

常用的性能测量APIs

关键事件节点(Navigation Timing,Resource Timing)

网络状态(Network APIs)

客户端服务端协商(HTTP Client Hints) & 网页显示状态(UI APIs)

重要的时间节点

DNS 解析耗时: domainLookupEnd - domainLookupStart
TCP 连接耗时: connectEnd - connectStart
SSL 安全连接耗时: connectEnd - secureConnectionStart
网络请求耗时 (TTFB): responseStart - requestStart
数据传输耗时: responseEnd - responseStart
DOM 解析耗时: domInteractive - responseEnd
资源加载耗时: loadEventStart - domContentLoadedEventEnd
First Byte时间: responseStart - domainLookupStart
白屏时间: responseEnd - fetchStart
首次可交互时间: domInteractive - fetchStart
DOM Ready 时间: domContentLoadEventEnd - fetchStart
页面完全加载时间: loadEventStart - fetchStart
http 头部大小: transferSize - encodedBodySize
重定向次数:performance.navigation.redirectCount
重定向耗时: redirectEnd - redirectStart
// 计算一些关键的性能指标
window.addEventListener('load', (event) => {
   
   
    // Time to Interactive
    let timing = performance.getEntriesByType('navigation')[0];
    console.log(timing.domInteractive);
    console.log(timing.fetchStart);
    let diff = timing.domInteractive - timing.fetchStart;
    console.log("TTI: " + diff);
})
// 观察长任务
const observer = new PerformanceObserver((list) => {
   
   
    for (const entry of list.getEntries()) {
   
   
        console.log(entry)
    }
})

observer.observe({
   
   entryTypes: ['longtask']})
// 见面可见性的状态监听
let vEvent = 'visibilitychange';
if (document.webkitHidden != undefined) {
   
   
    // webkit prefix detected
    vEvent = 'webkitvisibilitychange';
}

function visibilityChanged() {
   
   
    //页面不可见
    if (document.hidden || document.webkitHidden) {
   
   
        console.log("Web page is hidden.")
    } else {
   
   //页面可见
        console.log("Web page is visible.")
    }
}

document.addEventListener(vEvent, visibilityChanged, false);
var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
var type = connection.effectiveType;

function updateConnectionStatus() {
   
   
  console.log("Connection type changed from " + type + " to " + connection.effectiveType);
  type = connection.effectiveType;
}

connection.addEventListener('change', updateConnectionStatus);

代码优化

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vNgINJ8w-1624099839224)(https://z3.ax1x.com/2021/06/18/RpZTnf.png)]

V8 编译原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jH8xtzm5-1624099839228)(https://z3.ax1x.com/2021/06/18/RpehaF.png)]

抽象语法树

源码 – 抽象语法树 – 字节码Bytecode – 机器码

编译过程会进行优化

运行时可能发生反优化

V8 代表性优化机制

脚本流 :下载超过30kb时,会下载同时解析

字节码缓存 :不同页面使用相同代码会使用缓存

懒解析:不解析函数内部,用的时候解析

const {
   
   performance, PerformanceObserver} = require('perf_hooks');

const add = (a, b) => a+b;

const num1 = 1;
const num2 = 2;

performance.mark('start');

for(let i = 0; i < 10000000; i++) {
   
   
	add(num1, num2);
}

//发现类型转变会导致编译变慢
add(num1, 's');

for(let i = 0; i < 10000000; i++) {
   
   
	add(num1, num2);
}

performance.mark('end');

const observer = new PerformanceObserver((list) => {
   
   
	console.log(list.getEntries()[
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

f(me)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值