HTTP 协议中 Cache-Control 的两个迷惑设计
1. 缓存了,但没完全缓存:
Cache-Control 有个
2. 过期了,但没完全过期:
通常认为,只要
如 `max-age=60, stale-while-revalidate=20`,表示虽然 60 秒后缓存到期,但在 80 秒内缓存还有效,也就可以拿来使用,然后浏览器在后台默默发送一个 revalidation 请求。
#learning
1. 缓存了,但没完全缓存:
Cache-Control 有个
no-cache 选项,乍一看是“不缓存”的意思,但实际是“缓存”,只是每次使用缓存时,都向服务器验证是否过期。可以理解成“缓存了个缓存时间为 0 的东西”,真正的“不缓存”是 no-store。2. 过期了,但没完全过期:
通常认为,只要
max-age 指定的时间到了,缓存就过期了。但是,还有个 stale-while-revalidate,它的意思是,如果时间超过了 max-age,但“超过的时间”没超过 stale-while-revalidate,就认为缓存有效。如 `max-age=60, stale-while-revalidate=20`,表示虽然 60 秒后缓存到期,但在 80 秒内缓存还有效,也就可以拿来使用,然后浏览器在后台默默发送一个 revalidation 请求。
#learning
font-display: optional 的应用场景
长期以来,网络字体都存在着性能问题。
鉴于以上原因,
它会至多等待 100ms 字体就绪,在此期间内容处于 invisible 状态,100ms 后,使用已就绪字体或 fallback font 渲染内容。这意味着,UA 需要在 100ms 内,从缓存中取出字体,或从高速网络中下载字体。
#learning
长期以来,网络字体都存在着性能问题。
font-display 的三个选项 block、swap、fallback,都有一些问题:block 会使内容进入至多 3s 的 invisible 状态,这会产生 FOIT。swap 会持续等待字体就绪,并替换,这会产生 FOUT。而 fallback 只是介于 block、swap 间的一个折中。鉴于以上原因,
optional 是高性能应用唯一好的选择,它专为缓存而生,并拥有最好的 LCP、CLS。它会至多等待 100ms 字体就绪,在此期间内容处于 invisible 状态,100ms 后,使用已就绪字体或 fallback font 渲染内容。这意味着,UA 需要在 100ms 内,从缓存中取出字体,或从高速网络中下载字体。
#learning
🌸
font-display: optional 的应用场景 长期以来,网络字体都存在着性能问题。font-display 的三个选项 block、swap、fallback,都有一些问题: block 会使内容进入至多 3s 的 invisible 状态,这会产生 FOIT。swap 会持续等待字体就绪,并替换,这会产生 FOUT。而 fallback 只是介于 block、swap 间的一个折中。 鉴于以上原因,optional 是高性能应用唯一好的选择,它专为缓存而生,并拥有最好的 LCP、CLS。…
补充:optional 与 preload 的细节
- 使用
- 设置
在 Chrome 83 中,针对符合以上两个条件的情况,做了修正:
Chrome 会将整个页面至多阻塞 100ms,然后一并渲染出来,若在此期间字体下载完成,则使用下载的字体,否则使用 fallback font,整个过程只经历一个渲染周期。
在此之前,需要经历两个渲染周期:字体无关、字体相关内容分别渲染。在 100ms 内,字体相关的内容会一直处于 invisible 状态;100ms 后,使用已就绪字体或 fallback font 重新渲染页面。
#learning
- 使用
link rel="preload" 预加载字体文件- 设置
font-display: optional,避免布局偏移在 Chrome 83 中,针对符合以上两个条件的情况,做了修正:
Chrome 会将整个页面至多阻塞 100ms,然后一并渲染出来,若在此期间字体下载完成,则使用下载的字体,否则使用 fallback font,整个过程只经历一个渲染周期。
在此之前,需要经历两个渲染周期:字体无关、字体相关内容分别渲染。在 100ms 内,字体相关的内容会一直处于 invisible 状态;100ms 后,使用已就绪字体或 fallback font 重新渲染页面。
#learning
如何缓存 Opaque Response
对于 Opaque Response,无法通过 JS 得到任何有意义的信息,甚至是 status。这些 Response 一般由
想要有效缓存 Opaque Response,是一件很复杂的事,针对不同的情况,有以下三种模式:
- CORS 请求模式:这需要为
- Network First 缓存模式:这意味着 Opaque Response 缓存可作为 offline 模式下的 fallback
- Stale While Revalidate 缓存模式:这意味着 Opaque Response 缓存可被优先使用,但会在下次使用时获得更新
另外需要注意的是,为保护隐私,不同浏览器会为 Opaque Response 填充不同的大小,例如 Chrome 会将 Google Analytics gifs 填充至 7MB,这可能会使缓存配额提前用光。
#learning
对于 Opaque Response,无法通过 JS 得到任何有意义的信息,甚至是 status。这些 Response 一般由
<link>、<script>、<img> 等标签产生。想要有效缓存 Opaque Response,是一件很复杂的事,针对不同的情况,有以下三种模式:
- CORS 请求模式:这需要为
link、script 等标签添加 crossorigin 属性- Network First 缓存模式:这意味着 Opaque Response 缓存可作为 offline 模式下的 fallback
- Stale While Revalidate 缓存模式:这意味着 Opaque Response 缓存可被优先使用,但会在下次使用时获得更新
另外需要注意的是,为保护隐私,不同浏览器会为 Opaque Response 填充不同的大小,例如 Chrome 会将 Google Analytics gifs 填充至 7MB,这可能会使缓存配额提前用光。
#learning
CSS 硬件加速
硬件加速(aka GPU加速),指将一些繁重的图形任务从 CPU 转移到 GPU,其基于页面呈现时采用的 layering model。
当元素被设置 3D transform、opacity、filter、will-change 时,该元素可能会被提升到自己的 layer,它独立于页面中的其它部分,单独渲染,然后 composite 到屏幕中显示。
早期,人们通过指定
后来出现了
#learning
硬件加速(aka GPU加速),指将一些繁重的图形任务从 CPU 转移到 GPU,其基于页面呈现时采用的 layering model。
当元素被设置 3D transform、opacity、filter、will-change 时,该元素可能会被提升到自己的 layer,它独立于页面中的其它部分,单独渲染,然后 composite 到屏幕中显示。
早期,人们通过指定
transform 为 translateZ(0) 或 translate3d(0,0,0) 欺骗浏览器,为 2D 内容启用硬件加速,但这会浪费更多内存和造成其它不良影响。后来出现了
will-change,它允许提前暗示浏览器,为那些昂贵的任务做提前准备,同时它也可能导致元素创建自己的 layer,如在 will-change: transform 时。#learning
modulepreload 与 preload 区别
preload 仅仅下载和缓存资源,而 modulepreload 还会对 module 预编译,这会减小 FID。
此外,使用 preload 预加载 module,可能会导致 module 被重复下载两次,这归因于 CORS 策略的差异:
link、script 等标签都有一个 crossorigin 属性,它有三个值:未设置 crossorigin,crossorigin=anonymous 和 crossorigin=use-credentials。
而当 script 的 type=module 时,未设置 crossorigin == crossorigin=anonymous,这下只有两个值了。因此在默认情况下:
-
-
module 会因 CORS 策略的不同被意外的下载两次,除非为每个 link 都设置 crossorigin。但是 modulepreload 不存在此问题,因为它的行为默认与 script type=module 一致。
#learning
preload 仅仅下载和缓存资源,而 modulepreload 还会对 module 预编译,这会减小 FID。
此外,使用 preload 预加载 module,可能会导致 module 被重复下载两次,这归因于 CORS 策略的差异:
link、script 等标签都有一个 crossorigin 属性,它有三个值:未设置 crossorigin,crossorigin=anonymous 和 crossorigin=use-credentials。
而当 script 的 type=module 时,未设置 crossorigin == crossorigin=anonymous,这下只有两个值了。因此在默认情况下:
-
<script type=module> 未设置 crossorigin,表示使用 CORS,等价于 crossorigin="anonymous"-
<link rel=preload> 未设置 crossorigin,表示不使用 CORSmodule 会因 CORS 策略的不同被意外的下载两次,除非为每个 link 都设置 crossorigin。但是 modulepreload 不存在此问题,因为它的行为默认与 script type=module 一致。
#learning
👍4
🌸
https://publicsuffix.org/list/public_suffix_list.dat JP 域名分得好细,粗略数了下,大概有1900多条 .jp 记录,应该是列表里最多的了。
对了, github.io、 gitlab.io、 glitch.me 这些也在里面,这表示像 github.io 也被当成“顶级域(TLD)”对待。
也就是说 a.github.io 和 b.github.io 是两个完全独立的站点,并不共享资源。
也就是说 a.github.io 和 b.github.io 是两个完全独立的站点,并不共享资源。
想到两个 Service Worker 奇怪用法
1. 把一个页面(或数据)拆成 header、content、footer 三部分,在 Service Worker 缓存并自动拼上 header、footer,这样以后都只请求 content 就行了,相当是把 Service Worker 做成了一个简单的 rendering engine。
2. 在 Service Worker 维持一个 wss,并在会话建立后,把所有 HTTP Request 都 over wss,这样可以同时受益于 HTTP 的低会话成本、wss 的低延迟。
第二个打算近期找时间试一试,看看在小范围内能否获得性能提升。
#神奇海螺
1. 把一个页面(或数据)拆成 header、content、footer 三部分,在 Service Worker 缓存并自动拼上 header、footer,这样以后都只请求 content 就行了,相当是把 Service Worker 做成了一个简单的 rendering engine。
2. 在 Service Worker 维持一个 wss,并在会话建立后,把所有 HTTP Request 都 over wss,这样可以同时受益于 HTTP 的低会话成本、wss 的低延迟。
第二个打算近期找时间试一试,看看在小范围内能否获得性能提升。
#神奇海螺
Safari 16 将支持 Web Push API
Apple 将为 Safari 16 带来全平台的 Web Push Notifications 支持,它是最后一个提供 Web Push 支持的主流浏览器,届时 Web Push 将在所有主流平台可用。
此外,Safari on iOS 的 Web Notifications API 在此次更新后依旧不可用,它并没有被特别提到。
ref:
https://www.apple.com/ios/ios-16-preview/features/
https://www.apple.com/macos/macos-ventura-preview/features/
Apple 将为 Safari 16 带来全平台的 Web Push Notifications 支持,它是最后一个提供 Web Push 支持的主流浏览器,届时 Web Push 将在所有主流平台可用。
此外,Safari on iOS 的 Web Notifications API 在此次更新后依旧不可用,它并没有被特别提到。
ref:
https://www.apple.com/ios/ios-16-preview/features/
https://www.apple.com/macos/macos-ventura-preview/features/
Apple
OS - iOS 26
iOS 26 for iPhone with a new design, more helpful Apple Intelligence, polls and backgrounds in Messages, and features that make every day effortless.
Forwarded from Zenithal Hourly Radio