性能优化篇
新 2019-07-07
interview
# 1、图片优化
- 压缩图片大小(webpack 插件)
- 使用 css 代替装饰类图片
- 雪碧图
- iconfont
- 小图使用 base64 格式
- 移动端根据设备宽度加载相应的图片
# 如何选择图片格式
图片格式 | 压缩方式 | 透明度 | 动画 | 浏览器兼容 | 适应场景 |
---|---|---|---|---|---|
JPEG | 有损压缩 | 不支持 | 不支持 | 所有 | 复杂颜色及形状、尤其是照片 |
GIF | 无损压缩 | 支持 | 支持 | 所有 | 简单颜色,动画 |
PNG | 无损压缩 | 支持 | 不支持 | 所有 | 需要透明时 |
APNG | 无损压缩 | 支持 | 支持 | FirefoxSafariiOS Safari | 需要半透明效果的动画 |
WebP | 有损压缩 | 支持 | 支持 | ChromeOperaAndroid ChromeAndroid Browser | 复杂颜色及形状浏览器平台可预知 |
SVG | 无损压缩 | 支持 | 支持 | 所有(IE8以上) | 简单图形,需要良好的放缩体验需要动态控制图片特效 |
# 2、防抖节流
- 防抖
- 在事件被触发 n 秒后再执行回调,如果在这 n 秒内又被触发,则重新计时(王者荣耀的回城)
- 频繁点击、输入框输入掉接口
- 节流
- 规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。
- 监听 scroll 、resize 等事件
# 3、预加载和懒加载
合理使用浏览器的预取指令 prefetch 和预加载指令 preload
使用 link 标签的 rel 属性设置 prefetch(这段资源将会在未来某个导航或者功能要用到,但是本资源的下载顺序权重比较低,prefetch 通常用于加速下一次导航)、preload(preload 将会把资源得下载顺序权重提高,使得关键数据提前下载好,优化页面打开速度)
# 4、http 缓存
加速或者减少 HTTP 请求,合理使用浏览器强缓存和协商缓存
- 强缓存 200 (优先级从高到低分别是 Pragma -> Cache-Control -> Expires)
- Pragma:支持 http1.0;可设置 no-cache,表示不缓存资源;优先级最高
- Cache-Control:支持 http1.1;可设置 no-cache、max-age = 3600 (s);优先级中等
- Expires:支持 http1.0;可设置一个格林尼治时间;优先级最低
- 协商缓存 304
- ETag/If-None-Match 高
- Last-Modified/If-Modified-Since 低
总结:
- 首先通过
Cache-Control
验证强缓存是否可用,如果强缓存可用,直接使用 - 否则进入协商缓存,即发送 HTTP 请求,服务器通过请求头中的
Last-Modified
或者ETag
字段检查资源是否更新- 若资源更新,返回资源和 200 状态码
- 否则,返回 304,告诉浏览器直接从缓存获取资源
# 5、webpack
- 大小
- 按需加载 (require.ensure 或 动态 import )
- 代码压缩混淆 (html,css,js) tree shaking
- 代码分离,提取公共模块(SplitChunksPlugin 或者 html-webpack-externals-plugin cdn 引入基础包)
- 使用 analyzer 可视化分析包大小
- 速度
- 开启 production 模式 (tree shaking, scope hoisting)
- 多线程 happypack
- 使用 DllPlugin & DllReferencePlugin 提前打包公共依赖
- 合理使用 sourcemap
- include | exclude 限定和缓存 loader
- 使用 SpeedMeasureWebpackPlugin 可视化分析各个环节的速度
# 6、本地存储
cookie
- 4kb
- 服务端通过 Set-Cookie 设置
- 添加 http-only 属性,不能通过 js 操作 cookie,减少 xss
- 同源 -- 协议、域名、端口
localStorage
- 5Mb
- 长期存在。模拟实现过期功能
- 同源 -- 协议、域名、端口
sessionStorage
- 5Mb
- 会话级、tab 级别
- 同源 -- 协议、域名、端口、窗口
indexDB
# 7、cdn
静态资源尽量使用 CDN 加载,由于浏览器对于单个域名有并发请求上限,可以考虑使用多个 CDN 域名。对于 CDN 加载静态资源需要注意 CDN 域名要与主站不同,否则每次请求都会带上主站的 Cookie。
# 8、浏览器
- css 文件在
<head>
标签中引入,js 文件在<body>
标签中引入,优化关键渲染路径 - 减少重绘和回流,任何会导致重绘和回流的操作都应减少执行,可将多次操作合并为一次
- 减少 DOM 的访问次数,可以将 DOM 缓存到变量中
- 动画尽量使用 CSS3 动画属性来实现,开启 GPU 硬件加速
- 尽量采用事件委托的方式进行事件绑定,避免大量绑定导致内存占用过多
# 9、首屏优化
- Vue-Router 路由懒加载(利用 Webpack 的代码切割)
- 使用 CDN 加速,将通用的库从 vendor 进行抽离
- Nginx 的 gzip 压缩
- Vue 异步组件
- 服务端渲染 SSR
- 如果使用了一些 UI 库,采用按需加载
- 如果首屏为登录页,可以做成多入口
- 使用 link 标签的 rel 属性设置 prefetch(这段资源将会在未来某个导航或者功能要用到,但是本资源的下载顺序权重比较低,prefetch 通常用于加速下一次导航)、preload(preload 将会把资源得下载顺序权重提高,使得关键数据提前下载好,优化页面打开速度)
# 10、react 中优化
- 减少无用渲染:使用 PureComponents 优化类组件;使用 React.memo 优化函数组件
- 在 shouldComponentUpdate 中添加自定义逻辑判断是否需要重新描绘 dom
- 使用 Suspense 和 lazy 懒加载组件
- 使用 Fragment 避免额外标记
- 事件绑定时不使用内联函数定义
- 在 componentDidCatch 中捕获错误并作错误处理
- 列表渲染使用唯一 key,避免使用 index 作为 key
- 组件卸载时移除定时器及事件监听
# 优化类文章
# (附个人编码优化)
- 编码前多思考:可读性、可维护性、封装性、性能、安全;
- 了解下函数式编程 - 代码中多使用纯函数;
- 独立功能封装成函数,重复代码提取成函数,如果多处使用考虑是否需要提取出来作为一个模块对外提供;
- 不相关的功能逻辑单独封装,比如数据获取、页面渲染,数据计算等;
- 给自己一个代码开发规范;
- 多多使用es6的新特性,一些语法糖,这样有利于引出你不熟悉的东西,然后去解决掉;
- 了解下设计模式,如发布订阅,单例等,想办法在工作中用到;
- 性能是至关重要的,数据的加载机制和拿到数据后的渲染机制是很重要的。从一个普通用户的角度考虑体验;
阅读量: