web前端性能优化:让用户觉得网页加载贼快
根据用户按下回车键后的一系列事件,找出对应的优化方案
chrome的Audits
目的
让用户觉得网页加载贼快
实现原理
当用户输入完网址、按下回车键后
- 看本地有没有缓存
- DNS查询
- 建立tcp连接
- 发送请求
- 等待服务端处理,然后发送响应
- 接收响应
- 接收完成后得到HTML,逐行解析HTML
- 解析到css则下载css文件【多个css文件可以最多同时下载4个】
- 解析到js则下载js文件,js会阻塞HTML渲染
优化方案
css放在head里,js放在body最后
把CSS放在HTML头部是为了让浏览器尽早生成CSSOM,然后往下解析HTML的时候可以一次性生成最终的 RenderTree,渲染一次即可。如果把CSS放在底部,会出现渲染卡顿的现象,影响性能和体验。
由于js会阻塞渲染,因此把js放在底部,可以保证浏览器优先渲染完所有的HTML内容,让用户先看到内容,体验好。另外,JS中可能涉及到DOM的操作,得等到DOM解析完,才能获取DOM元素。
减少域名数量,降低DNS查询
假设baidu.com/index.html的css文件放在a.com/xxx.css,js文件放在b.com/xxx.js
那么DNS就会查询3次(分别查询baidu.com、a.com、b.com的DNS)
将所有文件放在1个域名下,这样就只有1次DNS查询了
DNS预解析
|
|
tcp连接复用
在请求头加上keep-alive
http/2.0多路复用
发送请求时减小cookie
浏览器每次发送请求时都会带上cookie,所以减小cookie体积可以优化web性能
增加域名数量,从而增加资源下载的并发数
浏览器可以最多同时下载4个文件,假设有10个js文件,那么必须等前4个下载完,才能继续下载后面的js文件。
这时,如果将前4个js文件放在a.com,5~8放在b.com,9、10放在c.com,那么这10个js文件就能同时一起下载
!注意:当文件数量少时,减少域名数量,降低DNS查询;当文件数量很多时,增加域名数量,从而增加资源下载的并发数
压缩合并文件,减少HTTP请求
将多个css合并到1个css文件
将多个js合并到1个js文件
雪碧图
多个图片合并到一张图上
小图标用base64
压缩css、js、图片文件
利用浏览器缓存
浏览器缓存分为强缓存和协商缓存
- 浏览器在加载资源时,先根据这个资源的一些http header判断它是否命中强缓存,强缓存如果命中,浏览器直接从本地缓存中读取资源,不会发请求到服务器。比如某个css文件,如果浏览器在加载它所在的网页时,这个css文件命中了强缓存,浏览器就直接从缓存中加载这个css,连请求都不会发送到服务器;
- 当强缓存没有命中的时候,浏览器一定会发送一个请求到服务器,通过服务器端依据资源的另外一些http header验证这个资源是否命中协商缓存,如果协商缓存命中,服务器会返回304,但是不会下载这个资源,而是告诉客户端可以直接从缓存中加载这个资源,于是浏览器就又会从本地缓存中去加载这个资源;
- 强缓存与协商缓存的共同点是:如果命中,都是从本地缓存中加载资源,而不是从服务器加载资源数据;区别是:强缓存不发送请求到服务器,协商缓存会发送请求到服务器。
- 当协商缓存也没有命中的时候,浏览器直接从服务器加载资源数据。
强缓存
Expires 和 Cache-Control 都是强缓存。强缓存表示在缓存期间不发送请求,直接使用本地缓存
|
|
表示资源会在 Wed, 22 Oct 2018 08:41:00 GMT 后过期,需要再次请求。并且 Expires 属于绝对时间,如果手动修改了本地时间,可能会造成缓存失效。
|
|
表示资源会在 300 秒后过期,需要再次请求。属于相对时间,不受本地时间的影响。
同时存在时,听 Cache-control 的
协商缓存
如果缓存过期了,我们就可以使用协商缓存来解决问题。
协商缓存会向服务端发送http请求,询问是否继续使用本地缓存,如果要使用本地缓存,则服务端返回304状态码。
Last-Modified 和 If-Modified-Since
Last-Modified 表示文件最后修改日期
第一次访问后端,后端返回文件和Last-Modified(假设2018-01-01);再次访问后端时,请求头的If-Modified-Since会把Last-Modified的值给带上,后端接收到该值后,与服务器上的文件进行比较,如果服务器上的文件最后修改日期是2018-01-01,那就说明文件没有修改过,只返回304,不返回文件;如果服务器上的文件最后修改日期是2018-02-01,说明文件有更新,于是返回新的文件和Last-Modified值
但是如果在本地打开缓存文件,就会造成 Last-Modified 被修改【此时最后修改时间改变,但是文件本身没有做修改,造成重新下载资源】,所以在 HTTP / 1.1 出现了 ETag 。
ETag 和 If-None-Match
假设1分钟前请求了a.css,服务器下发了一个Etag是xxxxx;当浏览器再次请求a.css时,请求头中的 If-None-Match 会将这个 ETag值 发送给服务器,后端比较该资源 ETag 是否相同,两端的Etag值不同的话说明文件有更新,则发送新的资源和Etag。如果服务器发现该资源的Etag没有变动,那么只发送响应304(not modified),而不会下载这个css文件
ETag 优先级比 Last-Modified 高。
!注意:Etag会发送请求,返回304,不下载文件;Cache-Control直接不发送请求
开启Gzip压缩
服务器用gzip压缩HTML、CSS、JS等各种文件后,将压缩包发送给浏览器
浏览器接收到压缩包后,发现响应头是Content-Encoding:gzip
,于是浏览器解压压缩包
!注意:浏览器解压压缩包会消耗浏览器cpu,所以体积较小的文件不需要gzip,体积较大的文件适用gzip
使用CDN
- CDN可以增加域名数量,从而增加请求的并发数,达到同时下载多个文件的目的
- 内容分发网络:将静态资源分发到全球各地,让不同地区的人都能快速访问距离你最近的那个服务器
- CDN没有cookie,因为cookie是发送给自己的服务器的
尽量使用css3动画代替js动画
使用transform:translate3d(0,0,0) 开启GPU加速
尽量使用translateX/Y代替left/top的移动
使用事件委托减少监听器
懒加载
|
|
首先展示loading图
当执行到尾部的js文件时,再将图片链接换成真实的图片地址
预加载
减少DOM操作
- 缓存DOM查询,在for循环中缓存元素的length
- 合并DOM插入,利用文档片段【document.createDocumentFragment】
使用SSR后端渲染
直接返回渲染好的html文件,这样就不需要发送ajax请求获取数据了
节流
|
|
chrome调试方法
chrome开发者工具 –> Audits –> Perform an audit –> run audit
运行完后会告诉你哪里需要进行优化