- 一般情况下,都是通过什么手段或者方法来进行性能分析的
- 长列表优化(vue-vitual-scoll-list和vue-virtual-scroller)
- 突破浏览器并发限制方法有哪些?
- 在项目中如何使资源用缓存最合理?
- canvas 合成图片或者或者画视频生成base64时候卡顿
性能优化总结:减少请求次数、减小资源大小、提高响应和加载速度、优化资源加载时机、优化加载方式。
主要从两个方面进行优化 构建优化、网络资源优化
构建优化
Gzip
gzip 压缩效率非常高,通常可以达到 70% 的压缩率,也就是说,如果你的网页有 30K,压缩之后也就10K左右。compression-webpack-plugin,这个插件不仅能够gzip压缩,还能够去除console.log、debugger,gzip压缩需要服务端配合开启
const CompressionPlugin = require('compression-webpack-plugin')
configureWebpack: config => {
config.plugins.push(new CompressionPlugin())
}
去除 console.log
线上不应该看到日志信息,所以需要去掉console.log, 而有时候我们忘记手动去掉,所以用以下方式可以做到自动去除
configureWebpack: config => {
const TerserPlugin = require('terser-webpack-plugin')
config.optimization.minimizer.push(
new TerserPlugin({
extractComments: false,
terserOptions: { compress: { drop_console: true } },
})
)
}
// minimizer: [
// new UglifyJsPlugin({
// uglifyOptions: {
// compress: {
// drop_debugger: true, // debugger
// drop_console: true,
// pure_funcs: ['console.log'] // 移除console
// }
// }
// })
// ]
去除 SourceMap
module.exports = {
productionSourceMap: false,
}
CDN减少打包体积
CDN的全称是Content Delivery Network,即内容分发网络。CDN的通俗理解就是网站加速,不仅能减少打包体积,还能增加网站相应速度。(浏览器对同一个域名的资源请求并发有限制,如果资源比较多,可以用多个域名。)
configureWebpack: config => {
config.externals = {
'Vue': 'Vue',
'element-ui': 'element-ui'
}
}
路由懒加载(按需加载)
主要解决首屏加载速度,提高用户体验,要注意的是,要关闭prefetch,这个配置默认是打开的,说的是在空闲时期加载,其实还是会多少影响首屏加载速度.
chainWebpack: config => {
config.plugins.delete('prefetch')
},
资源和并与压缩
减少http请求数量
比如嵌套路由,一个模块可以编译成一个chunkname,本来也不是特别大。这样可以达到减少请求次数.
第三方插件的按需引入
我们在项目中经常会需要引入第三方插件,如果我们直接引入整个插件,会导致项目的体积太大,我们可以借助 babel-plugin-component ,然后可以只引入需要的组件,以达到减小项目体积的目的。以下为项目中引入 element-ui 组件库为例:
- 1)首先,安装 babel-plugin-component npm install babel-plugin-component -D
- 2)然后,将 .babelrc 修改为:
{
"presets": [["es2015", { "modules": false }]],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
- 3)在 main.js 中引入部分组件:
import Vue from 'vue';
import { Button, Select } from 'element-ui';
Vue.use(Button)
Vue.use(Select)
提取公共代码
Webpack 内置了专门用于提取多个Chunk 中的公共部分的插件 split-chunks-plugin,根据不同需求可以做不同的配置:
configureWebpack: config => {
/** 去掉console.log debugger sourceMap*/
console.log()
config.optimization = {
splitChunks: {
chunks: 'async', // 代码分割时对异步代码生效,all:所有代码有效,inital:同步代码有效
minSize: 30000, // 代码分割最小的模块大小,引入的模块大于 30000B 才做代码分割
maxSize: 0, // 代码分割最大的模块大小,大于这个值要进行代码分割,一般使用默认值
minChunks: 1, // 引入的次数大于等于1时才进行代码分割
maxAsyncRequests: 6, // 最大的异步请求数量,也就是同时加载的模块最大模块数量
maxInitialRequests: 4, // 入口文件做代码分割最多分成 4 个 js 文件
automaticNameDelimiter: '~', // 文件生成时的连接符
automaticNameMaxLength: 30, // 自动生成的文件名的最大长度
cacheGroups: {
vendors: {
name: "chunk-vendors1111", //
test: /[\\/]node_modules[\\/]/,
priority: -20, // 分离规则的优先级,优先级越高,则优先匹配。
chunks: "initial"
},
'element-ui': {
name: 'chunk-elementUI', // split elementUI into a single package
priority: -5, // the weight needs to be larger than libs and app or it will be packaged into libs or app
test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
},
},
}
}
}
}
网络资源优化
缓存 这是一个链接
合理使用缓存
缓存可以说是性能优化中最高效的一种手段
三级缓存:
- 先查找内存,如果内存中存在,从内存中加载;
- 如果内存中未查找到,选择硬盘获取,如果硬盘中有,从硬盘中加载;
- 如果硬盘中未查找到,那就进行网络请求;
- 加载到的资源缓存到硬盘和内存;
HTTP状态码:
-
200 form memory cache 不访问服务器,一般已经加载过该资源且缓存在了内存当中,直接从内存中读取缓存。浏览器关闭后,数据将不存在(资源被释放掉了),再次打开相同的页面时,不会出现from memory cache。
-
200 from disk cache 不访问服务器,已经在之前的某个时间加载过该资源,直接从硬盘中读取缓存,关闭浏览器后,数据依然存在,此资源不会随着该页面的关闭而释放掉下次打开仍然会是from disk cache。
-
304 Not Modified 访问服务器,发现数据没有更新,服务器返回此状态码。然后从缓存中读取数据。
一、vue的所有资源修改后打包出来的名称都会改变,所以可以使用强缓存,对css、js、png、ttf、jpg等
location ~* \.(css|js|png|jpg|jpeg|gif|gz|svg|mp4|ogg|ogv|webm|htc|xml|woff)$ {
access_log off;
add_header Cache-Control max-age=604800;
}
二、html文件每次编译名称不会改变,所以使用协商缓存,html文件有改动就会立即更新, max-age=no-cache代表直接进入协商缓存,文件改动会自动更新,不改动会返回304, 确保index.html 里面加载的js css等资源确保每次更新完之后都会拿到最新的资源
location ~* \.(html)$ {
access_log off;
add_header Cache-Control max-age=no-cache;
}
HTTP2
特性
-
多路复用,无需多个TCP连接,因为其允许在单一的HTTP2连接上发起多重请求,因此可以不用依赖建立多个TCP连接。
-
二进制分帧,将所有要传输的消息采用二进制编码,并且会将信息分割为更小的消息块。
-
头部压缩,用HPACK技术压缩头部,减小报文大小
-
服务端推送,服务端可以在客户端发起请求前发送数据,换句话说,服务端可以对客户端的一个请求发送多个相应,并且资源可以正常缓存。 HTTP客户端一般对同一个服务器的并发连接个数都是有限制的。
实际上,浏览器确实使用并行连接,但它们将并行连接的总数限制为少量(通常为四个)。服务器可以自由地关闭来自特定客户端的过多连接。
一些主流浏览器对HTTP 1.1和HTTP 1.0的最大并发连接数目,可以参考如下表格:
ngnix 相关配置
server {
listen 443 ssl http2;
}
能够很好的利用服务器宽带性能
注意:使用 http2 的前提是必须是 https
资源预加载
对当前页面需要的资源,使用 preload 进行预加载,对其它页面需要的资源进行 prefetch 预加载
preload
preload 页面加载的过程中,在浏览器开始主体渲染之前加载。
<!-- 对sty1e.cs5和 index.js进行pre1oad预加载 -->
<link rel="preload" href="style.css" as="style">
<link rel="preload" href="index.js" as="script">
prefetch
prefetch 页面加载完成后,利用空闲时间提前加载。
<!--对资源进行 prefetch预加载-->
<link rel="prefetch" href="next.css">
<link rel="prefetch" href="next.js">
注意:vue-cli 默认开启 prefetch ,可在 vue.config.js 中全局禁用 prefetch ,再针对指定模块开启。
chainWebpack: config => {
config.plugins.delete('prefetch')
}
dns-prefetch
页面加载完成后,利用空闲时间提前加载。
<link rel="dns-prefetch" href="//example.com">
异步无阻塞加载JS
页面加载完成后,利用空闲时间提前加载。 异步加载 js 文件,并且不会阻塞页面的渲染。
defer
<script src="d.js" defer></script>
<script src="e.js" defer></script>
- 不阻止解析 document, 并行下载 d.js, e.js
- 即使下载完 d.js, e.js 仍继续解析 document
- 按照页面中出现的顺序,在其他同步脚本执行后,DOMContentLoaded 事件前 依次执行 d.js, e.js。
async
<script src="b.js" async></script>
<script src="c.js" async></script>
- 不阻止解析 document, 并行下载 b.js, c.js
- 当脚本下载完后立即执行。(两者执行顺序不确定,执行阶段不确定,可能在 DOMContentLoaded 事件前或者后 )
图片优化
- 格式选择 png、svg、webp
- 雪碧图(优点: 减少网站的http请求数量 缺点: 整张图片比较大时,加载速度比较慢)雪碧图制作工具 spritecow
- base64 (图标大小最好小于5kb)
用户体验优化
- 菊花loading,在加载资源过程之中,可以提供loading。此菊花loading不是那菊花。所以可以自由选择自己喜欢的菊花。
- 骨架屏幕 在首屏加载资源较多,可能会出现白屏和闪屏的情况(antv)
如果追求极致的性能瓶颈 可以关注chrome->performance工具
具体内容可以参考这是一个参考链接
减少css重排重绘
触发reflow的属性
布局 | 定位 | 字体排版 |
---|---|---|
width | top | text-align |
height | right | overflow-y |
padding | bottom | font-weight |
margin | left | overflow |
display | float | font-family |
border-width | clear | line-height |
border | position | vertical-align |
min-height | font-size | white-space |
触发repaint的属性
- border-style
- border-radius
- visibility
- text-decoration
- outline-color
- outline
- outline-style
- outline-width
- background
- background-image
- background-position
- background-repeat
- background-size
- box-shadow
- color