前端性能优化之LightHouse

优质博文:IT-BLOG-CN

一、LightHouse环境搭建

LightHouse是一款由Google开发的开源工具,用于评估Web应用程序的性能和质量。可以将其看作是一个Chrome扩展程序运行,或从命令行运行。为LightHouse提供一个需要审查的网址,它将针对此页面进行一连串的测试,然后生成一个有关页面性能的报告。可以分析Web应用程序的加载速度、渲染性能、可访问性、可用性和最佳实践等方面,提供详细的报告和建议。LightHouse GitHub , LightHouse 官网

我们可以在LightHouse GitHub中看到多种安装和使用方式,我们这里使用扩展程序进行演示:

Google商店中直接搜索LightHouse下载安装即可。

我们从Chrome Developers网站获取一个性能差的项目,进行实战优化:Lighthouse: Optimize website speed

【1】登录账号后点击Remix

【2】点击Glitch图标

【3】选择你要下载的项目每个人的项目名可能不同

【4】解压下载的项目后,通过Visual Studio Code打开项目,删除package-lock.json,然后执行npm i会生成新的依赖package-lock.json

最后通过npm run start启动项目,项目启动后的访问地址为:http://localhost:1234/

二、LightHouse 指标介绍

我们使用F12打开当前项目的控制台,点击LightHouse后能够看到Analyze page load点击后,就会对网页进行性能分析。需要注意的是浏览器的缓存会影响性能分析的分数,所以在分析之前需要对缓存进行清理。

设置:
【1】Clear Storage:是否清除缓存,模拟用户第一次进入页面就勾选,清除缓存;
【2】Simulated throttling:模拟限制,勾选之后Lighthouse在测试过程中限制网速与CPU。网络限速:Latency延迟: 150msThroughput上行下行网速: 1.6Mbps down / 750 Kbps upPacket loss: noneCPU限制:4x CPU谷歌开发者工具也可设置网络限速。CPU限制:4x CPU;谷歌开发者工具也可设置网络限速。

模式:
【1】navigation:默认的,测试的是当前页面,分类都可选;
【2】Timespan:用这个模式可以测试一堆操作的性能,不只是一个页面,测试类型只有Performance、Best Practices
【3】snapshot:生成页面快照的一种测试模式,测试类型有Performance、Accessibility、Best Practices、SEO

分类:
【1】Performance:评估Web应用程序的性能得分,根据测量的结果打分,根据占比计算得到的。分析页面加载时间、资源大小、缓存策略等因素,并给出相应的建议和优化方案;
【2】Accessibility:评估Web应用程序的可访问性,它会检查页面是否符合WCAG(Web Content Accessibility Guidelines)标准,并给出相应的建议和优化方案,目的是用来评估构建一个适用于所有用户的网站;
【3】Best Practices:该选项用于评估Web应用程序是否符合最佳实践。它会检查页面是否存在常见的问题,例如安全问题、SEO问题等,并给出相应的建议和优化方案;
【4】SEO:该选项用于评估Web应用程序的搜索引擎优化情况。它会检查页面是否符合搜索引擎的要求,例如页面标题、meta标签等,并给出相应的建议和优化方案;
【5】PWA:选项用于评估Web应用程序是否符合渐进式Web应用程序PWA的标准。它会检查页面是否具有离线访问、添加到主屏幕等功能,并给出相应的建议和优化方案;

常规情况下,我们重点关注第一个Performance

点击Analyze page load查看分析结果:

指标介绍:
【1】FCP(First Contentful Paint)首次内容绘制: 白屏时间,第一次有内容呈现在用户屏幕上的时间点。
【2】LCP(Largest Contentful Paint)最大内容绘制: 指页面渲染出最大文本或图片的时间。
【3】TTI(Time to Interactive)可交互时间: 测量页面从开始加载到主要子资源完成渲染,第一次可流畅交互的时间。
【4】SI(Speed Index)页面加载速度: 是一个衡量Web页面加载速度的指标,它表示页面在加载过程中的视觉稳定性。Speed Index越低,表示页面加载速度越快,用户体验越好,视觉稳定性得分是根据页面中元素的位置和大小变化来计算的,变化越大得分越高,变化越小得分越低。
【5】TBT(Total Blocking Time)总阻塞时间: 它是指在FCPTTI之间,所有超过50毫秒的任务时间总和,以毫秒为单位。

当页面开始呈现内容FCP后,用户可以开始与页面进行交互,直到页面完全加载并响应用户操作TTI。在这个过程中,浏览器需要执行多个任务,例如解析HTML、加载CSSJavaScript文件、渲染页面等。如果某个任务的执行时间超过50毫秒,就会对页面的加载速度和性能产生负面影响。

【6】CLS(Cumulative Layout Shift)累积布局偏移: 布局偏移情况,当页面中的元素位置发生变化时,浏览器需要重新计算页面的布局,从而增加页面加载时间。如果页面中的元素位置变化过于频繁,会导致页面加载时间过长,影响用户体验和SEO排名,布局偏移分数 = 影响分数 * 距离分数。

疑问:Lighthouse打分的标准是什么呢?

Lighthouse的打分标准,我们可以通过拖动每个指标观察分数的变化,便可以得到指标在分数中的占比,但需要注意不同版本占比是不相同的。

View Treemap:我们继续查看Lighthouse性能分析页面,通过点击View Treemap我们还能看到静态资源的利用率情况:

得到静态资源的利用率情况如下:

Lighthouse还为网站提供了优化建议 :根据业务情况斟酌处理

三、页面优化

【1】Enable text compression开启文本压缩: 在压缩之前先看下资源占用的大小

在项目的server.js中开启压缩:目前资源的传输时没有开启gzip压缩的,通过下面的代码就可以加载compression第三方包,开启gzip压缩,主要压缩文字类容js/css放到中间中。

const compression = require('compression'); 
app.use(compression());

然后我们点击+生成一个新的报告:原有的报告还在

刷新缓存重新看下js/css资源加载的大小:

重新跑一次Lighthouse发现分数上升了, 同时也没有了压缩的相关建议:

【2】Resize images重新设定合适大小的图片: 优化前加载这些静态图片,用了3.84秒

我们将图片的大小由big变为small,更改项目中src/model.js文件:

const dir = 'small';

在这里插入图片描述

重启项目后,重新跑一次Lighthouse发现分数上升了, 同时也没有了图片大小修改的相关建议:也可以在Network中查看资源的大小。

【3】Eliminate render-blocking resources消除非关键资源:

Lighthouse给的建议是lodash.jsjquery.js两个文件是首次加载时的非关键的资源,但是我们实际看到这样的建议之后,可能会存在疑惑。就需要证明,页面加载的时候,哪些js被用到了,哪部分代码没有被使用。打开控制台,按ctrl + shift + p打开Command Menu,输入coverage

这两个js页面确实用到了,但它们一定就是关键资源了吗?我们需要继续往后验证。

ctrl + shift + p输入blocking

点击左下角+号,添加阻塞规则:

我们先把jquerylodash两个文件给禁止掉了,发现页面依旧可以运行,如果把bundle也给禁止掉,页面直接白屏不可用。去除禁止,则恢复使用。

结合Chrome的控制台命令进行校验,哪些JS文件被禁止加载了,页面也依旧可以正常展示。那么对于这类非关键资源,即页面首次加载并不需要它的文件,我们可以将其改为异步加载。我们找到template.html文件,删除里面对这两个js的引用:

也可以把它们改为异步加载,增加defer标识:

<script src="/libs/lodash.js" defer></script>
<script src="/libs/jquery.js" defer></script>

重新跑一次Lighthouse发现分数上升了, 同时也没有了js修改的相关建议:

【4】Diagnostics需要进一步调试的复杂诊断: Lighthouse里面还有Diagnostics相关的专栏,这一部分的建议都是需要我们开发者通过调试来分析诊断的。

选择Performance,然后选择左上角的start按钮

进行相关参数的配置:

查看哪些js的运行时间特别长:

我们先看下执行时间最长的mineBitcoin函数,执行时间占用了75%。如下:我们将这段代码注释掉。

重新跑一次Lighthouse发现分数直线上升了:

当前项目webpack.config.js的打包模式为生产者模式。

mode: "production",

最后我们再看下分数吧:666

四、总结

【1】从js/css资源的大小来看:减少js/css的体积。我们可以开启minify压缩。或者删除一些无用的代码。
【2】从加载方式角度来看:一些非关键资源,开启异步加载,预加载、按需加载、延迟加载等。
【3】从请求协议角度来看:我们可以减少Http1.0请求次数,并且可以使用Http2.0,因为它是异步非阻塞的。对于Chrome浏览器,针对http1.0默认会限制住6个文件数量的请求并发,如果>6个文件,就会分成n + 1个批次去请求资源。但是如果你是http2.0的话,就会同时请求这12个文件。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于django水果蔬菜生鲜销售系统

基于django水果蔬菜生鲜销售系统 摘要 基于Django的水果蔬菜生鲜销售系统是一种利用Django框架开发的电子商务平台&#xff0c;旨在提供高效、便捷的购物体验&#xff0c;同时支持水果蔬菜生鲜产品的在线销售。该系统整合了用户管理、产品管理、购物车、订单管理等核心功能&…

springboot引入第三方jar包放到项目目录中,添加web.xml

参考博客&#xff1a;https://www.cnblogs.com/mask-xiexie/p/16086612.html https://zhuanlan.zhihu.com/p/587605618 1、在resources目录下新建lib文件夹&#xff0c;将jar包放到lib文件夹中 2、修改pom.xml文件 <dependency><groupId>com.lanren312</grou…

【C++】【Opencv】cv::warpAffine()仿射变换函数详解,实现平移、缩放和旋转等功能

仿射变换是一种二维变换&#xff0c;它可以将一个二维图形映射到另一个二维图形上&#xff0c;保持了图形的“形状”和“大小”不变&#xff0c;但可能会改变图形的方向和位置。仿射变换可以用一个线性变换矩阵来表示&#xff0c;该矩阵包含了六个参数&#xff0c;可以进行平移…

数据库课后习题加真题

文章目录 第二章第三章第四到六章某年真题 第二章 第三章 3.8 对于教学数据库的三个基本表&#xff1a; s( 学号 ‾ \underline{学号} 学号​&#xff0c;姓名&#xff0c;年龄, 性别) sc( 学号 , 课程号 ‾ \underline{学号, 课程号} 学号,课程号​, 成绩) c( 课程号 ‾ \un…

移动端表格分页uni-app

使用uni-app提供的uni-table表格 网址&#xff1a;https://uniapp.dcloud.net.cn/component/uniui/uni-table.html#%E4%BB%8B%E7%BB%8D <uni-table ref"table" :loading"loading" border stripe type"selection" emptyText"暂无更多数据…

Java 省考试院自学考试考籍管理系统

1) 项目简介 考籍管理系统是省考试院自学考试管理系统的一部分&#xff0c;包括考生考籍档案管理、考生免考管理、课程顶替、考籍转入转出管理、毕业管理和日志管理等功能模块。该项目的建设方便和加强了省考试院对自学考试考籍的一系列管理操作&#xff0c;社会效应明显。…

为什么软件公司很少用Python开发Web项目?

实际上&#xff0c;Python在Web开发方面有着广泛的应用&#xff0c;许多软件公司也确实使用Python来开发Web项目。 Python拥有诸如Django、Flask等流行的Web框架&#xff0c;这些框架使得开发者能够迅速、高效地开发出Web应用。 然而&#xff0c;Python在Web开发中的使用可能会…

深度学习——(生成模型)DDPM

前置数学知识 1、先验概率和后验概率 先验概率&#xff1a;根据以往经验和分析得到的概率,它往往作为“由因求果”问题中的“因”出现&#xff0c;如 q ( x t ∣ x t − 1 ) q(x_t|x_{t-1}) q(xt​∣xt−1​) 后验概率&#xff1a;指在得到“结果”的信息后重新修正的概率,是…

LeetCo

题目描述如下&#xff1a; 罗马数字包含以下七种字符: I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M …

component 动态组件的用法

一&#xff1a;前言 <component></component> 标签是Vue框架自定义的标签&#xff0c;它的用途就是可以动态绑定我们的组件&#xff0c;根据数据的不同需求来更换使用不同的组件。 在最上方的图片中&#xff0c;就是使用的 Element Plus 的 Tags 组件&#xff0c;根…

golang学习笔记——接口

文章目录 Go 语言接口例子空接口空接口的定义空接口的应用空接口作为函数的参数空接口作为map的值 类型断言接口值 类型断言例子001类型断言例子002 Go 语言接口 接口&#xff08;interface&#xff09;定义了一个对象的行为规范&#xff0c;只定义规范不实现&#xff0c;由具…

Codeforces Round #909 (Div. 3)

A. Game with Integers 签到题&#xff0c;但是本蒟蒻11分钟才AC&#xff0c;主要还是英文题面不熟练&#xff0c;题目中加粗了after&#xff0c;只有下一步操作之后能被整除才胜利。 英文题面的加粗单词很重要&#xff0c;注意提高签到题速度。 B. 250 Thousand Tons of TNT…

C语言的由来与发展历程

C语言的起源可以追溯到上世纪70年代&#xff0c;由Dennis Ritchie在贝尔实验室开发出来。C语言的设计目标是提供一种简洁、高效、可移植的编程语言&#xff0c;以便于开发底层的系统软件。在那个时代&#xff0c;计算机技术正在迅速发展&#xff0c;出现了多种高级编程语言&…

05-Spring Boot工程中简化开发的方式Lombok和dev-tools

简化开发的方式Lombok和dev-tools Lombok常用注解 Lombok用标签方式代替构造器、getter/setter、toString()等重复代码, 在程序编译的时候自动生成这些代码 注解名功能NoArgsConstructor生成无参构造方法AllArgsConstructor生产含所有属性的有参构造方法,如果不希望含所有属…

Pycharm中添加Python库指南

一、介绍 Pycharm是一款为Python开发者提供的集成开发环境&#xff08;IDE&#xff09;&#xff0c;支持执行、调试Python代码&#xff0c;并提供了许多有用的工具和功能&#xff0c;其中之一就是在Pycharm中添加Python库。 添加Python库有许多好处&#xff0c;比如能够增加开…

C/C++字符判断 2021年12月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析

目录 C/C字符判断 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 C/C字符判断 2021年12月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 对于给定的字符&#xff0c;如果该字符是大小写字母或…

Typecho用宝塔面板建站(保姆级教程)

提前准备&#xff1a; 1 已备案域名 注意:在腾讯云备案的域名部署阿里云服务器的话还需要在阿里云备案&#xff0c;反之亦然 2 服务器 服务器操作系统设置为windows 服务器实例设置&#xff1a;依次开放8888/888/443/3000-4000/21/22端口 个人用的阿里云&#xff0c;到安全组配…

代码随想录算法训练营第五十五天|392. 判断子序列、115. 不同的子序列

第九章 动态规划 part15 392. 判断子序列 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&#xff09;字符而不改变剩余字符相对位置形成的新字符串。&#xff08;例如&#xff0c;"ace&q…

实验(二):存储器实验

一、实验内容与目的 实验要求&#xff1a; 利用 CP226 实验仪上的 K16..K23 开关做为 DBUS 的数据&#xff0c;其它开关做为控制信号&#xff0c;实现主存储器 EM 的读写操作&#xff1b;利用 CP226 实验仪上的小键盘将程序输入主存储器 EM&#xff0c;实现程序的自动运行。 实…

leetcoe刷题日志-6N字形变换

将一个给定字符串 s 根据给定的行数 numRows &#xff0c;以从上往下、从左到右进行 Z 字形排列。 比如输入字符串为 “PAYPALISHIRING” 行数为 3 时&#xff0c;排列如下&#xff1a; 之后&#xff0c;你的输出需要从左往右逐行读取&#xff0c;产生出一个新的字符串&#…