本文已参与掘金创作者训练营第三期「话题写作」赛道,详情查看:掘力计划|创作者训练营第三期正在进行,「写」出个人影响力。
本文对HTTP提升网络加载速度的方法进行总结,可能不是按照页面具体打开流程来看的。
目的是能够更好的掌握其中相关环节如何优化。感谢大家支持~
其中关于DNS、TCP的优化,本人写过两篇文章:
这里就先不在赘述了,哈哈哈
一、HTTP缓存
缓存位置
-
Service Worker(暂时只看缓存这部分)
- 运行在后台的Worker线程,可以充当代理服务器,拦截用户发起的请求。
- 必须是HTTPS,因为涉及请求拦截,所以用HTTPS保障安全。
- 可以在本地缓存文件,可以直接从缓存加载文件,从而提高访问速度。
-
Menory
- 内存中的缓存。持续性很短,进程释放了就被释放了。
- 主要是页面上已经下载的样式、脚本、图片等已经抓取到的资源。
-
Disk
- 硬盘中的缓存。
- 比Menory读取速度相对慢点,但是存储量大,存储时间长。
-
Push
- 推送缓存,是HTTP2中的内容,当以上三种缓存都没有被命中,他才会被使用。
- 注意:他只会在会话(Session)中存在,当会话结束就被释放,并且缓存也很短暂。
缓存的过程
如上图,浏览器缓存的过程如下:
- 浏览器发起一个HTTP请求
- 浏览器缓存没有命中,通知浏览器缓存中没有当前请求的缓存结果和缓存标识
- 浏览器 向 服务器 发起HTTP请求
- 服务器 返回请求结果和缓存规则
- 浏览器 存储缓存结果和缓存标识
缓存分为 强缓存 和 协商缓存。
强缓存优先执行于协商缓存。如果强缓存生效,就继续使用缓存,否则会进行协商缓存。
协商缓存是由服务器决定是否使用缓存,如果缓存失效服务器会重新返回对应的HTTP响应和缓存的标识,返回200状态码,然后再存入浏览器中;生效则返回304状态码,继续使用缓存。
如果强缓存和协商缓存都没有设置,浏览器就会采用启发算法,通常会取响应头中的Date减去Last-Modified的值的10%作为缓存时间。
强缓存
不会向服务器发起请求,直接从缓存中读取资源。
强缓存 判断是否缓存的依据来自于是否超出设定的缓存时间或者某个时间段,而不关心服务器文件是否已经更新,这可能会导致加载文件不是服务器最新文件。(如果需要判断服务器文件是否发生改变就需要协商缓存)
HTTP1.0的强缓存是Expires:
- 缓存的是服务器上的过期时间。
- 受限于本地时间,如果用户修改了本地时间就没用了。
HTTP2.0的强缓存是Cache-Control:
- 设置过期时间的时间段,也就是服务器时间过了多少秒过期。如果url发生变化,会发起重新请求。配合webpack的hash目录很有效果。
- code码为200
当两个缓存同时存在的时候,Catch-Control比Expries优先级更高。
协商缓存
当强制缓存失效之后,就会携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存。 如果协商缓存存在,返回状态码304和Not Modified
上面是协商缓存有效的请求流程:
- 浏览器先发HTTP请求,先经过浏览器缓存
- 浏览器缓存判断缓存是否有效,强缓存无效返回缓存标识
- 浏览器携带缓存标识,向服务器发起HTTP请求
- 服务器收到缓存标识,查看请求资源是否发生改变,没改变返回304,通知浏览器资源没有更新,使用本地缓存
- 浏览器再次请求之前的缓存结果
- 浏览器缓存返回给浏览器缓存资源
如果协商缓存失效了,会返回状态码200
上图是协商缓存失效的请求流程:
- 浏览器发起HTTP请求,先经过浏览器缓存
- 浏览器强缓存失效,返回缓存标识
- 浏览器携带缓存标识,向服务器发送HTTP请求
- 服务器判断资源是否更新,更新了,返回200,响应新的资源和缓存标识
- 浏览器将资源和缓存标识存储到浏览器缓存中
HTTP1.0的协商缓存是Last-Modified:
- 查看资源在服务器上最后的修改时间,与缓存标识中的时间进行比对。
- 存在一个问题,如果当前资源被修改了,但是只多了个空格或者说实际内容并没有发生改变,但是依然会返回给浏览器200状态,新的资源和缓存标识。
HTTP2.0的协商缓存是Etag:
- 会设置一个值,比如:
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4
,如果响应的资源没有发生改变,就会使用缓存。 - 如果改变就会重新响应,并重新给一个新的值。
通过缓存能够提升HTTP的请求速度,从而提升网络加载速度。
二、HTTP Cookies
HTTP Cookie 是服务器发送到用户的浏览器并保存在本地的一块小数据。他会在浏览器下次向同一个服务器再发起请求时被携带并发送到服务器上。
Cookie主要用于一下三个方面:
- 会话状态管理(如用户登陆状态、购物车、游戏分数或其他信息)
- 个性化设置(如用户自定义设置、主题)
- 浏览器行为追踪(如跟踪分析用户行为)
创建Cookie
当服务器收到HTTP请求的时候,可以往响应头中添加Set-Cookie选项。
浏览器在收到响应之后,会存下Cookie。之后的每次请求都会通过Cookie请求头部将信息携带给服务器。
服务器使用Set-Cookie:
HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry
浏览器保存Cookie,之后每次请求携带Cookie发送给服务器:
GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry
定义Cookie的生命周期
Cookie的生命周期有两种方式:
-
会话期Cookie是最简单的Cookie: 浏览器关闭之后,会被自动删除。会话期的Cookie不需要指定过期时间(Expires)或者有效期(Max-Age)
-
持久性Cookie的生命周期取决于过期时间(Expires)或者有效期(Max-Age)指定的一段时间。
比如:
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
注意:当Cookie过期时间被设定时,设定的日期和时间只与客户端相关,与服务端无关。
限制Cookie
两种方法可以确保Cookie被安全发送,并且不会被意外的参与者或脚本访问:Secure属性和HttpOnly属性。
-
Secure
- 标记为这个属性的Cookie只应该通过HTTPS协议加密过的请求发送给服务端。
- 但是即便设置了Secure属性,敏感信息也不应该通过Cookie传输,因为Secure也无法提供确实的安全保障。
- 例如,可以访问客户硬盘的人就可以读取他,修电脑的。
-
HttpOnly
- 在JavaScript中的 document.cookie API 无法获取/访问带有HttpOnly属性的Cookie。
- 这种类型的Cookie只作用于服务器。
- 这样有助于缓解XSS攻击。
比如:
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
Cookie的作用域
Domian和Path标识定义了Cookie的作用域:
-
Domian:
- 指定哪些主机可以接受Cookie。如果不指定,默认是Origin,子域名不会被包含。
- 如果指定了,将会包含子域名。也就是子域名能够获取到父域名的Cookie。
- 比如,如果设置
Domain=mozilla.org
,mozilla.org的子域名就能够使用他的Cookie。
-
Path
- 定义了主机下哪些路径可以接受Cookie。子路径也会被匹配。
- 比如设置path=/d,那/d下的/d/c也会被匹配。
-
SameSite
- 允许服务器要求某个Cookie在跨站请求的时候不会被浏览器发送,从而可以阻止跨站请求伪造攻击(CSRF)。
- 例如:
Set-Cookie: key=value; SameSite=Strict
- SameSite有三种值:
- None: 浏览器会在同站请求、跨站请求中继续发送Cookie,不区分大小写。
- Strict: 浏览器只在访问相同站点时发送Cookie。
- Lax: 浏览器只在访问相同站点时发送Cookie,但用户从外部站点导航至URL时会携带Cookie。新版浏览器中为默认选项。
下面还有document.cookie的一些属性:
- name
- 创建或覆盖cookie的名字时,必须字段
- value
- cookie的值
- end
- 过期时间设置,秒数(永不过期的Cookie为Infinity)。如果没有定义,会在会话期结束时结束。
- path
- 和上面介绍的path一样
- domain
- 和上面介绍的domain一样
- secure
- 和上面介绍的secure一样
优化
能够通过减少Cookie的传递来加速网络请求,比如当前请求携带了所有Cookie的值。可以通过设置那些Cookie不需要传递来提升请求速度。
比如,在跨域请求的时候,Cookie的其中部分值不需要传递,就可以用SameSite值Strict进行处理。而有些请求需要用到Cookie,就可以使用path。
总结
本篇文章主要是将HTTP缓存和Cookie,以及如何基于这两个对HTTP请求进行优化。
- HTTP缓存进行对HTTP请求进行优化
- 减少Cookie对HTTP请求进行优化