参考指标

白屏时间、首屏时间、整页时间、DNS时间、CPU占有率等

网络传输优化

浏览器缓存

  1. 浏览器响应请求步骤

重定向 —> 拉取缓存 —> DNS 查询 —> 建立 TCP 连接 —> 发起请求 —> 接收响应 —> 处理 HTML 元素 —> 元素加载完成

  1. 浏览器处理缓存策略

浏览器缓存默认地址内存中,内存里的缓存会因为进程的结束或者说浏览器的关闭而被清除,而存在硬盘里的缓存才能够被长期保留下去。

network 请求的size项里:from memory cache、from disk cache

控制缓存存放位置的方法:设置服务器 ETag 字段,检查服务器响应头,是否包含 ETag 字段,有则将本次缓存写入硬盘

资源打包压缩

网络性能优化:减少请求数、减小请求资源体积、提高网络传输速率

自动化打包推荐 webpack,Gulp和Grunt来编译node,Parcel太新
  1. webpack

① JS 压缩

1
2
3
4
5
6
7
8
9
10
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true // set to true if you want JS source maps
}),
...Plugins
]
}

② HTML 压缩

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
new HtmlWebpackPlugin({
template: __dirname + '/views/index.html',
filename: '../index.html',
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
chunksSortMode: 'dependency'
})

③ 提取公共资源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
splitChunks: {
cacheGroups: {
vendor: { // 抽离第三方插件
test: /node_modules/, // 指定是node_modules下的第三方包
chunks: 'initial',
name: 'common/vendor', // 打包后的文件名,任意命名
priority: 10 // 设置优先级,防止和自定义的公共代码提取时被覆盖,不进行打包
},
utils: { // 抽离自定义公共代码
test: /\.js$/,
chunks: 'initial',
name: 'common/utils',
minSize: 0 // 只要超出0字节就生成一个新包
}
}
}

④ 提取CSS压缩

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module: {
rules: [..., {
test: /\.css$/,
exclude: /node_modules/,
use: [
_mode === 'development' ? 'style-loader' : MiniCssExtractPlugin.loader, {
loader: 'css-loader',
options: {
importLoaders: 1
}
}, {
loader: 'postcss-loader',
options: {
ident: 'postcss'
}
}
]
}]
}
  1. 图片资源优化

雪碧图生成插件: webpack-spritesmith

  • 使用字体图标

    icomoon:将 svg 图片自动转化成 CSS 样式

  • 使用 WebP

  • 网络传输性能检测工具 —— Page Speed

  • 使用 CDN

Linux:traceroute targetIp
Windows:tracert targetIp

定义用户与目标计算机之间的路由器

页面渲染优化

Webkit技术内幕,减少重排和重绘

浏览器解释器

DOM 渲染和 GPU 硬件加速

渲染步骤:

  • 浏览器获取 DOM 树并依据样式将其分割成多个独立的渲染层

  • CPU 将每个层绘制进绘图中

  • 将位图作为纹理上传到 GPU 显卡绘制

  • GPU 将所有的渲染层缓存

  • 复合多个渲染层展示最终页面

    布局由 CPU 处理,绘制由 GPU 完成

Layers(开启渲染层功能模块)
rendering(开启渲染性能监测工具)

① Paint flashing:勾选之后会对页面中发生重绘的元素高亮显示
② Layer borders:和我们的Layer版块功能类似,它会用高亮边界突出我们页面中的各个渲染层
③ FPS meter:就是开启小黑窗,用于观察我们的GPU占用率

  • 触发渲染层
1
2
transform: translateZ(0)
backface-visibility: hidden

重排和重绘

① 重排(reflow):渲染层内的元素布局发生修改,都会导致页面重新排列,比如窗口的尺寸发生变化、删除或添加DOM元素,修改了影响元素盒子大小的CSS属性(诸如:width、height、padding)。
② 重绘(repaint):绘制,即渲染上色,所有对元素的视觉表现属性的修改,都会引发重绘。

performance 测页面重排重绘时间比

① 蓝色部分:HTML解析和网络通信占用的时间
② 黄色部分:JavaScript语句执行所占用时间
③ 紫色部分:重排占用时间
④ 绿色部分:重绘占用时间

重排是由CPU处理的,而重绘是由GPU处理的,CPU的处理效率远不及GPU,并且重排一定会引发重绘,而重绘不一定会引发重排

参考表

优化策略

  • CSS 属性操作读写分离,先读后写
  • 通过切换 class 后者 style.csstext 批量操作元素样式
  • DOM 离线更新,display:none、visibility:hidden 先隐藏元素,绘制完再显示
  • 压缩 DON 深度,少用 DOM 完成页面样式,多用伪元素
  • 图片渲染前指定大小
  • 对页面可能发生大量重排重绘的元素单独触发渲染层,使用 GPU 分担 CPU 压力

JS 阻塞性能

JavaScript Profile

负载均衡

Node.js处理IO密集型请求

事件驱动的运行机制

node的优劣

pm2实现Node.js“多线程”

npm i pm2 -g
pm2 start pm2.json

nginx搭建反向代理

反向代理

反向代理是对服务器实现负载均衡,而pm2是对进程实现负载均衡

nginx 模块:

  • handler
  • filter
  • upstream 反向代理模块,负责完成数据的接收、处理和转发

upstream配置信息:

  • ip_hash 关键字:控制用户再次访问时是否连接到前一次连接的服务器
  • server关键字:真实服务器的地址

server配置信息:

  • listen关键字:服务器监听的端口
  • location关键字:把用户的请求分配到对应的upstream上

[推荐书籍 大型网站性能监测、分析与优化(唐文)]