实践指南-前端性能提升 270% | 京东云技术团队

一、背景

当我们疲于开发一个接一个的需求时,很容易忘记去关注网站的性能,到了某一个节点,猛地发现,随着越来越多代码的堆积,网站变得越来越慢。

本文就是从这样的一个背景出发,着手优化网站的前端性能,并总结出一套开发习惯,让我们在日常开发时,也保持高性能,而不是又一次回过头来优化性能。

指标名称优化前优化后提升
Lighthouse Performance 评分2981279%
FCP(First Contentful Paint 首次内容绘制)0.7s0.7s
LCP(Largest Contentful Paint 最大内容绘制)6.2s2.5s248%
TTI(Time to Interactive 可交互时间)10.1s2.1s480%
Speed Index(速度指数)5.6s1.8311%
TBT(Total Blocking Time 总阻塞时间)820ms120ms683%

优化前后对比:

优化前后对比

二、优化前

接下来就是介绍下优化前我们要做哪些事件:

  1. 了解性能指标及测量工具

  2. 分析需要优化的地方

1. 了解测量工具及性能指标

一开始我们只是感受到网站的页面打开时白屏时间较长,感觉性能是比较差的,那么具体有哪些性能指标需要去关注呢?

这里我使用的是 Chrome devtools 内置的Lighthouse,Lighthouse 是一种开源的自动化工具,用于提高 Web 应用程序的质量。

Lighthouse 会在一系列的测试下运行网页,比如不同尺寸的设备和不同的网络速度。它还会检查页面对辅助功能指南的一致性,例如颜色对比度和 ARIA 最佳实践。

打开 Chrome devtools Lighthouse 即可使用。

在比较短的时间内,Lighthouse 可以给出这样一份报告。

这份报告从 5 个方面来分析页面: 性能、辅助功能、最佳实践、搜索引擎优化和 PWA。像性能方面,会给出一些常见的耗时统计。

优化前

1.1 Performance

Performance 评分统计,包括了以下指标:

1.1.1 FCP

FCP 测量在用户导航到页面后浏览器呈现第一段 DOM 内容所花费的时间。页面上的图像、非白色<canvas>元素和 SVG 被视为 DOM 内容;不包括 iframe 内的任何内容。

1.1.2 LCP

LCP 测量视口中最大的内容元素何时呈现到屏幕上。这近似于页面的主要内容对用户可见的时间。

需要注意的是 LCP 的计算是一个动态的过程,如下图最后的图片才是这个页面中的最大内容绘制的元素。

lcp

1.1.3 TTI

TTI 测量页面完全交互所需的时间。

TTI 是如何计算的呢,如下图首先延时间轴正向搜索时长至少为 5 秒的安静窗口(安静窗口是指没有长任务且不超过两个正在处理的网络 get 请求),然后沿时间轴反向搜索安静窗口之前的最后一个长任务,如果没有找到长任务,则在 FCP 步骤停止执行,TTI 就是安静窗口之前最后一个长任务的结束时间,如果没有找到长任务的话,则与 FCP 值相同。

TTI

1.1.4 Speed Index

Speed Index 衡量页面加载期间内容以视觉方式显示的速度。Lighthouse 首先捕获浏览器中页面加载的视频,并计算帧之间的视觉进度。

1.1.5 TBT

TBT 测量页面被阻止响应用户输入(例如鼠标点击、屏幕点击或键盘按下)的总时间。

通过添加 First Contentful Paint 和 Time to Interactive 之间所有长任务的阻塞部分来计算总和。任何执行时间超过 50 毫秒的任务都是长任务。

50 毫秒后的时间量是阻塞部分。例如,如果 Lighthouse 检测到一个 70 毫秒长的任务,则阻塞部分将为 20 毫秒。

如下图淡红色区域的时间总和就是这个页面的 TBT 分数。

TBT

1.2 最佳实践

用于检测 Web 应用程序整体代码健康状况,包括是否包含文档类型、图片宽高比是否正确等等。

1.3 SEO

用于检测搜索引擎对网页内容的理解程度。

2. 分析需要优化的地方

了解了关键的性能指标后,就可以测量看看当前网站的性能了,

上面看到综合评分是非常低的,Lighthouse 给出了应该从哪些地方开始优化的建议。

2.1 Performance

性能优化建议主要包括以下几点:

  • 减少未使用的 JS;

  • 合理使用图片的格式,webp 或者 avif 更快;

  • 延迟加载不在视图的图片;

  • JS 压缩;

  • 图片的尺寸大小应该适当;

  • 减少未使用的 CSS。

性能优化建议

Lighthouse 诊断出的网站存在的问题:

  • 需要加载的资源太多太大,有 147 个请求,合计 11mb;

  • 有 40 个静态资源的缓存只有 1 小时

  • 滚动事件没有添加标记{passive: true}),导致需要等待侦听器完成执行后再滚动页面;

  • 图像元素没有设置明确的宽度和高度;

  • JS 文件太多,主线程工作量太大、JS 执行时间太长;

存在的问题

2.2 最佳实践

最佳实践方面有以下问题:

  • 图片的分辨率太低,清晰度不够;

  • 没有设置 CSP 策略。

最佳实践的问题

2.3 SEO

SEO 有以下问题:

  • 没有 meta description;

  • 图片没有 alt 属性;

  • robots.txt 是无效的。

SEO的问题

三、优化 Performance

根据上面 Lighthouse 报告,捋一捋项目中影响性能最大的因素,包括以下几点:

  • 体积太大,达 11mb;

  • 图片太大,图片格式也有影响。

1. 体积优化

1.1 代码压缩

检查是否还有压缩空间,或者有无工具库未压缩的。

1.2 代码分包

通过 webpack-bundle-analyzer 插件分析包体积,将一些大的 npm 包和 runtimeChunk 独立分包,减小包体积。

1.3 组件按需加载

React.lazy + Suspense 封装懒加载组件,路由级组件引入懒加载组件。
同时使用骨架屏作为懒加载的兜底组件,可以让用户感知加载更快。
在鼠标移入导航栏时预加载路由组件,可以加快页面展示。

1.4 工具库按需加载

通过 import(‘xx’).then(xx) 按需加载工具库。

1.5 静态资源上传 CDN

项目内有一些 json 文件存储的静态数据,这部分文件上传至 CDN,改为 fetch 的方式按需引入。

1.6 删除不需要的资源

检查项目中引入的 mf、npm 资源,将没有使用到的删除。

1.7 避免重复的 npm 包引入

发现业务组件库通过 npm 引入的原子组件库,而项目本身又是通过 mf 引入的原子组件库,相对于引入了 2 遍原子组件库。

这时就需要改造业务组件库,也改成用 mf 的方法引入。

1.8 避免 esm 依赖嵌套

因为 webpack 的按需加载是通过 import、export 来标记的,因此想要一个好的按需加载的效果,就需要避免依赖嵌套的问题。

1.9 图标按需加载

原子组件库 mf 暴露的方式会导致只用了 1 个 icon,就会加载组件库下所有 icon 对应的 chunk,导致资源浪费。

新建一个 icon 的 npm 包用于 icon 的按需引入。

1.10 小结

通过以上优化手段,体积从 11.7mb 降低至 1.1mb,降低 10.6 倍。

优化前:

优化前

优化后:

优化后

2. 图片优化

1.1 图片懒加载

对非首屏的图片采用图片懒加载策略。

1.2 图片尺寸

使用图片时,设置图片的合理尺寸。

1.3 图片格式设置

优先使用 webp 格式图片。

四、优化最佳实践

1. 设置 CSP 策略

2. 设置合理的图片的分辨率

优化项目内的图片分辨率。

五、优化 SEO

1. meta description、keywords 优化

详细的 meta description、keywords 可以加快 SEO。

<meta name="keywords" content="xx" /> <meta name="description" content="xx" />

2. 图片加上 alt 属性

<img src="smiley.gif" alt="Smiley face" />

六、优化前后对比

再来回顾下前后对比:

优化前,明显的感知白屏时间长:

优化前

优化后,在清缓存的情况下也能实现秒开:

优化后

整体性能提升 270%:

优化前后对比

七、性能监控

为了在后续的迭代过程中,保持高性能,引入内部前端监控平台 -烛龙,可视化的监控前端性能。

第一步,加载 cdn 插件:

<scriptdefersrc="https://h5static.m.jd.com/act/jd-jssdk/latest/jd-jssdk.min.js"
></script>

第二步,在入口文件中,初始化 cdn 插件:

useEffect(() => {// 初始化测速组件,在这里可以打开一些控制的开关,如是否上报接口if (IS_PROD) {// @ts-ignorejmfe.profilerInit({flag: xxx, // 这是应用ID,需要先在烛龙申请应用autoReport: true,autoAddStaticReport: true,autoAddApiReport: true,autoAddImageReport: false, // 支持所有图片上报,如果图片多,切记关闭,否则存在性能问题performanceReportTime: 8000,profilingRate: 1,})}
}, [])

第三步,查看监控数据:

在烛龙平台,小工具性能评分达 96分:

查看监控数据

第四步,新增告警,实时监控

烛龙平台支持多维度的告警的服务,增加性能指标相关的告警,在性能异动时,及时发现问题,优化性能。

小结

本文详细介绍了一个前端项目优化的详细过程,从优化前的问题分析,到具体的优化措施,最终实现了前端性能提升了近 3 倍。同时也将性能指标落到监控平台,实现可视化的监控前端性能指标。

希望能对你有所帮助,感谢阅读~

参考资料

  • 被删的前端游乐场-前端性能优化-归纳篇
  • 前端缓存 API 请求数据的解决方案
  • 网易云课堂 Service Worker 运用与实践

作者:京东零售 唐姣

来源:京东云开发者社区

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/87260.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在R中比较两个矩阵是否相等

目录 方法一&#xff1a;使用all.equal()比较两个R对象是否近似相等 方法二&#xff1a;使用identical比较两个R对象是否精确相等。 方法一&#xff1a;使用all.equal()比较两个R对象是否近似相等 使用函数&#xff1a;all.equal(x,y) 比较两个R对象x和y是否近似相等 > M1…

abbitmq启动访问不了http://localhost:15672 通过修改服务登录admin

abbitmq默认的对Administration授权&#xff0c;而我的用户不是默认的Administration&#xff0c;所以后来打开服务&#xff0c;找到rabbitmq服务&#xff0c;属性&#xff0c;登陆&#xff0c;将本地系统账户修改为此账户&#xff0c;修改完成之后再重启服务&#xff0c;这时候…

SpringMVC注解开发

1. 构建流程 1&#xff09;IDEA创建一个Maven项目。配置所需依赖 <dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></depe…

【Fegin技术专题】「原生态」打开Fegin之RPC技术的开端,你会使用原生态的Fegin吗?(上)

前提介绍 Feign是SpringCloud中服务消费端的调用框架&#xff0c;通常与ribbon&#xff0c;hystrix等组合使用。由于遗留原因&#xff0c;某些项目中&#xff0c;整个系统并不是SpringCloud项目&#xff0c;甚至不是Spring项目&#xff0c;而使用者关注的重点仅仅是简化http调…

瑞数系列及顶像二次验证LOGS

瑞数商标局药监局专利局及顶像二次验证 日期&#xff1a;20230808 瑞数信息安全是一个专注于信息安全领域的公司&#xff0c;致力于为企业和个人提供全面的信息安全解决方案。他们的主要业务包括网络安全、数据安全、应用安全、云安全等方面的服务和产品。瑞数信息安全拥有一支…

机器学习笔记:李宏毅chatgpt 大模型 大资料

1 大模型 1.1 大模型的顿悟时刻 Emergent Abilities of Large Language Models&#xff0c;Transactions on Machine Learning Research 2022 模型的效果不是随着模型参数量变多而慢慢变好&#xff0c;而是在某一个瞬间&#xff0c;模型“顿悟”了 这边举的一个例子是&#…

YOLOv5、YOLOv8改进:MobileViT:轻量通用且适合移动端的视觉Transformer

MobileViT: Light-weight, General-purpose, and Mobile-friendly Vision Transformer 论文&#xff1a;https://arxiv.org/abs/2110.02178 1简介 MobileviT是一个用于移动设备的轻量级通用可视化Transformer&#xff0c;据作者介绍&#xff0c;这是第一次基于轻量级CNN网络性…

STM32 LL库+STM32CubeMX--点亮板载LED

一、前期准备 硬件&#xff1a;STM32F103C8T6开发板调试工具&#xff1a;DAPLink(本次使用)或USB-TTL开发环境&#xff1a;STM32CubeMX、Keil、Vscode(可选)板载LED&#xff1a;PC13(低电平点亮) 二、STM32CubeMX配置 1.选择芯片型号&#xff1a; 2.配置外设时钟&#xff1a;…

【BASH】回顾与知识点梳理(十七)

【BASH】回顾与知识点梳理 十七 十七. 什么是 Shell scripts17.1 干嘛学习 shell scripts自动化管理的重要依据追踪与管理系统的重要工作简单入侵检测功能连续指令单一化简易的数据处理跨平台支持与学习历程较短 17.2 第一支 script 的撰写与执行撰写第一支 script 17.3 撰写 s…

Android应用开发(37)LTPO帧率测试基于Surfaceview(暂存)

Android应用开发学习笔记——目录索引 参考android官网&#xff1a; Frame rate | Android media | Android Developers多重刷新率 | Android 开源项目 | Android Open Source ProjectWindowManager.LayoutParams | Android Developers 目前市面上旗舰手机基本都是…

[保研/考研机试] KY56 数制转换 北京大学复试上机题 C++实现

题目链接&#xff1a; 数制转换https://www.nowcoder.com/share/jump/437195121691734210665 描述 求任意两个不同进制非负整数的转换&#xff08;2进制&#xff5e;16进制&#xff09;&#xff0c;所给整数在long所能表达的范围之内。 不同进制的表示符号为&#xff08;0&a…

腾讯云COS的快速接入

背景 最近在研究一个剪贴板粘贴工具&#xff0c;实现粘贴图片&#xff0c;返回可访问的地址&#xff0c;这个在我的哔哩哔哩上有出一期视频&#x1f92d;。但是&#xff0c;我发现部分博客平台不能正常的转载我的图片链接&#xff0c;于是研究了一下腾讯云的COS&#xff08;阿…

Oracle 知识篇+会话级全局临时表在不同连接模式中的表现

标签&#xff1a;会话级临时表、全局临时表、幻读释义&#xff1a;Oracle 全局临时表又叫GTT ★ 结论 ✔ 专用服务器模式&#xff1a;不同应用会话只能访问自己的数据 ✔ 共享服务器模式&#xff1a;不同应用会话只能访问自己的数据 ✔ 数据库驻留连接池模式&#xff1a;不同应…

“冰箭卫士·IP发布会”首次亮相第14届海峡两岸(厦门)文博会

2023年8月6日,“冰箭卫士IP发布会”首次亮相海峡两岸文博会思明馆。此次发布会由厦门市文化创意产业协会、厦门理工&#xff08;集美区&#xff09;政产学研基地主办&#xff0c;厦门市文化创意产业协会IP设计研究院、厦门一笔之上文化发展有限公司、冰箭应急安全科技研究院承办…

(vue)获取对象的键遍历,同时循环el-tab页展示key及内容

(vue)获取对象的键遍历&#xff0c;同时循环el-tab页展示key及内容 效果&#xff1a; 数据结构&#xff1a; "statusData": {"订购广度": [ {"id": 11, "ztName": "广", …

[保研/考研机试] KY183 素数 北京航空航天大学复试上机题 C++实现

题目链接&#xff1a; 素数https://www.nowcoder.com/share/jump/437195121691718444910 描述 输入一个整数n(2<n<10000)&#xff0c;要求输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数&#xff0c;如果没有则输出-1。 输入描述&#xff1a; 输入有多…

PowerShell 使用SqlScriptDOM对T-SQL做规则校验

对于数据项目来说&#xff0c;编写Sql是一项基本任务同时也是数量最多的代码。为了统一项目代码规范同时降低Code Review的成本&#xff0c;因此需要通过自动化的方式来进行规则校验。由于本人所在的项目以SQL Server数据库为基础&#xff0c;于是本人决定通过使用SqlScriptDom…

2022年06月 C/C++(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题&#xff1a;倒序输出 依次输入4个整数a、b、c、d,将他们倒序输出&#xff0c;即依次输出d、c、b、a这4个数。 时间限制&#xff1a;1000 内存限制&#xff1a;65536 输入 一行4个整数a、b、c、d&#xff0c;以空格分隔。 0 < a,b,c,d < 108 输出 一行4个整数d、c、…

快速上手React:从概述到组件与事件处理

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

ElasticSearch学习

一&#xff0c;简介 ES&#xff08;elaticsearch简写&#xff09;&#xff0c; Elasticsearch是一个开源的高扩展的分布式全文检索引擎&#xff0c;它可以近乎实时的存储、检索数据&#xff1b;本身扩展性很好&#xff0c;可以扩展到上百台服务器&#xff0c;处理PB级别的数据…