Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【浏览器】缓存 #19

Open
Tracked by #6
swiftwind0405 opened this issue Mar 2, 2020 · 2 comments
Open
Tracked by #6

【浏览器】缓存 #19

swiftwind0405 opened this issue Mar 2, 2020 · 2 comments

Comments

@swiftwind0405
Copy link
Owner

swiftwind0405 commented Mar 2, 2020

image

各类缓存技术优缺点

1、cookie

优点:对于传输部分少量不敏感数据,非常简明有效

缺点:容量小(4K),不安全(cookie被拦截,很可能暴露session);原生接口不够友好,需要自己封装;需要指定作用域,不可以跨域调用

2、Web Storage

容量稍大一点(5M),localStorage可做持久化数据存储支持事件通知机制,可以将数据更新的通知发送给监听者

缺点:本地储存数据都容易被篡改,容易受到XSS攻击

缓存读取需要依靠js的执行,所以前提条件就是能够读取到html及js代码段,其次文件的版本更新控制会带来更多的代码层面的维护成本,所以LocalStorage更适合关键的业务数据而非静态资源

Cookie的作用是与服务器进行交互,作为HTTP规范的一部分而存在 ,而Web Storage仅仅是为了在本地“存储”数据而生

3、indexDB

IndexedDb提供了一个结构化的、事务型的、高性能的NoSQL类型的数据库,包含了一组同步/异步API,这部分不好判断优缺点,主要看使用者。

4、Manifest(已经被web标准废除)

优点

  • 可以离线运行
  • 可以减少资源请求
  • 可以更新资源

缺点

  • 更新的资源,需要二次刷新才会被页面采用
  • 不支持增量更新,只有manifest发生变化,所有资源全部重新下载一次
  • 缺乏足够容错机制,当清单中任意资源文件出现加载异常,都会导致整个manifest策略运行异常

Manifest被移除是技术发展的必然,请拥抱Service Worker吧

5、PWA(Service Worker)

这位目前是最炙手可热的缓存明星,是官方建议替代Application Cache(Manifest)的方案作为一个独立的线程,是一段在后台运行的脚本,可使web app也具有类似原生App的离线使用、消息推送、后台自动更新等能力

目前有三个限制(不能明说是缺点)

  • 不能访问 DOM
  • 不能使用同步 API
  • 需要HTTPS协议

localStorage,sessionStorage和cookie的区别

  • 共同点:都是保存在浏览器端、且同源的
  • 区别:
    • cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递,而sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下
    • 存储大小限制也不同,cookie数据不能超过4K,同时因为每次http请求都会携带cookie、所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大
    • 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭之前有效;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭
    • 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localstorage在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的
    • web Storage支持事件通知机制,可以将数据更新的通知发送给监听者
    • web Storage的api接口使用更方便

浏览器缓存

浏览器处理缓存的策略流程图:
image

通常浏览器缓存策略分为两种:强缓存和协商缓存

image

基本原理:

  • 1)浏览器在加载资源时,根据请求头的 expirescache-control 判断是否命中强缓存,是则直接从缓存读取资源,不会发请求到服务器。
  • 2)如果没有命中强缓存,浏览器一定会发送一个请求到服务器,通过 last-modifiedetag 验证资源是否命中协商缓存,如果命中,服务器会将这个请求返回,但是不会返回这个资源的数据,依然是从缓存中读取资源
  • 3)如果前面两者都没有命中,直接从服务器加载资源

强缓存

Expires

ExpiresHTTP/1.0 控制网页缓存的字段。其值为服务器返回该请求结果缓存的到期时间,即如果发生时间在 Expires 之前,那么本地缓存始终有效,否则就会发送请求到服务器来获取资源;是绝对时间

Cache-Control

Cache-ControlHTTP/1.1 新增的规则,用于控制网页缓存的字段。
image

Expires & Cache-Control

Cache-ControlExpires 同时存在的话(如下图),Cache-Control 优先级高于 Expires
因为 Expires 时间返回的是服务器绝对时间,而客户端本地时间是可以修改的(时区不同等),造成服务器与客户端时间发生误差,强缓存会直接失效。而 Cache-Control 是相对时间,每次参照客户端第一次请求时间计算而来的,故不会受到影响;毕竟 Cache-ControlHTTP/1.1 新增的规范

协商缓存

Last-Modified

Last-Modified: Wed, 21 Nov 2018 05:46:58 GMT
If-Modified-Since: Wed, 21 Nov 2018 05:46:58 GMT

ETag

Etag 是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成)。

ETag: "d5d-55b192d5e0640"
If-None-Match: "d5d-55b192d5e0640"

Last-Modified & Etag

Last-ModifiedETag 是可以一起使用的),服务器会优先验证 ETag ,一致的情况下,才会继续比对 Last-Modified,最后才决定是否返回 304 Not Modified

ETag 可以解决 Last-Modified 存在的一些问题,既生 Last-Modified 何生 ETag ?

  • 文件内容不更改,但修改时间发生改变,这时候不希望客户端认为这个文件修改了。
  • 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说 1S 内修改了 N 次),If-Modified-Since 能检查到的粒度是 S 级的,这种修改无法判断;
  • 某些服务器不能精确的得到文件的最后修改时间。

参考资料

@swiftwind0405 swiftwind0405 changed the title 浏览器(客户端)缓存 浏览器缓存 Mar 2, 2020
@swiftwind0405 swiftwind0405 changed the title 浏览器缓存 【Day09】浏览器缓存 Mar 2, 2020
@swiftwind0405 swiftwind0405 changed the title 【Day09】浏览器缓存 【浏览器】缓存 Apr 29, 2020
@swiftwind0405
Copy link
Owner Author

2万字 | 前端基础拾遗90问

1. 介绍一下浏览器缓存位置和优先级

  1. Service Worker
  2. Memory Cache(内存缓存)
  3. Disk Cache(硬盘缓存)
  4. Push Cache(推送缓存)
  5. 以上缓存都没命中就会进行网络请求

2. 说说不同缓存间的差别

Service Worker
和Web Worker类似,是独立的线程,我们可以在这个线程中缓存文件,在主线程需要的时候读取这里的文件,Service Worker使我们可以自由选择缓存哪些文件以及文件的匹配、读取规则,并且缓存是持续性的

Memory Cache
即内存缓存,内存缓存不是持续性的,缓存会随着进程释放而释放

Disk Cache
即硬盘缓存,相较于内存缓存,硬盘缓存的持续性和容量更优,它会根据HTTP header的字段判断哪些资源需要缓存

Push Cache
即推送缓存,是HTTP/2的内容,目前应用较少

3. 介绍一下浏览器缓存策略

强缓存(不要向服务器询问的缓存)

  • 设置Expires
    • 即过期时间,例如「Expires: Thu, 26 Dec 2019 10:30:42 GMT」表示缓存会在这个时间后失效,这个过期日期是绝对日期,如果修改了本地日期,或者本地日期与服务器日期不一致,那么将导致缓存过期时间错误。
  • 设置Cache-Control
    • HTTP/1.1新增字段,Cache-Control可以通过max-age字段来设置过期时间,例如「Cache-Control:max-age=3600」除此之外Cache-Control还能设置private/no-cache等多种字段

协商缓存(需要向服务器询问缓存是否已经过期)

  • Last-Modified
    • 即最后修改时间,浏览器第一次请求资源时,服务器会在响应头上加上Last-Modified ,当浏览器再次请求该资源时,浏览器会在请求头中带上If-Modified-Since 字段,字段的值就是之前服务器返回的最后修改时间,服务器对比这两个时间,若相同则返回304,否则返回新资源,并更新Last-Modified
  • ETag
    • HTTP/1.1新增字段,表示文件唯一标识,只要文件内容改动,ETag就会重新计算。缓存流程和 Last-Modified 一样:服务器发送 ETag 字段 -> 浏览器再次请求时发送 If-None-Match -> 如果ETag值不匹配,说明文件已经改变,返回新资源并更新ETag,若匹配则返回304
  • 两者对比
    • ETag 比 Last-Modified 更准确:如果我们打开文件但并没有修改,Last-Modified 也会改变,并且 Last-Modified 的单位时间为一秒,如果一秒内修改完了文件,那么还是会命中缓存
    • 如果什么缓存策略都没有设置,那么浏览器会取响应头中的 Date 减去 Last-Modified 值的 10% 作为缓存时间

image

看这篇文章:浏览器缓存机制剖析

@swiftwind0405
Copy link
Owner Author

swiftwind0405 commented Dec 15, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant