两种异步 CSS 加载方案的细微区别
为了避免 DOM 构建被 non-critical CSS 的加载阻塞,有两种常见的异步加载方案。其一(preload):
其二(media query):
media query 方案,除了有更好的浏览器兼容性,在加载时机上也和 preload 有细微的区别:
被标记为 preload 的资源,拥有最高的加载优先级,因此很可能导致其它重要资源的下载时机被剥夺,这可能也并非是 non-critical CSS 所需要的。
#learning
为了避免 DOM 构建被 non-critical CSS 的加载阻塞,有两种常见的异步加载方案。其一(preload):
<link rel="preload" as="style" href="style.css" onload="this.rel='stylesheet'">其二(media query):
<link rel="stylesheet" href="style.css" media="print" onload="this.media='all'">media query 方案,除了有更好的浏览器兼容性,在加载时机上也和 preload 有细微的区别:
被标记为 preload 的资源,拥有最高的加载优先级,因此很可能导致其它重要资源的下载时机被剥夺,这可能也并非是 non-critical CSS 所需要的。
#learning
这个有意思,测量 Embedded content 在不同 viewport sizes 的最小高度,提前生成 CSS,从而避免 CLS
https://github.com/GoogleChromeLabs/layout-shift-terminator
#tools
https://github.com/GoogleChromeLabs/layout-shift-terminator
#tools
GitHub
GitHub - GoogleChromeLabs/layout-shift-terminator
Contribute to GoogleChromeLabs/layout-shift-terminator development by creating an account on GitHub.
Google 是怎样定义 CLS 测量的
首先存在两个概念:帧之间的 CLS,下面简称“帧CLS”;会话之间的 CLS,下面简称“会话CLS”。
帧 CLS:使用 PerformanceObserver API,指定 type 为 layout-shift。这由浏览器提供支持,它计算元素由“一个已渲染帧”变更到“下个已渲染帧”的“CLS 分数”,换句话说,它是每帧间的变化差度。
会话 CLS:帧 CLS 往往不能直接使用,为了更加准确,需要再由用户引入 Session(或 Window)的概念,目前 Google 对其定义是:单个会话中每帧间隔最长 1s、每个会话最长 5s、“会话CLS”为每个“帧CLS”累加、仅报告“最大会话CLS”。
看到这里,或许会有一个疑问:为什么要分为“帧CLS”、“会话CLS”两个东西,直接一个 PerformanceObserver API 搞定不也挺好?
原因是,帧 CLS 的算法不会变,但会话 CLS 会随着时间不断进步,也许以后对会话的定义就不是 1s/5s 了,但若集成在浏览器中,老版本的浏览器将无法得到更新,因此决定由用户计算会话 CLS 得分。
#learning
首先存在两个概念:帧之间的 CLS,下面简称“帧CLS”;会话之间的 CLS,下面简称“会话CLS”。
帧 CLS:使用 PerformanceObserver API,指定 type 为 layout-shift。这由浏览器提供支持,它计算元素由“一个已渲染帧”变更到“下个已渲染帧”的“CLS 分数”,换句话说,它是每帧间的变化差度。
会话 CLS:帧 CLS 往往不能直接使用,为了更加准确,需要再由用户引入 Session(或 Window)的概念,目前 Google 对其定义是:单个会话中每帧间隔最长 1s、每个会话最长 5s、“会话CLS”为每个“帧CLS”累加、仅报告“最大会话CLS”。
看到这里,或许会有一个疑问:为什么要分为“帧CLS”、“会话CLS”两个东西,直接一个 PerformanceObserver API 搞定不也挺好?
原因是,帧 CLS 的算法不会变,但会话 CLS 会随着时间不断进步,也许以后对会话的定义就不是 1s/5s 了,但若集成在浏览器中,老版本的浏览器将无法得到更新,因此决定由用户计算会话 CLS 得分。
#learning
https://github.com/w3c/webappsec-permissions-policy/blob/main/policies/unsized-media.md
TL;DR:
- intrinsicSize 未设置,默认固有尺寸 300x150
- width、height 未设置,使用 intrinsicSize;部分设置,按照 intrinsicSize 计算纵横比;全部设置,使用 width、height
#看了什么
TL;DR:
- intrinsicSize 未设置,默认固有尺寸 300x150
- width、height 未设置,使用 intrinsicSize;部分设置,按照 intrinsicSize 计算纵横比;全部设置,使用 width、height
#看了什么
GitHub
webappsec-permissions-policy/policies/unsized-media.md at main · w3c/webappsec-permissions-policy
A mechanism to selectively enable and disable browser features and APIs - w3c/webappsec-permissions-policy
二清问题
昨天看 V 站 有人讨论,正好之前也有做过类似的项目,记录一下。
什么是二清:比如与平台合作的入驻商户,用户在支付后钱暂时入账到平台账户,再由平台提现给商户,此时这些钱流经了平台账户,就会涉及二清问题。如果是小平台,这么操作问题不大,但只要流水一多,就会被盯上,比如微信在支付时,会有针对用户、金额、地域等条件的风控(当然是我们自己测试出的,微信不可能泄漏他们的风控规则)。
央行规定,要想二清必须得有支付牌照。一个牌照大概十几亿吧(现在好像便宜点了),当然还得有关系,也不是都给批的。那就只能换模式:
分账模式:找有牌照的机构合作,让每个商户自己开户(可以是个体工商户,或企业),用户支付时,钱直接到商户账户,不流经平台,平台仅拥有对其交易款项的分账权限,且分账金额至多不能超过 30%(不同机构不同),分账后的金额进到平台账户。此时商户、平台均作为该机构的二级商户。为什么要分账?因为平台要抽点。
#experience
昨天看 V 站 有人讨论,正好之前也有做过类似的项目,记录一下。
什么是二清:比如与平台合作的入驻商户,用户在支付后钱暂时入账到平台账户,再由平台提现给商户,此时这些钱流经了平台账户,就会涉及二清问题。如果是小平台,这么操作问题不大,但只要流水一多,就会被盯上,比如微信在支付时,会有针对用户、金额、地域等条件的风控(当然是我们自己测试出的,微信不可能泄漏他们的风控规则)。
央行规定,要想二清必须得有支付牌照。一个牌照大概十几亿吧(现在好像便宜点了),当然还得有关系,也不是都给批的。那就只能换模式:
分账模式:找有牌照的机构合作,让每个商户自己开户(可以是个体工商户,或企业),用户支付时,钱直接到商户账户,不流经平台,平台仅拥有对其交易款项的分账权限,且分账金额至多不能超过 30%(不同机构不同),分账后的金额进到平台账户。此时商户、平台均作为该机构的二级商户。为什么要分账?因为平台要抽点。
#experience
V2EX
大佬们请教一下,爱发电这种经营方式是逃税行为吗? - V2EX
问与答 - @djsfk - 爱发电是用三方支付收款比如支付宝,给到创作者会扣除 6%手续费,也就是提现到用户手中是 94%收益(也是通过支付宝提现),这其中没有交税的环节,这不是漏税行为吗,据我个人的了解,企业公转私是要缴纳个税
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