对于 HTTP1.1 ,减少 HTTP 请求
如果服务端还是 HTTP 1.1 协议,那么浏览器并发的 HTTP 请求是由数量限制的(比如桌面浏览器并发请求可能是 8 个,手机浏览器是 6 个),如果一下子并发的几十个请求那么会有很多请求会停下来等,等前面的请求好了下一个再进去,这样就延长了整个页面的加载时间。
对于 HTTP 2 ,拆包,充分利用缓存
如果服务端已经开启了 http2,那么不存在并发请求的限制。
拆包,充分利用缓存
项目中有很多依赖库如 React、lodash ,它们的版本是基本不会发生变化的。将这些不会发生变化的包单独拆出来,加上缓存,那么二次请求时这些不变的包都不会被拉取,这样就可以提升网站整体的性能。
压缩资源文件减小请求大小
文件大小越小当然加载速度就越快。
可对代码进行压缩,去掉空格、注释、变量替换,在传输时,使用 gzip 等压缩方式也可以降低资源文件的大小。
缓存分类
- 强缓存
- 直接从浏览器缓存中读取,不去后台查询是否过期
Exprise
过期时间Cache-Control:max-age=3600
过期秒数
- 协商缓存
- 每次使用缓存之前先去后台确认一下
Last-Modified
If-Modified-Since
上次修改时间Etag
If-None-Match
- 如何区别
- 是否设置了
no-cache
- 是否设置了
利用缓存机制,尽可能使用缓存减少请求
浏览器是有缓存机制的,在返回资源的时候设置一个 cache-control 设置过期时间,在过期时间内浏览器会默认使用本地缓存。
但缓存机制也存在一定的问题,因为网站开发是阶段性的,隔一段时间会发布一个新的版本。因为 HTTP 请求是根据 url 来定位的,如果资源文件名的 url 没有发生更改那么浏览器还是会使用缓存,这个时候怎么办那?
这时就需要一个缓存更新机制来让修改过的文件具有一个新的名字。
最简单的方法就是在 url 后加一个时间戳,但是这会导致只要有新的版本发布就会重新获取所有的新资源。
一个现代流行的方法就是根据文件计算一个 hash 值,这个 hash 值是根据文件的更新变化而变化的。 当浏览器获取文件时如果这个文件名有更新那么就会请求新的文件。
DNS 预解析
现代浏览器在 DNS Prefetch 上做了两项工作:
- html 源码下载完成后,会解析页面的包含链接的标签,提前查询对应的域名
- 对于访问过的页面,浏览器会记录一份域名列表,当再次打开时,会在 html 下载的同时去解析 DNS
自动解析
浏览器使用超链接的 href 属性来查找要预解析的主机名。当遇到 a 标签,浏览器会自动将 href 中的域名解析为 IP 地址,这个解析过程是与用户浏览网页并行处理的。但是为了确保安全性,在 HTTPS 页面中不会自动解析
手动解析
预解析某域名
<link rel="dns-prefetch" href="//img.alicdn.com" />
强制开启HTTPS下的DNS预解析
<meta http-equiv="x-dns-prefetch-control" content="on" />
CDN
CDN 的原理是尽可能的在各个地方分布机房缓存数据。
因此,我们可以将静态资源尽量使用 CDN 加载,由于浏览器对于单个域名有并发请求上限,可以考虑使用多个 CDN 域名。并且对于 CDN 加载静态资源需要注意 CDN 域名要与主站不同,否则每次请求都会带上主站的 Cookie,平白消耗流量。
预加载
在开发中,可能会遇到这样的情况。有些资源不需要马上用到,但是希望尽早获取,这时候就可以使用预加载。
预加载其实是声明式的 fetch ,强制浏览器请求资源,并且不会阻塞 onload 事件,可以使用以下代码开启预加载。
预加载可以一定程度上降低首屏的加载时间,因为可以将一些不影响首屏但重要的文件延后加载,唯一缺点就是兼容性不好。
<link rel="preload" href="http://example.com" />
预渲染
可以通过预渲染将下载的文件预先在后台渲染,可以使用以下代码开启预渲染。
图片优化
- 不用图片。很多时候会使用到很多修饰类图片,其实这类修饰图片完全可以用 CSS 去代替。
- 对于移动端按理说,图片不需要加载原图,可请求裁剪好的图片
- 小图使用 base64 格式
- 将多个图标文件整合到一张图中(雪碧图)
- 采用正确的图片格式
- 对于能够显示 WebP 格式的浏览器尽量使用 WebP 格式。因为 WebP 格式具有更好的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量,缺点就是兼容性并不好
- 色彩很多的使用 JPEG
- 色彩种类少的使用 PNG,有的可用 SVG 代替