网络策略优化
使用dns-prefetch
dns-prefetch 是DNS的预解析技术,浏览网页时,浏览器会在加载网页时对网页中的域名进行解析缓存,这样在单击当前网页中的连接时就无需进行DNS的解析,减少用户等待时间,提高用户体验。
dns预解析是与页面加载是并行处理的,且不会影响到页面加载的性能.
访问以图片为主的移动端网站时,使用DNS预解析的情意中下页面加载时间可以减少5%
设置:
<meta http-equiv="x-dns-prefetch-control" content="on" />
<link rel="dns-prefetch" href="http://www.baidu.com" />
禁止隐式的dns预解析:
<meta http-equiv="x-dns-prefetch-control" content="off">
减少http请求
- 合并js文件 css文件
- 使用雪碧图
- base64编码图片
使用http缓存
- 强缓存 静态资源文件 使用hash命名 文件没有修改直接从缓存中获取
- 协商缓存 一般入口index.html 设置协商缓存 每次请求都向服务端发送请求判断资源是否有修改
使用http2.0
- 多路复用: 数据分帧处理
- 头部压缩
- 服务器主动推送
避免重定向
301 302 重定向会降低响应速度
CDN存放静态资源
CDN能非常有效的加快网站静态资源的访问速度
资源压缩
gzip压缩 js css html 图片压缩
合理使用preload prefetch
preload 预加载 当前页面使用的资源 prefetch 页面空闲时间加载 提前加载之后可能会用到的资源 不一定是当前页面使用的
<link rel="preload" as="style" href="index.css">
<link rel="prefetch" as="style" href="index.css">
浏览器渲染优化策略
- 避免页面的重排重绘
- 使用css3合成动画 开启gpu加速 减少cpu压力
- 图片渲染时添加宽高属性 宽高固定 图片不会根据内容动态改变宽高 便不会触发重排重绘
- 使用will-change: transform;将元素独立为一个单独的图层。(定位、透明、transform、clip都会产生独立图层)
导致重排操作:
- 页面首次渲染(无可避免)
- 浏览器窗口大小改变
- 元素尺寸改变 (宽高 边框 边距)
- 元素内容发生变化 (文字数量 文字字体大小 图片大小)
- 添加或者删除可见的元素
- 激活伪类 :hover
- 查询属性 或者调用某些方法:(属性和方法都需要返回最新的布局信息,因此浏览器不得不触发回流重绘来返回正确的值) offsetTop getComputedStyle() getBoundingClientRect() scrollIntoView() clientTop() scrollHeight()
如何优化:
- 合并style样式的修改 使用css统一修改
- 减少dom的直接获取 dom的直接获取会导致强制重排获取最新的信息
- 使用transform替代position
- 使用display:none 隐藏元素后 进行修改 修改完成 设置 显示
- 通过 documentFragment 创建一个 dom 文档片段,在它上面批量操作 dom,操作完成之后,再添加到文档中,这样只会触发一次重排
- GPU 加速通常包括以下几个部分:Canvas2D,布局合成, CSS3转换(transitions),CSS3 3D变换(transforms),WebGL和视频(video)。
静态资源优化
合理选择图片格式
- jpg: 适合色彩丰富的图、Banner图。不适合:图形文字、图标、不支持透明度
- png: 适合纯色、透明、图标,支持纯透明和半透明。不适合色彩丰富图片,因为无损储存会导致储存体积大于jpeg
- gif: 适合动画、可以动的图标。支持纯透明但不支持半透明,不适合色彩丰富的图片。埋点信息通常也会使用gif发送,因为1x1的gif图发送的网络请求比普通的get请求要小一些
- webp: 支持纯透明和半透明,可以保证图片质量和较小的体积,适合Chrome和移动端浏览器。不适合其他浏览器。
- svg: 矢量格式,大小非常小,但渲染成本过高,适合小且色彩单一的图标
图片优化
- 减少图片尺寸大小 节约流量
- 设置alt属性 图片无法显示时会展示的内容
- srcset size属性在不同设备大小下的设置
- 使用base64 减少图片请求
- 雪碧图合并图片
HTML优化
- 使用语义化标签 meta设置TDK 利于SEO
- 减少标签嵌套 减少dom数量
- 避免table布局
- 提前声明字符编码,让浏览器快速确定如何渲染网页内容
<html lang="en">
<meta charset="UTF-8">
</html>
- 减少iframe,子iframe会阻塞父级的onload事件。可以使用js动态给iframe赋值,就能解决这个问题。
CSS优化
- 减少伪类选择器,减少选择器层数、减少通配符选择器、减少正则选择器
- 避免使用css表达式
- css使用外链 可以使用缓存
- link标签上添加媒体字段 只加载有效的css
<link href="a.css" media="screnn and (max-width: 600px)">
- 减少@import 使用 因为他使用串行加载 会等到页面加载完成后再加载,导致页面没有样式出现
JS优化
- script标签使用defer async 属性 异步加载js文件
- 减少dom操作 避免反复获取dom 对获取的dom进行缓存(js是js线程 dom是渲染线程 频繁获取dom会造成多次线程之间通信)
- 使用document.documentFragment。避免频繁访问dom
- 使用webworker执行复杂的计算
- 虚拟滚动 懒加载
- 使用requestAnimationFrame实现动画 requestIdleCallback 进行空闲时任务处理
- 使用事件委托
- 尽量使用canvas css3动画
- 使用节流防抖避免频繁触发事件
webpack优化
减小包体积
-
tree-shaking 删除项目中未被引用的代码 Webpack4 开启生产环境就会自动启动这个优化功能。 静态编译时,在ast中分析哪些没有被使用到,然后删除
-
Scope Hoisting 会分析出模块之间的依赖关系,尽可能的把打包出来的模块合并到一个函数中去 Webpack4 中你希望开启这个功能,只需要启用 optimization.concatenateModules 就可以了。
module.exports = {
optimization: {
concatenateModules: true
}
}
- purgecss-webpack-plugin 清除无用css
webpack打包构建优化
- HappyPack 开启多个线程 loader的编译并行执行(webpack5弃用)
- minicssextractPlugin: 将css抽离 单独打包 支持按需加载 异步加载 不会重复编译 只适用于css
- hardSourcewebpackPlugin 为模块提供中间缓存 缓存存放路径 node-modules/.cache/hard-source 首次构建无太大变化,二次构建 时间减少约80%
优化resolve配置
- alias 简化模块的引用
resolve:{
alias: {
'~': resolve('src'),
'@': resolve('src'),
'components': resolve('src/components')
}
}
- extensions 省略文件后缀
按照数组从左到右顺序解析模块
注意:高频文件放到前面,手动配置后默认配置会失效 保留默认配置 可使用... 代表
const config = {
//...
resolve: {
extensions: ['.js', '.json', '.wasm'],
},
};
- modules 告诉webpack解析模块时应该优先搜索的目录 减少依赖文件查找时间
webpack 优先查找src下目录,
const path = require('path');
// 路径处理方法
function resolve(dir){
return path.join(__dirname, dir);
}
const config = {
resolve: {
modules: [resolve('src'), 'node_modules'],
},
};
- externals 配置从输出的bundle中排除依赖的方法 从cdn引入的jquery不需要打包 直接使用链接
const config = {
externals: {
jquery: 'jQuery',
},
};
Vue优化
- v-if 和 v-show的合理选择
- 使用计算属性computed缓存计算结果
- 使用keep-alive缓存组件状态
- 保证key的唯一性
- import() 路由懒加载 按需引入组件
- 在destroy生命周期销毁 事件监听 定时器
React优化
- 组件状态变与不变分离
- React.memo 缓存组件
- useMemo 缓存大量计算
- useCallback 缓存函数的引用
- React.pureComponent 纯组件 自带shouldComponentUpdate功能
- shouldComponentUpdate 生命周期进行状态比较
- 避免使用内联对象 react会在每次渲染时重新生成内联对象引用 这会导致此组件prop发生改变 浅比较始终返回false 导致组件重复渲染
- 避免在组件上使用匿名函数
- 延迟加载 按需加载组件React.lazy React.suspense
- 使用React.Fragement 避免生成额外的dom元素