想做前端性能优化,就要知道从输入url按下回车那一刻,到页面呈现到你面前这个过程到底经历了什么?
从1.png的图中我们可以总结为4点:
1、DNS解析次数
2、TCP连接接时间
3、Http请求和响应
4、浏览器渲染
下面,我们将性能优化分为请求速度优化和渲染优化两部分来讲:
1、请求速度优化
资源从请求发出到接受这个部分要经历,DNS解析,TCP连接,请求和服务端响应这几个部分,并且这些部分都是要花费时间的,下面我们依次来讲述如何减少各个节点的时间:
DNS解析
说到DNS解析,我们能做的就是将解析过程前置,就是俗称的预解析,dns解析后会缓存,待真正请求资源时,就不会再花费DNS解析的时间。
注:浏览器会将我们页面中使用的域名自动进行dns解析,所以我们只需配置页面中没有出现的域名即可,但是要注意的是,要合理配置dns的解析,否则会浪费一些不必要的资源
TCP连接
讲解如何减少TCP连接次数之前,先来复习下三次握手和四次挥手:
TCP三次握手🤝
Https比Http多了SSL解析(第四次握手🤝)
TCP四次挥手👋
从上图可以看到这个每次http请求所要连接和断开的时间远远比我们想象的要多,但是页面中避免不开http的请求,所以下面我们就要来说说如何减少tcp的连接次数:
1、Keep-alive
2、握手复用
3、减少http请求
4、http2戳我👇
减少http请求我们常用的方法有:
1、合并静态资源
2、缓存
3、本地存储
缓存分为Memory cache,Disk cache,Servivce worker cache三种:
具体如何设置呢,打开控制台,仔细看一看请求头中的字段,可以总结为下图:
服务端响应
tcp建立连接后,就要面对静态资源传输速度的问题,从传输这两个字来看,肯定会和传输大小和传输距离有关,所以我们就要考虑如何将静态资源变的小,传输距离变得短?
1、Gzip
2、构建工具缩小js,css文件大小
3、CDN
CDN域名我们需要注意一下下,它和我们的域名是不一样的哦,这样它就不需要携带cookie,这样也变相的减少了请求头的大小
4、选择合理的图片类型
其他
多域名,利用浏览器的并发性,浏览器一次可以请求同域名下4-6个静态资源,所以在遇到阻塞的情况,不同域名下的静态资源则不会收到影响,所以可以利用多域名来加载静态资源,但需要注意的是,不要设置过多域名,会造成性能浪费,3-4个就好
2、浏览器渲染优化
众所周知页面解析时遇到link,js标签会停下等待资源的加载,并且为了防止浏览器裸奔,render tree的形成很重要,所以css放在头部,js放在尾部是必然的
减少重绘和回流的次数
重绘:当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color,则称为重绘
回流:当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建,这就称为回流
注意:回流必将引起重绘,而重绘不一定会引起回流
回流何时发生:
1、添加或者删除可见的DOM元素
2、元素位置改变
3、当页面布局或几何属性改变——边距、填充、边框、宽度和高度
4、内容改变——比如文本改变或者图片大小改变而引起的计算值宽度和高度改变
5、页面渲染初始化
6、浏览器窗口尺寸改变——resize事件发生时
7、获取offsetTop/Left/Width/Height , scrollTop/Left/Width/Height ,
clientTop/Left/Width/Height,Width/Height
所以:
1、用class来改变样式
2、脱离文档流,display:none或者position:absolute/fixed
3、dom结构离线处理后一次插入
4、不要经常访问会引起浏览器flush队列的属性,如果你确实要访问,利用缓存
懒加载
原则就是将必须呈现的东西快速加载,其余的资源可以按需加载,让用户快速看到页面,减少等待时间
1、白屏时间(从按下回车到第一个元素出现的时间)
2、首屏时间(第一屏展示出的时间)
总结
极端的总结为一句话😁:请求能少发就少发,资源能多小就多小,请求距离能多短就多短,dom操作能不变就不变,能一次做的绝不两次做
性能优化是一个漫长的过程,慢慢体验⛽️