性能优化
一、为什么要进行性能优化
优化的目的在于让页面加载的更快,对用户操作响应更及时,提高用户体验
二、从输入 URL 到页面加载完成,发生了什么
DNS 解析:将 URL 解析为对应的 IP 地址
TCP 连接:IP 地址与IP地址确定的那台服务器建立起 TCP 网络连接
HTTP 请求抛出:向服务端抛出我们的 HTTP 请求
服务端处理请求,HTTP 响应返回
浏览器拿到响应数据,解析响应内容,把解析的结果展示给用户
三、方法
1、减少http请求
精灵图**css Sprites:**通过
background-image
background-position
来控制位置字体图标:阿里图标
base64图片
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、减少重排重绘
浏览器渲染过程
解析HTML生成DOM树。
解析CSS生成CSSOM规则树。
解析JS,操作 DOM 树和 CSSOM 规则树。
将DOM树与CSSOM规则树合并在一起生成渲染树。
遍历渲染树开始布局,计算每个节点的位置大小信息。
浏览器将所有图层的数据发送给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、空白页面
参考: