绕不开的性能,躲不开的优化(一)

490 阅读6分钟

这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战

  1. 围绕浏览器的网络的相关优化
  2. 围绕浏览器的渲染情况优化

1. 网络相关优化

【简单的请求响应简略图:】

请求响应简略图.png

1.1 浏览器强缓存,协商缓存

这个是属于HTTP缓存,通过复用以前获取的资源,可以显著提高网站和应用程序的性能。Web缓存减少了等待时间和网络流量,因此减少了显示资源表示形式所需的时间。

如果没有缓存,浏览器就要直接请求服务器

HTTP缓存有2大类:

  • 私有缓存,指只能用于单独用户,一般是浏览器的缓存
  • 共享缓存,共享缓存可以被多个用户使用。例如,ISP 或你所在的公司可能会架设一个 web代理来作为本地网络基础的一部分提供给用户。这样热门的资源就会被重复使用,减少网络拥堵与延迟。

常见的 HTTP 缓存只能存储 GET 响应,对于其他类型的响应则无能为力。

1.1.1 缓存控制

Cache-control,即控制强缓存

强缓存,当浏览器去请求某个资源文件的时候,服务器就在respone header里面对文件做了缓存配置。缓存时间,缓存类型都由服务端控制。

大概模式就是

Response Headers
Cache-control:max-age=3600,private,no-cache
[key]:[value]
  • 重要的缓存请求指令

    1. no-cache:设置了这个,代表跳过强缓存,但是不妨碍协商缓存,每次请求都询问服务器
    2. no-store: 不缓存,服务器和客户端都不缓存
    3. max-age: 响应最大值,也就是在请求后多少时间内有效
  • 重要的缓存响应指令

    1. no-cache缓存前必须确认其有效性
    2. public,向任意方提供响应
    3. private,仅向特定的用户返回响应
    4. max-age,设置资源过期时间
    5. s-maxage,设置公共缓存服务器资源过期时间

简单示例:

  1. cache-control:max-age:3600,public, 强缓存,有效时间为3600,客户端和代理缓存服务器都可以缓存该资源
  2. cache-control:max-age:3600,private,强缓存,有效时间3600,只允许客户端缓存
  3. cache-control:max-age:3000,immutable,强缓存,有效时间3000,不询问服务器,即时用户做了刷新也不向服务器发起http请求

1.1.2 协商缓存

上面的强缓存,就是给资源设置一个过期时间。客户端每次请求资源都会看是否过期;只有过期才会询问服务器。

当资源过期了,就去请求服务器,这时候请求服务器的过程就可以设置协商缓存。

协商缓存,其实就是客户端和服务端的交互下的一种缓存

基本过程:

  • 一个陈旧的资源(缓存副本)是不会直接被清除或忽略的,当客户端发起一个请求时,缓存检索到已有一个对应的陈旧资源(缓存副本),则缓存会先将此请求附加一个If-None-Match头,然后发给目标服务器,以此来检查该资源副本是否是依然还是算新鲜的,则服务器返回 304 (Not Modified)。若服务器通过 If-None-Match判断后发现已过期,那么会带有该资源的实体内容返回。(该响应不会有带有实体信息),则表示此资源副本是新鲜的,这样一来,可以节省一些带宽。
GET /index.html
If-None-Match:W/"225-tts73UY9XxnjshrvQS8tolQ7xSw"
...

上面这段意思就是如果ETag和我不相同,说明资源更新,请求服务器,如果相同返回304进行资源缓存重定向,和If-None-Match相反的是If-Match

  • 当然服务器也能通过 If-Modified-Since判断资源是否过期。
GET /index.html
If-Modified-Since: Thu, 15 Apr 2021 00:00:00 GMT

如果该资源在2021年4月15号之前未发生改变则资源重定向304,否则就向服务器获取该资源返回200

如何设置呢?毕竟是前端,以node.js为例子

res.setHeader('max-age','3600 public');
res.setHeader(etag,'sci4454885');
res.setHeader('last-modified':Mon,'24 Dec 2020 05:04:00 GMT')

1.2 使用CDN

CDN指的是内容分发网络。其基本思路是尽可能的避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。

可以将图片等静态资源放在CDN,减少了服务器的负载

2. 浏览器渲染阶段优化

DOM的修改会导致重排和重绘

2.1 重排

重排是指元素的位置或者大小发生了改变,浏览器需要重新去计算渲染树,新的渲染树建立之后,浏览器会重新绘制所影响的元素

导致页面重排的一些操作(5小点):

  • 内容改变: 文本改变或者图片的尺寸改变

  • DOM元素的几何属性改变: 元素的宽高改变时,原来渲染树中的DOM节点会失效,浏览器会根据DOM的变化重新构建渲染树中的相关节点。如果父元素的几何属性发生变化时,会导致子元素以及兄弟元素的位置发生变化,从而引起重排。

  • DOM树结构发生变化: 添加DOM节点,修改DOM节点的位置以及删除某个节点都会对渲染树进行修改,从而导致重排。浏览器的布局是自上而下的,修改当前元素不会都之前的元素造成影响,但是会对之后的元素造成影响,导致重排。

  • 获取某些属性时: 当获取一些属性值时,浏览器为了保证获取到正确的值也会引起重排。如元素的offsetTop,offsetLeft,offsetHeightoffsetWidthscrollTopscrollWidthscrollLeftscrollHeight

  • 浏览器窗口尺寸发生改变时: 浏览器窗口的尺寸发生改变时,会导致所有元素的尺寸发生变化,从而导致重排。

2.2 重绘

重绘是指元素的样式发生了变化,而大小和尺寸没有发生改变

重绘不一定引起重排,但是重排一定引起重绘

2.3 基本优化手段

  1. 将多次样式改变属性合并成一次操作,样式属性的操作可以使用class代替
  2. 批量修改DOM,或者让元素脱离文本流,对其进行多重改变,然后将元素带回文档中
  3. 缓存布局信息,比如缓存offsetTop这些属性的信息,减少直接访问
  4. 对于动画较多的区域可以使用绝对定位,以此来减少回流带来整体影响