性能优化是一个老生常谈的话题,它并不是某一块知识点而是贯穿于整个html的打包到渲染整个流程,首先先复习一下浏览器输入url的过程。
首先我们需要通过 DNS(域名解析系统)将 URL 解析为对应的 IP 地址,然后与这个 IP 地址确定的那台服务器建立起 TCP 网络连接,随后我们向服务端抛出我们的 HTTP 请求,服务端处理完我们的请求之后,把目标数据放在 HTTP 响应里返回给客户端,拿到响应数据的浏览器就可以开始走一个渲染的流程。
我们将这个过程切分为如下的过程片段:
- DNS 解析
- TCP 连接
- HTTP 请求抛出
- 服务端处理请求,HTTP 响应返回
- 浏览器拿到响应数据,解析响应内容,把解析的结果展示给用户
我们接下来要做的事情,就是针对这五个过程进行分解,各个提问,各个击破。
具体来说,DNS 解析花时间,能不能尽量减少解析次数或者把解析前置?能——浏览器 DNS 缓存和 DNS prefetch。TCP 每次的三次握手都急死人,有没有解决方案?有——长连接、预连接、接入 SPDY 协议。如果说这两个过程的优化往往需要我们和团队的服务端工程师协作完成,前端单方面可以做的努力有限,那么 HTTP 请求呢?——在减少请求次数和减小请求体积方面,我们应该是专家!再者,服务器越远,一次请求就越慢,那部署时就把静态资源放在离我们更近的 CDN 上是不是就能更快一些?
DNS预解析
<link rel="dns-prefetch" href="//example.com">以上提到的都是网络层面的性能优化。再往下走就是浏览器端的性能优化——这部分涉及资源加载优化、服务端渲染、浏览器缓存机制的利用、DOM 树的构建、网页排版和渲染过程、回流与重绘的考量、DOM 操作的合理规避等等——这正是前端工程师可以真正一展拳脚的地方。学习这些知识,不仅可以帮助我们从根本上提升页面性能,更能够大大加深个人对浏览器底层原理、运行机制的理解,一举两得!
我们整个的知识图谱,用思维导图展示如下:

由上文可知,对于 DNS 解析和 TCP 连接两个步骤,我们前端可以做的努力非常有限。相比之下,HTTP 连接这一层面的优化才是我们网络优化的核心。
HTTP 优化有两个大的方向:
- 减少http请求次数
- 减少单次请求所花费的时间(缩小数据包)
1.webpack相关优化
这两个优化点直直地指向了我们日常开发中非常常见的操作——资源的压缩与合并。没错,这就是我们每天用构建工具在做的事情。而时下最主流的构建工具无疑是 webpack,所以我们这节的主要任务就是围绕业界霸主 webpack 来做文章。webpack优化从4个方向下手:缓存、多核、抽离以及拆分
webpack 的优化瓶颈,主要是两个方面:
- webpack 的构建过程太花时间(这个不属于页面性能优化)
- webpack 打包的结果体积太大
对于webpack构建优化的方法
- DllPlugin打包一些不常更换的文件如jq、react,这个还能实现构建优化一举两得
- happyPack在打包大型项目,能实现构建优化,不能缩小打包体积
- 选取合适的source-map
- 少用extensions后缀找文件
- 使用include exclude
- babel-loader使用缓存
- resolve module
对于webpack缩小打包体积的方法
- tree shaking
- UglifyJsPlugin,optimize-css-assets-webpack-plugin压缩css资源成单行
- externals排除打包公共文件,使用cdn引入(需要用到CDN资源)
- CompressionPlugin开启gzip压缩,配合nginx开启
- 组件库按需引入
- 懒加载
关于gzip的文章:zhuanlan.zhihu.com/p/37429159
webpack好文www.xbhub.com/wiki/webpac…
对于减少http的方法
- url-loader limit图片转base64
- 防抖节流
2.浏览器缓存机制
分为强弱缓存,服务端配置,如果有Etag字段,那么浏览器就会将本次缓存写入硬盘中。
只有是第二次请求才会有优化效果
3.图片优化
在我们实际开发中,真正占用了大量网络传输资源的,并不是这些文件,而是图片,如果你对图片进行了优化工作,你能立刻看见明显的效果。
方法:
- 不要在html缩放图片
- 使用iconfont
- 使用webp格式图片
- base64
4.CDN存放静态资源
首次访问加速的利器
cookie好文mp.weixin.qq.com/s/oOGIuJCpl…
5.页面渲染优化
1.css优化
- 避免使用通配符,只对需要用到的元素进行选择
- 少用标签选择器。如果可以,用类选择器替代
- 使用cdn
2.js优化
- 使用async和defer,async 模式下,JS 不会阻塞浏览器做任何其它的事情。它的加载是异步的,当它加载结束,JS 脚本会立即执行。defer 模式下,JS 的加载是异步的,执行是被推迟的。等整个文档解析完成、DOMContentLoaded 事件即将被触发时,被标记了 defer 的 JS 文件才会开始依次执行。
- js改变css时使用类统一改
- js在添加dom时可以使用createDocumentFragment
- 异步渲染
- vue中的优化
- 图片懒加载