0%

前端性能优化

性能优化

资源合并与压缩

主要是css和js文件的资源压缩合并,压缩可以减小文件体积,而合并则可减少HTTP请求,可通过webpack和一些现有的线上工具进行。

非核心脚本延迟/异步加载

异步加载包括三种方式:async和defer以及动态脚本创建。

  • async加载,是html5引入的机制,async加载规定脚本一旦加载好就立刻执行,并且各脚本加载的顺序不定。
  • defer加载规定脚本是否延迟加载,在HTML解析之后进行脚本加载,并且加载顺序和声明顺序一致
  • 动态脚本加载是在async和defer之前,动态创造script标签进行脚本加载,并在onload事件触发后执行。

利用缓存

缓存类型包含强缓存和协商缓存,强缓存不发起HTTP请求,而协商缓存发起HTTP请求。

强缓存

直接从disk cache中读取或者从memory cache中获取,在chrome的network面板中可看到状态码为200,并且标明缓存来源。HTTP/1.0版本的Expires响应头用于标识客户端资源的有效性,值是一个GMT绝对时间,表明如果在所表明的时间内访问资源时,就会命中强缓存。HTTP/1.1版本的max-age是一个相对时间单位,用秒来表示,表明在响应正确返回时间之后的多长时间内访问该资源时,命中强缓存。

二者起到的作用是相同的,只不过分别是HTTP/1.0和HTTP/1.1的产物,Expires头只是为了向后兼容。如果同时出现,则max-age起作用,也就意味着max-age优先级更高。

强缓存固然可以提升性能,但是也有它自己的问题。就是我们命中的缓存资源可能不是最新的。此时就需要协商缓存了。

协商缓存

浏览器向服务器发送请求,服务器会根据请求头中的内容来决定返回的内容。如果命中协商缓存,则返回304状态码并在响应头中附上相关信息通知浏览器从缓存中读取缓存。需要配合cache-control一起使用。

cache-control中相关的头列举如下:

  • last-modified和if-modified-since:当服务器向浏览器第一次发送请求的内容时,会将文件的最后修改时间发送给客户端。这个时间被附加在响应头中的last-modified中体现。当我们再次向服务器请求该资源时,会在请求中配置if-modified-since头,其值为服务器上次告知我们的last-modified值,服务器接收到该请求时,会判断该资源是否发生了更新,如果没有更新,就返回304,浏览器从缓存中读取资源,节省带宽。而如果发生更新了,就像第一次发送请求那样,返回最新的资源。

但是这种策略也有着自己的缺点:

  • 有些服务器不能获取到精确的修改时间
  • 文件修改时间改变了,但是文件内容并没有改变

所以就有了另外一种利用文件内容来协商缓存的机制,这种方法涉及到以下两个头字段:

  • ETag和If-None-Match:ETag是服务器端对请求资源文件的唯一标识,和之前的一样。第一次向服务器发送请求,服务端会把资源的etag值通过ETag字段返回给客户端,而再次请求该资源时,浏览器会在请求头中的If-None-Match字段中标识出上次返回的ETag,服务器拿到这个ETag值和服务端资源的ETag进行对比,由于每次文件内容的变化都会重新计算ETag,所以更加有效地通过文件内容是否修改来控制缓存,实现了更加精准的控制。

下面通过三个方面来对比这两种协商缓存的策略:

  • 精确度上:根据modified来判断只能精确到秒,当文件在1秒内改变多次时,客户端不能及时感知到文件的变化。而ETag值在精确度就更胜一筹。此外,在负载均衡的服务器上,各个服务器的last-modified时间并不能保证完全一致
  • 性能上,last-modified策略要优于ETag策略,因为前者只是记录文件的修改时间,而后者需要服务器通过相应算法计算出一个hash值。
  • 优先级上,ETag要优先于Last-Modified。

总结一下,强缓存优先于协商缓存进行。如果强缓存生效,则返回强缓存的内容,如果协商缓存生效,则如果服务端资源文件改变,返回200状态码并返回最新的资源内容。否则返回304,从缓存中读取资源,并存入浏览器缓存。

用户行为和缓存

  • 地址栏访问,链接跳转,触发浏览器缓存机制
  • F5刷新,设置max-Age为0,跳过强缓存,会进行协商缓存
  • ctrl + F5会跳过强缓存和协商缓存

使用CDN

CDN(content delivery network),中文名叫内容分发网络。我们将服务器的静态资源缓存到CDN服务商部署的节点上,当我们的用户请求服务器资源时,会就近选择CDN节点进行资源获取,而节点会根据缓存的内容,向服务器请求,如果缓存资源最新,则返回这个缓存的资源,否则向服务器请求到最新资源并缓存在节点上,这样后续的用户都能访问到这个最新的内容了。

预解析DNS

使用prefetch技术告诉浏览器我们可能在未来需要用到的资源,通过link标签的rel属性设置为dns-prefetch来启用,href中设置url。当我们之后请求对应的url时,就免去了dns解析的时间。

懒加载

懒加载也叫延迟加载,是指在长网页中,在用户可视区域外的内容会进行延迟加载,与图片预加载正好相反,适用于图片很多,网页很长的电商网站。