콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.

青灯夜游
풀어 주다: 2022-07-18 11:19:35
앞으로
2590명이 탐색했습니다.

이 기사에서는 CSS 콘텐츠 가시성 속성을 살펴보고 이 속성을 사용하여 렌더링 성능을 최적화하는 방법에 대해 설명합니다. 모든 사람에게 도움이 되기를 바랍니다.

콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.

최근content-visibility는 일부 렌더링 성능을 최적화하기 위해 비즈니스에서 실제로 사용되었습니다.content-visibility进了一些渲染性能的优化。

这是一个比较新且有强大功能的属性。本文将带领大家深入理解一番。【推荐学习:css视频教程

何为content-visibility

content-visibility:属性控制一个元素是否渲染其内容,它允许用户代理(浏览器)潜在地省略大量布局和渲染工作,直到需要它为止。

MDN 原文:The content-visibility CSS property controls whether or not an element renders its contents at all, along with forcing a strong set of containments, allowing user agents to potentially omit large swathes of layout and rendering work until it becomes needed. Basically it enables the user agent to skip an element's rendering work (including layout and painting) until it is needed — which makes the initial page load much faster.

它有几个常见的取值。

/* Keyword values */ content-visibility: visible; content-visibility: hidden; content-visibility: auto;
로그인 후 복사

分别解释一下:

  • content-visibility: visible:默认值,没有任何效果,相当于没有添加content-visibility,元素的渲染与往常一致。
  • content-visibility: hidden:与display: none类似,用户代理将跳过其内容的渲染。(这里需要注意的是,跳过的是内容的渲染)
  • content-visibility: auto:如果该元素不在屏幕上,并且与用户无关,则不会渲染其后代元素。

contain-intrinsic-size

当然,除content-visibility之外,还有一个与之配套的属性 --contain-intrinsic-size

contain-intrinsic-size:控制由content-visibility指定的元素的自然大小。

上面两个属性光看定义和介绍会有点绕。

我们首先来看看content-visibility如何具体使用。

content-visibility: visible是默认值,添加后没有任何效果,我们就直接跳过。

利用content-visibility: hidden优化展示切换性能

首先来看看content-visibility: hidden,它通常会拿来和display: none做比较,但是其实它们之间还是有很大的不同的。

首先,假设我们有两个 DIV 包裹框:

1111
로그인 후 복사

设置两个 div 为200x200的黑色块:

.g-wrap > div { width: 200px; height: 200px; background: #000; }
로그인 후 복사

效果如下:

콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.

OK,没有问题,接下来,我们给其中的.hidden设置content-visibility: hidden,看看会发生什么:

.hidden { content-visibility: hidden; }
로그인 후 복사

效果如下:

콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.

注意,仔细看效果,这里添加了content-visibility: hidden之后,消失的只是添加了该元素的 div 的子元素消失不见,而父元素本身及其样式,还是存在页面上的

如果我们去掉设置了content-visibility: hidden的元素本身的widthheightpaddingmargin等属性,则元素看上去就如同设置了display: none一般,在页面上消失不见了。

那么,content-visibility: hidden的作用是什么呢?

设置了content-visibility: hidden的元素,其元素的子元素将被隐藏,但是,它的渲染状态将会被缓存。所以,当content-visibility: hidden被移除时,用户代理无需重头开始渲染它和它的子元素。

因此,如果我们将这个属性应用在一些一开始需要被隐藏,但是其后在页面的某一时刻需要被渲染,或者是一些需要被频繁切换显示、隐藏状态的元素上,其渲染效率将会有一个非常大的提升。

利用content-visibility: auto实现虚拟列表

OK,接下来是content-visibility的核心用法,利用auto

이것은 강력한 기능을 갖춘 비교적 새로운 속성입니다. 이 기사는 당신에게 깊은 이해를 줄 것입니다. [추천 학습: CSS 동영상 튜토리얼]

콘텐츠 가시성이란 무엇인가요?

content-visibility: 이 속성은 요소가 콘텐츠를 렌더링할지 여부를 제어합니다. 이를 통해 사용자 에이전트(브라우저)는 잠재적으로 많은 레이아웃 및 렌더링 작업을 생략할 수 있습니다. 필요합니다.
MDN 원본 텍스트: content-visibility CSS 속성은 강력한 포함 세트를 강제하는 것과 함께 요소가 콘텐츠를 렌더링할지 여부를 제어하여 사용자 에이전트가 잠재적으로 기본적으로 사용자 에이전트는 필요할 때까지 요소의 렌더링 작업(레이아웃 및 페인팅 포함)을 건너뛸 수 있습니다. 이는 초기 페이지 로드를 훨씬 빠르게 만듭니다.
몇 가지 공통 값이 있습니다.
...
// ... 包含了 N 个 paragraph
...
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
각각 설명:
  • content-visibility: visible: 기본값, 효과 없음,content-visibility를 추가하지 않은 것과 동일, 요소 렌더링 평소와 같습니다.
  • content-visibility: Hidden:display: none과 유사하게 사용자 에이전트는 콘텐츠 렌더링을 건너뜁니다. (여기서 건너뛴 것은 콘텐츠 렌더링이라는 점에 유의해야 합니다.)
  • content-visibility: auto: 요소가 화면에 없고 할 일이 없는 경우 사용자와 함께 하위 요소를 렌더링하지 않습니다.

contain-intrinsic-size

물론 content-visibility는 제외 code> 또한 일치하는 속성인 contain-intrinsic-size가 있습니다. contain-intrinsic-size: content-visibility로 지정된 요소의 기본 크기를 제어합니다. 위 두 속성의 정의와 소개가 다소 혼란스럽습니다. 먼저 content-visibility를 구체적으로 사용하는 방법을 살펴보겠습니다. content-visibility: visible은 기본값이므로 추가 후에도 아무런 효과가 없으므로 바로 건너뛰겠습니다.

content-visibility:hidden을 사용하여 디스플레이 전환 성능 최적화

먼저 content-visibility:hidden을 살펴보겠습니다. 일반적으로 display: none과 비교되지만 실제로는 큰 차이가 있습니다. 먼저 두 개의 DIV 래핑 상자가 있다고 가정합니다.
.paragraph { content-visibility: auto; }
로그인 후 복사
로그인 후 복사
두 개의 div를 200x200의 검은색 블록으로 설정합니다.
...
// ... 包含了 N 个 paragraph
...
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
효과는 다음과 같습니다. 콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.좋아요, 문제 없습니다. 다음은 우리가 드리겠습니다. .hidden content-visibility: hiden을 설정하고 무슨 일이 일어나는지 확인하세요.
.paragraph { content-visibility: auto; contain-intrinsic-size: 320px; }
로그인 후 복사
로그인 후 복사
효과는 다음과 같습니다: 콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.주의하세요. 효과를 주의 깊게 살펴보세요. content-visibility는 여기에 추가됨: 숨긴 후, 요소가 추가된 div의 하위 요소만 사라지지만 상위 요소 자체와 해당 스타일은 페이지에 계속 존재합니다. 너비, 높이, 패딩, 여백및 기타 속성을 제거하면 요소는 다음과 같습니다. display: none으로 설정되어 페이지에서 사라집니다. 그럼 콘텐츠 가시성: 숨김의 역할은 무엇인가요? content-visibility: hide가 설정된 요소의 경우 하위 요소는 숨겨지지만 렌더링 상태는 캐시됩니다. 따라서 content-visibility:hidden이 제거되면 사용자 에이전트는 해당 항목과 해당 하위 항목의 렌더링을 다시 시작할 필요가 없습니다. 따라서 처음에는 숨겨져야 하지만 페이지의 특정 순간에 렌더링되어야 하는 일부 요소 또는 표시 상태와 숨겨진 상태 사이를 자주 전환해야 하는 일부 요소에 이 속성을 적용하면 렌더링이 효율성이 매우 크게 향상될 것입니다.

content-visibility: auto를 사용하여 가상 목록 구현

OK, 계속 다음은 auto속성 값을 사용하는 content-visibility의 핵심 사용법입니다.

content-visibility: auto的作用是,如果该元素不在屏幕上,并且与用户无关,则不会渲染其后代元素。是不是与 LazyLoad 非常类似?

我们来看这样一个 DEMO ,了解其作用:

假设,我们存在这样一个 HTML 结构,含有大量的文本内容:

...
// ... 包含了 N 个 paragraph
...
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

每个.paragraph的内容如下:

콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.

因此,整个的页面看起来就是这样的:

콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.

由于,我们没有对页面内容进行任何处理,因此,所有的.paragraph在页面刷新的一瞬间,都会进行渲染,看到的效果就如上所示。

当然,现代浏览器愈加趋于智能,基于这种场景,其实我们非常希望对于仍未看到,仍旧未滚动到的区域,可以延迟加载,只有到我们需要展示、滚动到该处时,页面内容才进行渲染。

基于这种场景,content-visibility: auto就应运而生了,它允许浏览器对于设置了该属性的元素进行判断,如果该元素当前不处于视口内,则不渲染该元素。

我们基于上述的代码,只需要最小化,添加这样一段代码:

.paragraph { content-visibility: auto; }
로그인 후 복사
로그인 후 복사

再看看效果,仔细观察右侧的滚动条:

콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.

这里我使用了::-webkit-scrollbar相关样式,让滚动条更明显。

可能你还没意识到发生了什么,我们对比下添加了content-visibility: auto和没有添加content-visibility: auto的两种效果下文本的整体高度:

콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.

有着非常明显的差异,这是因为,设置了content-visibility: auto的元素,在非可视区域内,目前并没有被渲染,因此,右侧内容的高度其实是比正常状态下少了一大截的。

好,我们实际开始进行滚动,看看会发生什么:

콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.

由于下方的元素在滚动的过程中,出现在视口范围内才被渲染,因此,滚动条出现了明显的飘忽不定的抖动现象。(当然这也是使用了content-visibility: auto的一个小问题之一),不过明显可以看出,这与我们通常使用 JavaScript 实现的虚拟列表非常类似。

当然,在向下滚动的过程中,上方消失的已经被渲染过且消失在视口的元素,也会因为消失在视口中,重新被隐藏。因此,即便页面滚动到最下方,整体的滚动条高度还是没有什么变化的。

content-visibility是否能够优化渲染性能?

那么,content-visibility是否能够优化渲染性能呢?

Youtube -- Slashing layout cost with content-visibility中,给了一个非常好的例子。

这里我简单复现一下。

对于一个存在巨量 HTML 内容的页面,譬如类似于这个页面 --HTML - Living Standard

콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.

可以感受到,往下翻,根本翻不到尽头。(这里我在本地模拟了该页面,复制了该页面的所有 DOM,并非实际在该网站进行测试)

如果不对这个页面做任何处理,看看首次渲染需要花费的时间:

콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.

可以看到,DOMContentLoaded 的时间的3s+,而花费在 Rendering 上的就有整整2900ms

而如果给这个页面的每个段落,添加上content-visibility: auto,再看看整体的耗时:

콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.

可以看到,DOMContentLoaded 的时间骤降至了500ms+,而花费在 Rendering 上的,直接优化到了61ms

2900ms --> 61ms,可谓是惊人级别的优化了。因此,content-visibility: auto对于长文本、长列表功能的优化是显而易见的。

利用contain-intrinsic-size解决滚动条抖动问题

当然,content-visibility也存在一些小问题。

从上面的例子,也能看到,在利用content-visibility: auto处理长文本、长列表的时候。在滚动页面的过程中,滚动条一直在抖动,这不是一个很好的体验。

当然,这也是许多虚拟列表都会存在的一些问题。

好在,规范制定者也发现了这个问题。这里我们可以使用另外一个 CSS 属性,也就是文章一开头提到的另外一个属性 --contain-intrinsic-size,来解决这个问题。

contain-intrinsic-size:控制由content-visibility指定的元素的自然大小。

什么意思呢?

还是上面的例子

...
// ... 包含了 N 个 paragraph
...
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

如果我们不使用contain-intrinsic-size,只对视口之外的元素使用content-visibility: auto,那么视口外的元素高度通常就为 0。

当然,如果直接给父元素设置固定的height,也是会有高度的。

那么实际的滚动效果,滚动条就是抖动的:

콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.

所以,我们可以同时利用上contain-intrinsic-size,如果能准确知道设置了content-visibility: auto的元素在渲染状态下的高度,就填写对应的高度。如果如法准确知道高度,也可以填写一个大概的值:

.paragraph { content-visibility: auto; contain-intrinsic-size: 320px; }
로그인 후 복사
로그인 후 복사

如此之后,浏览器会给未被实际渲染的视口之外的.paragraph元素一个高度,避免出现滚动条抖动的现象:

콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.

你可以自己亲自尝试感受一下:CodePen Demo -- content-visibility: auto Demo

content-visibility: autoVS LazyLoad

那么,content-visibility: auto是否可以替代LazyLoad(懒加载)呢?

我们来看看我们通常对于 LazyLoad(懒加载)的一个定义。

LazyLoad:通常而言,LazyLoad 的作用在于,当页面未滚动到相应区域,该区域内的资源(网络请求)不会被加载。反之,当页面滚动到相应区域,相关资源的请求才会被发起。

那么,如果content-visibility: auto要能够替代 LazyLoad,则需要做到,初始化渲染的时候,在页面当前展示范围外的,设定了content-visibility: auto的元素内的一些静态资源不会被加载。

这里我尝试做了一个简单的 DEMO:

还是借助上述的代码,假设我们有如下的 HTML 结构,也就是在上述代码基础上,插入一些图片资源:

...
// ... 包含了 N 个 paragraph
...
콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.
콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.
콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.
로그인 후 복사

相应设置下 CSS:

.paragraph, .g-img { content-visibility: auto; }
로그인 후 복사

当刷新页面的时候,观察网络请求(Network)的状况:

1콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.

即便当前页面可视区域外的内容未被渲染,但是图片依然会被加载!

因此,这也得到了一个非常重要的结论:

content-visibility: auto无法直接替代 LazyLoad,设置了content-visibility: auto的元素在可视区外只是未被渲染,但是其中的静态资源仍旧会在页面初始化的时候被全部加载

所以,在实际使用中,如果你的业务中已经使用了比较完善的 Lazyload 处理长列表或者一些图片资源,那么content-visibility: auto不是更好的选择。

可访问性功能探究

当然,content-visibility: auto的特性又引申出了另外一个有意思的点。

如果说可视区外的内容未被渲染,那是否会影响用户进行全文检索呢?毕竟这是一个非常重要的功能。

我们再来做个探究,还是上面的 DEMO,我们在首尾添加两个特殊的字符串:

content-visibility: auto 对搜索功能影响的探究

...
// ... 包含了 N 个 paragraph
...

content-visibility: auto 对搜索功能影响的探究

로그인 후 복사

相应设置下 CSS:

.paragraph, .text { content-visibility: auto; }
로그인 후 복사

好,如此一来,在页面刷新后,第二个.text是处于未被渲染状态,我们试着全局ctrl + F查找一下,看看能找到几个:

콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.

전 세계적으로 검색하면 현재 렌더링되지 않은 요소의 콘텐츠를 찾을 수 있다는 점에서 매우 흥미로운 현상입니다.

여기서 또 다른 중요한 점을 알 수 있습니다.

content-visibility: auto로 설정된 렌더링되지 않은 요소가 있어도 전역 검색 기능에 영향을 미치지 않습니다.content-visibility: auto的未被渲染的元素,但是它并不会影响全局的搜索功能。

这也是content-visibility设计上充分的考虑,对可访问性功能,或者说用户体验的考量,有了这一点,对于它的实际使用有着非常大的帮助。

content-visibility的一些其他问题

首先,看看content-visibility的兼容性(2022-06-03):

1콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.

目前还是比较惨淡的,并且我没有实际在业务中使用它,需要再等待一段时间。当然,由于该属性属于渐进增强一类的功能,即便失效,也完全不影响页面本身的展示。

同时,也有一些同学表示,利用content-visibility: auto只能解决部分场景,在海量 DOM 的场景下的实际效果,还有待进一步的实测。真正运用的时候,多做对比,在做取舍。

当然,现代浏览器已经越来越智能,类似content-visibility功能的属性也越来越多,我们在性能优化的路上有了更多选择,总归是一件好事。

总结一下

再简单总结一下:

  • 在一些需要被频繁切换显示、隐藏状态的元素上,使用content-visibility: hidden,用户代理无需重头开始渲染它和它的子元素,能有效的提升切换时的渲染性能;

  • content-visibility: auto的作用更加类似于虚拟列表,使用它能极大的提升长列表、长文本页面的渲染性能;

  • 合理使用contain-intrinsic-size预估设置了content-visibility: auto元素的高宽,可以有效的避免滚动条在滚动过程中的抖动;

  • content-visibility: auto无法直接替代 LazyLoad,设置了content-visibility: auto的元素在可视区外只是未被渲染,但是其中的静态资源仍旧会在页面初始化的时候被全部加载;

  • 即便存在设置了content-visibility: auto

    이는콘텐츠 가시성디자인에서도 충분히 고려된 사항으로,
  • 접근성 기능, 즉 사용자 경험을 고려하여 실제 사용에 매우 중요합니다. 큰 도움이 됩니다.

content-visibility관련 기타 문제먼저content를 살펴보세요. -가시성호환성(2022-06-03):

1콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.아직은 아직은 상대적으로 암울한 상황이고, 실제 업무상 사용해본 적은 없어서 좀 기다려야겠습니다. 물론 이 속성은 점진적인 향상 기능이므로 실패하더라도 페이지 표시 자체에는 전혀 영향을 미치지 않습니다. 동시에 일부 학생들은 content-visibility: auto를 사용하면 일부 시나리오만 해결할 수 있으며 대규모 DOM이 있는 시나리오의 실제 효과는 추가 테스트가 필요하다고 말했습니다. 실제로 사용하실 때에는 좀 더 많이 비교하고 선택해 보시기 바랍니다. 물론 최신 브라우저는 점점 더 지능화되었으며 content-visibility기능과 유사한 속성이 점점 더 많아지고 있습니다. 좋은 일이야.

요약

간단한 요약:
  • 일부 요구 사항 표시 상태와 숨겨진 상태 사이를 자주 전환하는 경우, 사용자 에이전트는 해당 요소와 하위 요소 렌더링을 처음부터 시작할 필요가 없으므로 전환 시 렌더링 성능을 효과적으로 향상시킬 수 있습니다.
  • content-visibility: auto기능을 사용하면 긴 목록과 긴 텍스트 페이지의 렌더링 성능이 크게 향상될 수 있습니다.
  • 합리적으로 사용하세요. code>contain-intrinsic-size는content-visibility: auto요소의 높이와 너비를 추정하여 스크롤 프로세스 중 스크롤 막대의 흔들림을 효과적으로 방지할 수 있습니다. li>content-visibility: auto는 LazyLoad를 직접 대체할 수 없습니다.content-visibility: auto가 설정된 요소는 시각적 영역 외부에 렌더링되지 않지만 그 안에 있는 정적 리소스는 그래도 페이지가 초기화되면 모두 로드됩니다.
  • content-visibility: auto로 설정된 렌더링되지 않은 요소가 있어도 전역 검색 기능에는 영향을 미치지 않습니다. (동영상 공유 학습: 웹 프론트엔드 시작하기)

위 내용은 콘텐츠 가시성 속성에 대해 자세히 알아보고 이를 사용하여 렌더링 성능을 최적화하는 방법에 대해 이야기합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:cnblogs.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!