前端性能优化建议
⚡题目:
❓ 前端相关的性能优化方案
一个完整的 HTTP 请求需要经历 DNS 查找,TCP 握手,浏览器发出 HTTP 请求,服务器接收请求,服务器处理请求并发回响应,浏览器接收响应等过程。 下载数据的时间与数据大小的成正比。这就是为什么要建议将多个小文件合并为一个大文件,从而减少 HTTP 请求次数的原因。
解析速度快
:服务器解析 HTTP1.1 的请求时,必须不断地读入字节,直到遇到分隔符 CRLF 为止。而解析 HTTP2 的请求就不用这么麻烦,因为 HTTP2 是基于帧的协议,每个帧都有表示帧长度的字段多路复用
: HTTP1.1 如果要同时发起多个请求,就得建立多个 TCP 连接,因为一个 TCP 连接同时只能处理一个 HTTP1.1 的请求。 在 HTTP2 上,多个请求可以共用一个 TCP 连接,这称为多路复用。同一个请求和响应用一个流来表示,并有唯一的流 ID 来标识。 多个请求和响应在 TCP 连接中可以乱序发送,到达目的地后再通过流 ID 重新组建。首部压缩
:HTTP/2 在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键-值对,对于相同的数据,不再通过每次请求和响应发送。优先级
:HTTP2 可以对比较紧急的请求设置一个较高的优先级,服务器在收到这样的请求后,可以优先处理。流量控制
: 流量控制可以对不同的流的流量进行精确控制。服务器推送
:HTTP2 新增的一个强大的新功能,就是服务器可以对一个客户端请求发送多个响应。
优点:首屏渲染快,SEO 好。 缺点:配置麻烦,增加了服务器的计算压力。
例:Vue SSR
客户端渲染:
- 访问客户端渲染的网站。
- 服务器返回一个包含了引入资源语句和
<div id="app"></div>
的 HTML 文件。 - 客户端通过 HTTP 向服务器请求资源,当必要的资源都加载完毕后,执行
new Vue()
开始实例化并渲染页面。
服务端渲染:
- 访问服务端渲染的网站。
- 服务器会查看当前路由组件需要哪些资源文件,然后将这些文件的内容填充到 HTML 文件。如果有 ajax 请求,就会执行它进行数据预取并填充到 HTML 文件里,最后返回这个 HTML 页面。
- 当客户端接收到这个 HTML 页面时,可以马上就开始渲染页面。与此同时,页面也会加载资源,当必要的资源都加载完毕后,开始执行
new Vue()
开始实例化并接管页面。
内容分发网络(CDN)是一组分布在多个不同地理位置的 Web 服务器。我们都知道,当服务器离用户越远时,延迟越高。CDN 就是为了解决这一问题,在多个位置部署服务器,让用户离服务器更近,从而缩短请求时间。 同时支持缓存,部署缓存服务器存取。
CSS 和 JS 文件都会堵塞渲染(CSS 不会阻塞 DOM 解析)
- css 放头部:避免页面渲染出现丑陋的样式布局,提前参与渲染
- js 放尾部:避免加载JS导致页面空白时间过长
字体图标就是将图标制作成一个字体,使用时就跟字体一样,可以设置属性,例如 font-size、color 等等,非常方便。 并且字体图标是矢量图,不会失真。还有一个优点是生成的文件特别小。
Expires 或 max-age
压缩文件可以减少文件下载时间,让用户体验性更好。 使用 gzip 压缩。可以通过向 HTTP 请求头中的 Accept-Encoding 头添加 gzip 标识来开启这一功能
图片延迟加载
:在页面中,先不给图片设置路径,只有当图片出现在浏览器的可视区域时,才去加载真正的图片,这就是延迟加载响应式图片
: 响应式图片的优点是浏览器能够根据屏幕大小自动加载合适的图片。
<!-- picture实现 -->
<picture>
<source srcset="banner_w1000.jpg" media="(min-width: 801px)">
<source srcset="banner_w800.jpg" media="(max-width: 800px)">
<img src="banner_w800.jpg" alt="">
</picture>
/* @media 实现 */
@media (min-width: 769px) {
.bg {
background-image: url(bg1080.jpg);
}
}
@media (max-width: 768px) {
.bg {
background-image: url(bg768.jpg);
}
}
调整图片大小
: 用两张图片来实行优化。一开始,只加载缩略图,当用户悬停在图片上时,才加载大图。还有一种办法,即对大图进行延迟加载,在所有元素都加载完成后手动更改大图的 src 进行下载。降低图片质量
: 100% 的质量和 90% 质量的通常看不出来区别,尤其是用来当背景图的时候CSS3 效果代替图片
: 代码大小通常是图片大小的几分之一甚至几十分之一。使用 webp 格式的图片
WebP 的优势体现在它具有更优的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量;同时具备了无损和有损的压缩模式、Alpha 透明以及动画的特性,在 JPEG 和 PNG 上的转化效果都相当优秀、稳定和统一。
懒加载或者按需加载
,是一种很好的优化网页或应用的方式。这种方式实际上是先把你的代码在一些逻辑断点处分离开,然后在一些代码块中完成某些操作后,立即引用或即将引用另外一些新的代码块。这样加快了应用的初始加载速度,减轻了它的总体体积,因为某些代码块可能永远不会被加载。
import()
动态引入- webpack4 的
splitChunk
插件 cacheGroups 选项 @babel/runtime
包就声明了所有需要用到的帮助函数,而@babel/plugin-transform-runtime
的作用就是将所有需要 helper 函数的文件,从 @babel/runtime包 引进来, 避免每个文件都引用源码函数
重排: 当改变 DOM 元素位置或大小时,会导致浏览器重新生成渲染树。 重绘:当重新生成渲染树后,就要将渲染树每个节点绘制到屏幕
重排会导致重绘,重绘不会导致重排
浏览器渲染过程:
- 解析HTML生成DOM树。
- 解析CSS生成CSSOM规则树。
- 解析JS,操作 DOM 树和 CSSOM 规则树。
- 将DOM树与CSSOM规则树合并在一起生成渲染树。
- 遍历渲染树开始布局,计算每个节点的位置大小信息。
- 浏览器将所有图层的数据发送给GPU,GPU将图层合成并显示在屏幕上
如何减少重排重绘?
- 用 JavaScript 修改样式时,最好不要直接写样式,而是替换 class 来改变样式。
- 如果要对 DOM 元素执行一系列操作,可以将 DOM 元素脱离文档流,修改完成后,再将它带回文档。推荐使用隐藏元素(display:none)或文档碎片(DocumentFragement),都能很好的实现这个方案。
事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。所有用到按钮的事件(多数鼠标事件和键盘事件)都适合采用事件委托技术, 使用事件委托可以节省内存。
一个编写良好的计算机程序常常具有良好的局部性,它们倾向于引用最近引用过的数据项附近的数据项,或者最近引用过的数据项本身,这种倾向性,被称为局部性原理。有良好局部性的程序比局部性差的程序运行得更快
时间局部性
:在一个具有良好时间局部性的程序中,被引用过一次的内存位置很可能在不远的将来被多次引用。空间局部性
:在一个具有良好空间局部性的程序中,如果一个内存位置被引用了一次,那么程序很可能在不远的将来引用附近的一个内存位置
当判断条件数量越来越多时,越倾向于使用 switch 而不是 if-else。if-else 需要进行更多的判断,switch只需要进行一次判断。
使用map表获取
60fps 与设备刷新率
requestAnimationFrame
来实现视觉变化- 对于一些长时间运行的 JavaScript,我们可以使用定时器进行切分,延迟执行
Web Worker
使用其他工作线程从而独立于主线程之外,它可以执行任务而不干扰用户界面。一个 worker 可以将消息发送到创建它的 JavaScript 代码, 通过将消息发送到该代码指定的事件处理程序(反之亦然)
JavaScript 中的数字都使用 IEEE-754 标准以 64 位格式存储。但是在位操作中,数字被转换为有符号的 32 位格式。即使需要转换,位操作也比其他数学运算和布尔操作快得多。
if (value % 2) {
// 奇数
} else {
// 偶数
}
// 位操作
if (value & 1) {
// 奇数
} else {
// 偶数
}
~~10.12 // 10
~~10 // 10
~~'1.5' // 1
~~undefined // 0
~~null // 0
const a = 1
const b = 2
const c = 4
const options = a | b | c
无论你的 JavaScript 代码如何优化,都比不上原生方法。因为原生方法是用低级语言写的(C/C++),并且被编译成机器码,成为浏览器的一部分。当原生方法可用时,尽量使用它们,特别是数学运算和 DOM 操作
- 选择器越短越好
- 尽量使用高优先级的选择器,例如 ID 和类选择器
- 避免使用通配符 *
比起早期的布局方式来说有个优势,那就是性能比较好。
transforms 和 opacity 这两个属性更改不会触发重排与重绘,它们是可以由合成器(composite)单独处理的属性。
合理使用规则,避免过度优化