小计一次 CLS 优化
网站 CLS(Cumulative Layout Shift) 评分一直在 0.7+, lighthouse 评分一直在 80 分上下, 然后就尝试找哪里有问题。
首先运行 lighthouse 评分, 找到 performance 下的 CLS 选项, 看到主要两处影响了 CLS 评分:
-
第一处是所有文章的列表, 是一个 MUI Grid 组件
当初文章列表打算做响应式, 就用了 MUI 的 Grid 组件, 后来决定列表不响应了, 但是感觉 Gird 还能用于纵向的 space, 就懒得换了。 可是这是 MUI 啊, 难道 MUI 还能影响 CLS? 不, 我不相信!!!
然而看 CLS 的截图, 明确指向了 Grid 组件, 之前看过 Grid 组件实现原理就是
负 margin
, 难道是负 margin
的问题? 一搜关键字,"mui Grid CLS"
,"negative margin CLS"
, 好几个 issue 指向了它:- v5 + emotion - increase in Cumulative Layout Shift
- [Grid] spacing with full width Items / Layout shift
并且最后的结论是 —— 别用。。。
好吧, 我确实就不用 Grid 了, 没有横向 Grid 的需求, 纵向的 space 用 margin 就可以实现。三下五除二, 拿掉了 Grid, 重新跑 lighthouse, 搓搓手, 好期待绿色的 90 分啊。。。
可惜事与愿违, 评分仍然只有 80 来分, 接下来就看第二处影响 CLS 评分的地方:
-
第二处是所有标签(tag)的列表, 是一个 object 元素
由于我希望在任何地方, 标签(tag)都能点击跳转到标签详情页(即使在另一个大的 a 标签下面), & 我希望使用原生的 a 标签, 以保证在禁用 js 的情况下仍能跳转, 然而 a 标签不能嵌套, 查了查, 哦, 可以用一个 object 标签包裹住 Tag 组件, 就用了。
CLS 截图指示 Tag 组件影响了评分, 可是它只是一个行内文本, 带了点 padding 和 margin, 它什么也没干啊, 它也没有负 margin, 为什么说它影响了评分啊, 不, 我不相信!!!
可是突然回想起前些天处理 tailwind preflight.css 时, 发现 tailwind preflight 把 object 和 img 放在了一起, 并将他们的默认样式设置为了
display: block;
, 会不会, object 和 img 有差不多的性质?一看 MDN, 果然:
HTML
<object>
元素(或者称作 HTML 嵌入对象元素)表示引入一个外部资源,这个资源可能是一张图片,一个嵌入的浏览上下文,亦或是一个插件所使用的资源。它引用一个外部资源, 那他必然不知道那个外部资源有多大, 而它里面的文字是标签的
name
, 有长有短, 就必然导致object
产生偏移。是啦, 说干就干, 标签name
固定一下长度,object
也设置一下宽度, 搞定。
重新跑一下 lighthouse, 99 分, 啊, 多么美丽的绿色(是不是...有哪里不对)