性能优化

一、为什么要进行性能优化

优化的目的在于让页面加载的更快,对用户操作响应更及时,提高用户体验

二、从输入 URL 到页面加载完成,发生了什么

  1. DNS 解析:将 URL 解析为对应的 IP 地址

  2. TCP 连接:IP 地址与IP地址确定的那台服务器建立起 TCP 网络连接

  3. HTTP 请求抛出:向服务端抛出我们的 HTTP 请求

  4. 服务端处理请求,HTTP 响应返回

  5. 浏览器拿到响应数据,解析响应内容,把解析的结果展示给用户

三、方法

1、减少http请求

2、缩小请求体积

1) gzip

  • nginx配置
// nginx.conf
gzip  on; # 开启gzip
  • vue-cli配置

    • 安装
npm install compression-webpack-plugin --save-dev

注意:打包时报如下错误,降低 compression-webpack-plugin版本

- 配置
// vue.config.js
const compressionPlugin = require("compression-webpack-plugin")

module.exports = {
	configureWebpack: {
	    plugins: [
	      new compressionPlugin({
	        test:/\.js/i, // 匹配文件名
	        threshold: 10240, // 对超过大小的数据进行压缩
	        deleteOriginalAssets: false // 是否删除源文件
		  })
	    ],
	 }

}
  • 查看是否开启了gzip

    • response header

- request header

2) 压缩js

  • 安装
npm install uglifyjs-webpack-plugin
  • 配置
const uglify = require('uglifyjs-webpack-plugin')

module.exports = {
  configureWebpack: {
    plugins: [
      // 压缩js
      new uglify()
    ]
  }
}

低版本ios会白屏,需配置

3、将 CSS 放在文件头部,JavaScript 文件放在底部

  • js阻塞后续dom的解析,浏览器无法预估js具体做了什么,比如先解析dom,js删除dom,那么就白解析了

  • js阻塞页面渲染,js可以修改样式

  • js阻塞后续js的执行,有依赖关系

4、避免重定向

5、减少重排重绘

浏览器渲染过程

  1. 解析HTML生成DOM树。

  2. 解析CSS生成CSSOM规则树。

  3. 解析JS,操作 DOM 树和 CSSOM 规则树。

  4. 将DOM树与CSSOM规则树合并在一起生成渲染树。

  5. 遍历渲染树开始布局,计算每个节点的位置大小信息。

  6. 浏览器将所有图层的数据发送给GPU,GPU将图层合成并显示在屏幕上。

重排

当改变 DOM 元素位置或大小时,会导致浏览器重新生成渲染树,这个过程叫重排。

重绘

当重新生成渲染树后,就要将渲染树每个节点绘制到屏幕,这个过程叫重绘。重排会导致重绘,重绘不会导致重排 。

什么操作会导致重排?

  • 添加或删除可见的 DOM 元素

  • 元素位置改变

  • 元素尺寸改变

  • 内容改变

  • 浏览器窗口尺寸改变

  • 读取某些元素属性:offsetLeft/Top/Height/Width, clientTop/Left/Width/Height, scrollTop/Left/Width/Height(强制刷新渲染队列以获取最新的值)

如何减少重排重绘?

  • 用 JavaScript 修改样式时,最好不要直接写样式,而是替换 class 来改变样式。

  • 如果要对 DOM 元素执行一系列操作,可以将 DOM 元素脱离文档流,修改完成后,再将它带回文档。推荐使用隐藏元素(display:none)或文档碎片(DocumentFragement),都能很好的实现这个方案。

  • 使用transform来代替对top left进行位置移动

  • 使用visibility代替display

requestAnimationFrame(callback)

  • 告诉浏览器在下次重绘之前调用指定的回调函数更新动画

  • 把每一帧中的所有DOM操作集中起来,在一次重绘中就完成,并且重绘的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧

  • 当页面被隐藏或最小化时,定时器 setTimeout 仍在后台执行动画任务,而requestAnimationFrame将会暂停,会减少cpu,gpu和内存使用量

四、工具

  • 打包分析工具

    • 安装
npm install webpack-bundle-analyzer --save-dev
- 配置
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
 
module.exports = {
  plugins: [
    new BundleAnalyzerPlugin()
  ]
}
  • performance

【FPS】每秒帧数。绿色竖线越高,FPS越高。FPS图表上的红色块表示长时间帧,很可能会出现卡顿。

【cpu】颜色对应Summary中的颜色

【NET】每条彩色横杠表示一种资源。横杠越长,检索资源所需的时间越长。

【main】记录了渲染进程中主线程的执行记录,点击查看某个任务执行的具体情况

【Summary】录制完成后,不选择任何事件时,显示当前录制的细节。对应颜色来优化

【Memory】内存占用情况

- JS Heap(堆),如果曲线一直在增长,则说明存在内存泄露

- Documents,目前tab的内存有多少个Documents,包括当前页面、之前的页面、iframe和插件产生的页面。

- nodes,DOM节点

- listeners,侦听器。Nodes和Listeners不断增加说明可能存在重复添加节点或者事件的情况

- GPU memory,GPU内存
  • lighthouse

  • network

【queueing】排队的时间花费

【stalled】请求等待发送所用的时间。

【proxy negotiaion】与代理服务器连接协商所用的时间

【DNS lookup】执行 DNS 查询所用的时间(DNS解析)。

【Initial Connection】建立连接所用的时间,包括 TCP 握手/重试和协商 SSL 的时间(TCP连接)

【SSL】完成 SSL 握手所用的时间

【Request sent】发出网络请求所用的时间(HTTP请求)。

【TTFB】是最初的网络请求被发起到从服务器接收到第一个字节这段时间。建议将此值控制在 200 毫秒以下(HTTP响应),通常是耗费时间最长的。

【content Download】接收响应数据所用的时间

1、app加载,安卓比iOS卡顿

2、vue,react虚拟dom

3、定位工具

4、空白页面

参考: