文章介绍了如何使用CSS的content-visibility属性提高网页在渲染大量元素时的性能,特别是在处理包含大量自定义表情符号的Fediverse实例时。文章讨论了作者遇到性能问题后的解决方案,以及content-visibility属性的工作原理和优势。
介绍如何使用CSS的content-visibility属性提高网页性能,特别是在处理大量自定义表情符号的情况下。
在一个包含近20k个自定义表情符号的Fediverse实例中,打开表情符号选择器时页面存在卡顿问题。
使用content-visibility属性对emoji分类进行调整,通过计算预期大小并设置CSS自定义属性来优化性能。
使用content-visibility属性后,初始加载在Chrome中提升了约15%,在Firefox中提升了5%。与虚拟列表相比,这个优化的效果并不理想,但在某些情况下可能是一个简单的解决方案。
前言
介绍了如何使用 CSS 的 content-visibility 属性来提高网页在渲染大量元素时的性能。今日前端早读课文章由 @ikoofe 翻译,公号:KooFE 前端团队授权分享。
正文从这开始~~
最近,我在 emoji-picker-element 上遇到了一个性能问题:在一个接近 20k 个自定义表情符号的 Fediverse 实例上,打开表情符号选择器时,页面至少冻结了一秒钟,之后会卡顿一段时间。
【第2073期】content-visibility: 一个可以提高渲染性能的css属性
与 Slack、Discord 等类似,在 Mastodon 或 Fediverse 的不同服务器上也可以有自己的自定义表情符号。对于 20k 大小的自定义表情符号虽然不常见,但也并非不会出现。
在启动了他们的 Repro 之后,它确实很慢:
这里存在的问题是:
让人欣慰的是,在这里使用了
,所以那 20k 张图片并不是一次全部下载的。但无论如何,渲染 40k 元素都会非常缓慢 - Lighthouse 的建议是不要超过 1,400 个!
当然,我的第一个想法是,“谁会有 20k 的自定义表情符号?”,我的第二个想法是,“唉,我想我应该做虚拟化”。
【早阅】用 React 虚拟化优化性能:行业级解决方案
当初,我刻意避免了 emoji-picker-element 中的虚拟化,即因为:1) 它很复杂,2) 我认为我不需要它,以及 3) 它会影响可访问性。
我之前有过做虚拟列表的经验:在另外一个类库 Pinafore 上实现一个很大的虚拟列表。其中,使用了 ARIA: feed role,我做了所有计算,并添加了一个选项来禁用 “无限滚动”,因为有些人不喜欢它。为了尽快解决这个卡顿问题,我开始打算实现类似的虚拟列表。
然而,几天后,我脑海中突然冒出一个想法:为什么不试试 CSS content-visibility 呢?从上面的性能监控截图中可以看到,在布局和绘画上花费了大量时间。因此,使用 content-visibility 可能是一个比全面虚拟化简单得多的解决方案。
content-visibility 是一个全新的 CSS 功能,它允许开发者从布局和绘制的角度 “隐藏” DOM 的某些部分。它在很大程度上不会影响可访问性(因为 DOM 节点仍然存在),它不会影响在页面中查找 (⌘+F/Ctrl+F),并且不需要虚拟化。它所需要的只是对屏幕外的元素进行调整,以便浏览器可以在其中保留空间。
在这里,可以把 emoji 的分类作为要调整的元素单元,比如 Fediverse 的自定义表情有 blobs、cats 等分类。
幸运的是,我有一个很好的 atomic 单元来调整大小:emoji 类别。Fediverse 上的自定义表情符号往往分为一口大小的类别:“blobs”、“cats” 等:
对于每个分类,表情符号的大小以及行数和列数是已知的,因此可以使用 CSS 自定义属性来计算出预期的大小:
.category {
content-visibility: auto;
contain-intrinsic-size:
/* width */
calc(var(--num-columns)