通过前端性能优化,可以带来更快的页面加载速度,以达到更好的体验,这里是一些初步的笔记。

资源合并与压缩

减少 HTTP 请求次数的同时,也从文件体积上减小网络负担。

对于 HTML、CSS、JS,我们可以将多个文件合并成一个文件,压缩空格、换行符等对显示和功能没有影响的内容。
此外,JS 还可以采用混淆压缩,相比非混淆压缩,它保护代码的同时也增加压缩比,但可读性几乎没有,可以使用的工具:html-minifieruglifyjs2clean-css

对于图片,可以用 tinypng 进行大幅度压缩,虽然还是有损压缩,但肉眼看不出就没问题了。
对于琐碎的图片,可以使用【CSS雪碧图】整合,即把所有图片都整合到一张新图片上,通过 background-position 定位切片。

根据情况可以格式化图片为 jpg 或 png,有条件使用 webp 的优先用它。
(不过 webp 作为一种新格式对于旧的浏览器和图片查看器并不友好。)

前面也提到,我们可以在页面中将多个 css、js 请求合并为一个请求。
这在现在还是比较有意义的,但当 http2 广泛应用后可能就不是那么必要了。

1_合并请求.jpg

浏览器加载原理优化

首先了解一下浏览器渲染 HTML 页面的流程:

2_渲染流程.jpg

于是主要是 JS 的相关优化:

  • 把 CDN 资源分布在多个域名下:利用并发请求加快资源加载,Chrome 的并发上限是6
  • 尽可能把 JS 放在页面底部:在 <head> 里通过 link 不管引入 CSS 还是 JS 都会阻塞页面渲染,CSS 是没办法,但 JS 可以优化
  • 尽可能将 JS 内嵌而非外部引入,同时内嵌 JS 也应当放在所有 link 引入的 CSS 前面
  • 对于会阻塞后续内容的外部 JS,需要增加 defer 解决

缓存优化

首先了解一下一个 HTTP 请求的过程:

3_http请求.jpg

强缓存——Expires & Cache-Control

当浏览器对某个资源的请求命中了强缓存时,返回的 HTTP 状态为 200。
在 Chrome 的开发者工具的 network 里面 size 会显示为 from disk cache,这种情况下是不会发送任何请求。

4_强缓存.jpg

Expires:

  • 指定浏览器上缓存的保质期
  • 等同 Cache-control 中的 max-age,如果同时存在,则被其覆盖。

Cache-Control:

  • public:响应被缓存,并且在多用户间共享。
  • private:默认值,响应只能够作为私有的缓存(e.g., 在一个浏览器中),不能再用户间共享;
  • no-cache:响应不会被缓存,而是实时向服务器端请求资源。
  • max-age:数值,单位是秒,从请求时间开始到过期时间之间的秒数。基于请求时间(Date字段)的相对时间间隔,而不是绝对过期时间;

协商缓存——Last-Modified & Etag:

当浏览器对某个资源的请求没有命中强缓存,就会发一个请求到服务器,验证协商缓存是否命中。
如果协商缓存命中,请求响应返回的 http 状态为304并且会显示一个 Not Modified 的字符串。

5_协商缓存.jpg

Last-Modified / If-Modified-Since:

表示本地文件在服务器上的最后一次修改时间。

缓存过期时把浏览器端缓存页面的最后修改时间发送到服务器去,服务器会把这个时间与服务器上实际文件的最后修改时间进行对比。
若时间一致,则返回304,客户端直接使用本地缓存文件。

Etag / If-None-Match:

EntityTags 是 URL 的 tag,用来标示 URL 对象是否改变,一般为资源实体的哈希值。
和 Last-Modified 类似,如果服务器验证资源的 ETag 没有改变(该资源没有更新),将返回一个304状态告诉客户端使用本地缓存文件。

Etag 的优先级高于 Last-Modified,Etag 主要为了解决 Last-Modified 无法解决的一些问题:

  • 文件也许会周期性的更改,但是他的内容并不改变,不希望客户端重新 get
  • If-Modified-Since 能检查到的粒度是s级
  • 某些服务器不能精确的得到文件的最后修改时间

懒加载和预加载

并发加载的资源过多会阻塞 JS 的加载,影响网站的正常使用。
而懒加载是在图片进入可视区域之后请求图片资源,即图片到达可视区域之后,img src 才会被设置进来,在没有到达的时候只是实现一个类似 1px 的占位符。

懒加载对于移动网页,尤其是滚动加载场景是一项非常重要的优化措施。
它可以减少无效资源的加载,对于图片多、页面长的场景适用。

而预加载是在使用之前提前请求资源,当资源被使用到的时候能直接从本地缓存加载。
所以常常应用于多 tab 场景,让用户更快的看到下一个页面。

此外还可以…

  • 使用 CDN 缓存,并用 gzip 压缩内容
  • 减少不必要的301跳转

参考文章:https://zhuanlan.zhihu.com/p/78053275