AI智能
改变未来

css 中的 content-visitly 提升渲染性能


content-visibility 新的css属性,可显著提升渲染性能

译文:原文链接:https://web.dev/content-visibility/

本文介绍CSS的新属性 

content-visibility

 ,这个属性可以显著提升渲染性能。

Chromium 85

 开始有了 

[content-visibility](<https://drafts.csswg.org/css-contain/#propdef-content-visibility>)

 属性,这可能是对于提升页面加载性能提升最有效的CSS属性,

content-visibility

 让用户代理正常情况下跳过元素渲染工作(包括 

layout

 和 

painting

 ),除非需要的时候进行渲染工作。如果页面有大量离屏(

off-screen

)的内容,借助 

content-visibility

 属性可以跳过离屏内容的渲染,加快用户首屏渲染时间,可以做到减少的页面可交互的等待时间

<center>上图中使用了

content-visibility: auto

属性的内容部分,其首次加载渲染(

Rendering

)提升了近7倍</center>

兼容性

content-visibility

 属性依赖于 the CSS Containment Spec , Containment 浏览器兼容性见 most modern browsers.

下面先介绍一下该属性的在浏览器中的兼容性

CSS content-visibility

CSS Containment

首先,提升页面渲染性能最关键是预测页面独立 

DOM

 节点树。

开发者需要告诉浏览器哪些内容是封装到一个容器的,允许浏览器对内容进行推断,而不需要考虑该容器子树之外的状态。从而知道哪些内容占位符是独立的容器,意味着浏览器可以对它进行优化。

这儿有四种类型的 CSS containment

  • size

     [ul]元素上的尺寸属性值确保可以在不检查其后代的情况下展开元素的框。意味着我们如果只需要元素容器的尺寸就可以跳过子树的布局(

    layout

  • layout

     

    layout

     布局是指后代不会影响页面上其他框的外部布局。如果我们想要做的是布局其他容器,那么这允许我们潜在地跳过子树的布局。

  • [/ul]

  • style

     

      确保容器对后代以外的其他属性产生影响的属性不会转义元素(例如计数器)。如果我们想计算其他元素上的样式,这允许我们潜在地跳过后代元素的样式计算。
  • paint

     

      确保容器的后代不会显示在其边界之外,没有任何东西可以明显地溢出元素,如果一个元素不在屏幕上或不可见,它的后代也将不可见。如果元素在屏幕外,这允许我们跳过绘制后代元素。

    使用 

    content-visibility

     跳过渲染

    可能很难确定 

    containment

     包含哪些值,因为浏览器优化可能只有在指定了适当的集合时才会启动。你可以看看哪些值搭配 what works best 性能最优,或者使用 

    content-visibility

     属性,它将自动进行优化。作为开发者使用 

    content-visibility

     可以达到事半功倍的效果。

    content-visibility

     属性有多个值,

    auto

     可以立即改善性能,一个元素是 

    style

     配置为:

    content-visibility: auto

    与 

    contain

     配置为 

    layout

    style

    paint

     等属性效果一样,如果一个元素离屏(与用户无关的元素——指选中或者已经上焦点),它获取 

    size

     属性值(它将阻止了 painting 和 hit-testing )。

    以上表述是什么意思呢?简短来说是:如果一个元素离屏,它的后代不会被渲染,浏览器计算元素大小而无须考虑它的内容,大部分的渲染是无须考虑后代的 

    style

     和 

    layout

    当元素接近视口时,浏览器不再给容器添加 

    size

    ,并开始绘制和点击测试元素的内容。渲染可以即时完成,让用户马上看到视图。

    示例: a travel blog

    https://player.bilibili.com/player.html?aid=586109787

    content-visibility

    这个例子中,我们可以看到未使用

    content-visibility:auto

    属性的页面渲染时间是232ms,使用了

    content-visibility:auto

    属性的渲染时间是30ms

    这个旅行博客比较典型的包含了一系列的故事和图片,以及对故事的描述,下面是当导航到这个博客的时候发生的事情:

    1. 页面从网络上下载需要的资源
    2. 根据用户的可见性,计算 
      style

       和 布局页面的内容

    3. 浏览器继续执行第一步直到页面所有资源都下载完毕

    在第二步中,浏览器处理所有可能发生变化的内容,它更新任何新元素的样式和布局,以及可能由于新更新而发生变化的元素。渲染工作需要时间。

    demo地址

    现在想想如果给元素的 

    style

     添加属性发生了什么,

    content-visibility: auto

    浏览器下载和渲染每一小块,他们之间的不同之处是在上面的第2步的执行。

    使用 

    content-visibility

     ,浏览器将计算显示在屏幕上的 

    style

     和 

    layout

    ,如果故事全屏了,浏览器将跳过渲染工作仅仅计算容器的 

    style

     和 

    layout

    页面加载性能包括所有的视图内故事和离屏的空容器,渲染性能将提升50%以上,在我们的例子中渲染时间从232ms减小到30ms,提升了7倍左右。

    为了获得这些好处,你需要做哪些工作?

    首先,我们将内容分成几个部分:

    示例将每个部分添加

    story

    class,应用

    content-visibility:auto

    ,示例在线地址

    我们应用的 

    style

     如下:

    .story {  content-visibility: auto;  contain-intrinsic-size: 1000px; /* Explained in the next section. */}

    注意,随着内容进入和离开可见性,它将根据需要开始和停止渲染。然而,这并不意味着浏览器将不得不反复渲染和重新渲染相同的内容,因为渲染工作将尽可能的情况下保存。

    指定元素的大小 

    contain-intrinsic-size

    为了更好的从 

    content-visibility

     收益,浏览器应用 

    size

     来确保渲染的内容尺寸不受其他影响,意味着元素将 进行 

    layout

     计算即使元素为空,如果元素没有高度,那么默认高度为 0 px。

    这可能并不理想,因为滚动条的大小会发生变化,这取决于每个故事的高度不为零。

    此时, CSS提供了另外一个属性 

    contain-intrinsic-size

     ,它可以配置元素的占位大小,在我们例子中将它设为了 

    1000px

    作为分块的高度和宽度。

    这意味着它将像拥有“内在大小”维度的一个子元素一样进行布局,以确保未设置大小的 

    div

     仍然占据空间。

    content -intrinsic-size

     充当占位符大小,代替呈现的内容。

    隐藏内容 

    content-visibility: hidden

    如果您想保持内容未呈现(不管它是否在屏幕上),同时利用缓存呈现状态的好处,那么使用

    content-visibility: hidden;

    content-visibility: hidden

     属性对 带来的好处跟 

    content-visibilit: auto

     对于离屏元素带来的好处是一样的,不同点是,它不会像 

    auto

     一样自动的渲染到屏幕上。

    这样可以给你更好的实现以下场景:

    控制元素的隐藏,稍后又显示

    与其他隐藏元素的方法进行比较:

    • display:none

       [ul]隐藏元素并且销毁渲染状态,意味着从隐藏到显示的成本与渲染一个新元素是一样的

  • visibility: hidden

     隐藏元素并且保存渲染状态,它并不是真的从文档中移除元素,因为它(和它的子树)仍然占据页面上的几何空间,仍然可以单击。它还会在任何需要的时候更新呈现状态,即使是隐藏的时候。

  • [/ul]

  • content-visibility: auto

     

      隐藏元素并且保存渲染状态,如果有变化发送,让元素显示出来的方法是移除 property 

      content-visibility: atuo

    内容可见性的一些很好的用例:

    content-visibility: auto

     可用于实现高级虚拟卷轴和测量布局。

    结论

    CSS 中 

    content-visibility

     和 CSS Containment 规格对于提升性能有显著作用,更多的文章请查看:

    • The CSS Containment Spec
    • MDN Docs on CSS Containment
    • CSSWG Drafts
  • 赞(0) 打赏
    未经允许不得转载:爱站程序员基地 » css 中的 content-visitly 提升渲染性能