페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다.

青灯夜游
풀어 주다: 2022-11-22 20:16:14
앞으로
2947명이 탐색했습니다.

페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다.

프런트 엔드 직원에게 가장 골치 아픈 것은 페이지 성능입니다. 사용자는 페이지를 방문할 때 항상 페이지가 대화형 상태로 빠르게 표시되기를 원합니다. 페이지가 너무 느리게 로드되면 사용자가 떠날 가능성이 높습니다. 따라서 프런트엔드 개발자에게는 페이지 성능이 최우선 사항입니다. 실제로 로딩부터 렌더링까지 전체 프로세스를 이해하면 어디서부터 시작해야 할지 알 수 있습니다.

글쎄, 벗어나지 마세요. 오늘은 주로 긴 목록 페이지의 렌더링 성능을 연구하겠습니다.

요즘에는 페이지가 점점 더 복잡해지고 있으며, 페이지에는 가장 일반적인 요소가 많이 포함되는 경우가 많습니다. 수만 개의 제품 목록이 지연 없이 렌더링되도록 하려면 어떻게 해야 합니까? 이러한 긴 목록 렌더링 시나리오에 직면했을 때 사람들은 일반적으로 일회성 렌더링에 대한 부담을 줄이기 위해 페이징 또는 가상 목록을 사용합니다. 페이지에 있지만 이러한 방법을 조정해야 하는데 JS가 함께 제공되므로 CSS만 사용하여 구현할 수 있는 솔루션이 있습니까?

대답은 '예'입니다. 콘텐츠 가시성(content-visibility)이 바로 오늘날 우리의 주인공입니다. [추천 학습: css 비디오 튜토리얼]

content-visibility

속성 값

content-visibility은 CSS의 새로운 속성으로 주로 페이지 렌더링 성능을 향상시키는 데 사용됩니다. 는 요소가 콘텐츠를 렌더링할지 여부를 제어하고 브라우저가 이러한 요소의 레이아웃 및 렌더링을 건너뛸 수 있도록 허용합니다. content-visibility是CSS新增的属性,主要用来提高页面渲染性能,它可以控制一个元素是否渲染其内容,并且允许浏览器跳过这些元素的布局与渲染。

  • visible:默认值,没有效果。元素的内容被正常布局和呈现。
  • hidden:元素跳过它的内容。跳过的内容不能被用户代理功能访问,例如在页面中查找、标签顺序导航等,也不能被选择或聚焦。这类似于给内容设置display: none
  • auto:该元素打开布局包含、样式包含和绘制包含。如果该元素与用户不相关,它也会跳过其内容。与 hidden 不同,跳过的内容必须仍可正常用于用户代理功能,例如在页面中查找、tab 顺序导航等,并且必须正常可聚焦和可选择。

content-visibility: hidden手动管理可见性

上面说到content-visibility: hidden的效果与display: none类似,但其实两者还是有比较大的区别的:

  • content-visibility: hidden 只是隐藏了子元素,自身不会被隐藏
  • content-visibility: hidden 隐藏内容的渲染状态会被缓存,所以当它被移除或者设为可见时,浏览器不会重新渲染,而是会应用缓存,所以对于需要频繁切换显示隐藏的元素,这个属性能够极大地提高渲染性能。

페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다.

从这上面我们可以看到,添加了content-visibility: hidden元素的子元素确实是没有渲染,但它自身是会渲染的!

content-visibility: auto 跳过渲染工作

我们仔细想想,页面上虽然会有很多元素,但是它们会同时呈现在用户眼前吗,很显然是不会的,用户每次能够真实看到就只有设备可见区那些内容,对于非可见区的内容只要页面不发生滚动,用户就永远看不到。虽然用户看不到,但浏览器却会实实在在的去渲染,以至于浪费大量的性能。所以我们得想办法让浏览器不渲染非可视区的内容就能够达到提高页面渲染性能的效果。

我们上面说到的虚拟列表原理其实就跟这个类似,在首屏加载时,只加载可视区的内容,当页面发生滚动时,动态通过计算获得可视区的内容,并将非可视区的内容进行删除,这样就能够大大提高长列表的渲染性能。

但这个需要配合JS才能实现,现在我们可以使用CSS中content-visibility: auto,它可以用来跳过屏幕外的内容渲染,对于这种有大量离屏内容的长列表,可以大大减少页面渲染时间。

我们将上面的例子稍微改改:

<template>
  <div>
    <div>
      <img  :src="book.bookCover" / alt="페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다." >
      <div>
        <div>{{ `${book.bookName}${index + 1}` }}</div>
        <div>{{ book.catlog }}</div>
        <div>
          <div v-for="(item, index) in book.tags" :key="index">
            {{ item }}
          </div>
        </div>
        <div>
          {{ book.desc }}
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { toRefs } from "vue";

const props = defineProps<{
  book: any;
  index: any;
}>();
const { book, index } = toRefs(props);
</script>

<style scoped>
.card_item {
  margin: 20px auto;
  content-visibility: auto;
}
  / *
  ...
  */
</style>
로그인 후 복사

首先是没有添加content-visibility: auto

  • visible: 기본값, 효과 없음. 요소의 콘텐츠가 정상적으로 배치되고 렌더링됩니다.
  • 숨김: 요소가 콘텐츠를 건너뜁니다. 건너뛴 콘텐츠는 페이지 내 찾기, 탭 순서 탐색 등과 같은 사용자 에이전트 기능으로 액세스할 수 없으며 선택하거나 집중할 수도 없습니다. 이는 콘텐츠에 display: none을 설정하는 것과 유사합니다.
  • auto: 이 요소는 레이아웃 포함, 스타일 포함 및 그림 포함을 설정합니다. 또한 요소가 사용자와 관련이 없는 경우 해당 콘텐츠를 건너뜁니다. 숨겨진 콘텐츠와 달리 건너뛴 콘텐츠는 페이지 찾기, 탭 순서 탐색 등과 같은 사용자 에이전트 기능에 대해 계속 제대로 작동해야 하며 포커스 및 선택이 가능하도록 제대로 작동해야 합니다.

content-visibility: Hidden수동으로 가시성 관리

페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다.

위에서 언급한 content-visibility:hidden 효과와 유사 display: none, 그러나 실제로 둘 사이에는 큰 차이가 있습니다.

  • content-visibility: hided는 하위 요소만 숨기고 숨기지 않습니다 li >
  • content-visibility: Hidden 숨겨진 콘텐츠의 렌더링 상태가 캐시되므로 해당 콘텐츠가 제거되거나 표시되면 브라우저는 다시 렌더링하지 않고 캐시를 적용하므로 디스플레이를 전환해야 하는 사용자를 위해 자주 숨겨진 요소인 경우 이 속성은 렌더링 성능을 크게 향상시킬 수 있습니다.

페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다.

위에서 content-visibility:hidden 요소가 추가된 하위 요소는 실제로 렌더링되지 않지만 자체적으로 렌더링되는 것을 볼 수 있습니다! 🎜

🎜content-visibility: 렌더링 작업을 자동으로 건너뜁니다🎜🎜🎜잘 생각해 보면 페이지에 많은 요소가 있더라도 이러한 요소가 사용자에게 다음과 같이 표시됩니까? 동시에 사용자는 실제로 장치의 표시 영역에 있는 콘텐츠만 볼 수 있지만 페이지가 스크롤되지 않는 한 사용자는 표시되지 않는 영역의 콘텐츠를 볼 수 없습니다. 사용자는 볼 수 없지만 브라우저는 실제로 렌더링하므로 성능이 많이 낭비됩니다. 따라서 우리는 브라우저가 보이지 않는 영역의 콘텐츠를 렌더링하는 것을 방지하여 페이지 렌더링 성능을 향상시킬 수 있는 방법을 찾아야 합니다. 🎜🎜위에서 언급한 가상 목록의 원리는 실제로 첫 번째 화면이 로드될 때 비주얼 영역의 내용만 로드됩니다. 계산을 통해 동적으로 얻어지는 영역의 내용과 비표시 영역의 내용이 삭제되므로 긴 목록의 렌더링 성능이 크게 향상될 수 있습니다. 🎜🎜하지만 이는 JS로 구현되어야 합니다. 이제 CSS에서 content-visibility: auto를 사용하여 이러한 종류의 콘텐츠에 대해 화면 밖의 콘텐츠 렌더링을 건너뛸 수 있습니다. 화면 밖에 콘텐츠가 많을 경우 목록이 길면 페이지 렌더링 시간이 크게 단축될 수 있습니다. 🎜🎜위의 예를 약간 변경했습니다. 🎜
.card_item {
  content-visibility: auto;
}
로그인 후 복사
🎜우선 content-visibility: auto 효과가 추가되지 않았습니다. 이러한 요소는 가시 영역에 있는지 여부에 관계없이 렌더링됩니다. 🎜🎜🎜🎜 일반적인 비즈니스에서 이렇게 쓰면 사용자가 이 페이지에 들어간 후 바로 향수를 뱉을 수 있습니다. 성능을 고려하여 다음을 추가합니다. 🎜
/* Keyword values */
contain-intrinsic-width: none;

/* <length> values */
contain-intrinsic-size: 1000px;
contain-intrinsic-size: 10rem;

/* width | height */
contain-intrinsic-size: 1000px 1.5em;

/* auto <length> */
contain-intrinsic-size: auto 300px;

/* auto width | auto height */
contain-intrinsic-size: auto 300px auto 4rem;
로그인 후 복사
로그인 후 복사
🎜이때 효과를 살펴보겠습니다. 🎜

페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다.

从第10个开始,这些没在可视区的元素就没有被渲染,这可比上面那种全部元素都渲染好太多了,但是如果浏览器不渲染页面内的一些元素,滚动将是一场噩梦,因为无法正确计算页面高度。这是因为,content-visibility会将分配给它的元素的高度(height)视为0,浏览器在渲染之前会将这个元素的高度变为0,从而使我们的页面高度和滚动变得混乱。

페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다.

这里我们可以看到页面上的滚动条会出现抖动现象,这是因为可视区外的元素只有出现在了可视区才会被渲染,这就回导致前后页面高度会发生变化,从而出现滚动条的诡异抖动现象,这是虚拟列表基本都会存在的问题。

⚠️注意:当元素接近视口时,浏览器不再添加size容器并开始绘制和命中测试元素的内容。这使得渲染工作能够及时完成以供用户查看。

这也是为什么上面我们看到的是从第十个才开始不渲染子元素,因为它需要一个缓冲区以便浏览器能够在页面发生滚动时及时渲染呈现在用户眼前。

上面提到的size其实是一种 CSS 属性的潜在值contain,它指的是元素上的大小限制确保元素的框可以在不需要检查其后代的情况下进行布局。这意味着如果我们只需要元素的大小,我们可以跳过后代的布局。

contain-intrinsic-size 救场

页面在滚动过程中滚动条一直抖动,这是一个不能接受的体验问题,为了更好地实现content-visibility,浏览器需要应用 size containment 以确保内容的渲染结果不会以任何方式影响元素的大小。这意味着该元素将像空的一样布局。如果元素没有在常规块布局中指定的高度,那么它将是 0 高度。

这个时候我们可以使用contain-intrinsic-size来指定的元素自然大小,确保我们未渲染子元素的 div 仍然占据空间,同时也保留延迟渲染的好处。

语法

此属性是以下 CSS 属性的简写:

  • contain-intrinsic-width
  • contain-intrinsic-height
/* Keyword values */
contain-intrinsic-width: none;

/* <length> values */
contain-intrinsic-size: 1000px;
contain-intrinsic-size: 10rem;

/* width | height */
contain-intrinsic-size: 1000px 1.5em;

/* auto <length> */
contain-intrinsic-size: auto 300px;

/* auto width | auto height */
contain-intrinsic-size: auto 300px auto 4rem;
로그인 후 복사
로그인 후 복사

contain-intrinsic-size 可以为元素指定以下一个或两个值。如果指定了两个值,则第一个值适用于宽度,第二个值适用于高度。如果指定单个值,则它适用于宽度和高度。

实现

我们只需要给添加了content-visibility: auto的元素添加上contain-intrinsic-size就能够解决滚动条抖动的问题,当然,这个高度约接近真实渲染的高度,效果会越好,如果实在无法知道准确的高度,我们也可以给一个大概的值,也会使滚动条的问题相对减少。

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

페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다.

之前没添加contain-intrinsic-size属性时,可视区外的元素高度都是0,现在这些元素高度都是我们设置的contain-intrinsic-size的值,这样的话整个页面的高度就是不会发生变化(或者说变化很小),从而页面滚动条也不会出现抖动问题(或者说抖动减少)

페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다.

性能对比

上面说了这么多,content-visibility是否真的能够提高页面的渲染性能呢,我们来实际对比看看:

  • 首先是没有content-visibility的页面渲染

페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다.

  • 然后是有content-visibility的页面渲染

페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다.

上面是用1000个列表元素进行测试的,有content-visibility的页面渲染花费时间大概是37ms,而没有content-visibility的页面渲染花费时间大概是269ms,提升了足足有7倍之多!!!

对于列表元素更多的页面,content-visibility带来的渲染性能提升会更加明显。

思考?

能否减小页面的内存占用?

之前有同学问到了content-visibility: auto是否会减少页面内存的占用,这个我们可以查看下使用前后页面所占用内存的大小是否有变化。

我们可以通过chrome浏览器 设置 --> 更多工具 --> 任务管理器 查看页面占用内存大小。

페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다.

  • 首先是没有content-visibility: auto,页面占用内存大概为96.2MB

페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다.

  • 然后是添加了content-visibility: auto,页面占用内存仍然是96.2MB

페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다.

也就是说,它并不会减少页面占用内存大小,这些元素是真实存在于DOM树中的,并且我们也可以通过JS访问到

페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다.

是否会影响脚本的加载行为?

如果我们在添加了content-visibility: auto的元素内去加载脚本,并且此时的元素处于一个不可见的状态,那么此时元素内的脚本能够正常加载呢?

<!-- ... 第十二个 -->
<div class="visibility_item">
        <div class="inner">
            测试脚本
            <img src="../../../../images/22-11/페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다." alt="">
            <script src="./2.js"></script>
        </div>
        
</div>
로그인 후 복사

페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다.

很明显它并不会影响脚本与图片的加载行为,并且脚本再加载后能够正常执行。结合上面第一点,我们可以得出结论,使用了content-visibility: auto的元素影响的只是子元素的渲染,对于内部静态资源的加载还是正常进行。

但我们需要注意的是脚本的执行时机,如果要获取DOM元素的话,此时的脚本只能获取到它加载位置之前的DOM元素,而与它自身DOM有没有渲染无关!

// 2.js
console.log(&#39;测试脚本&#39;)
console.log(&#39;第十一个&#39;, document.querySelectorAll(&#39;.visibility_item&#39;)[10])

console.log(&#39;第十三个&#39;, document.querySelectorAll(&#39;.visibility_item&#39;)[12])
로그인 후 복사

페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다.

可访问性

使用了content-visibility: auto并且在非可视区的元素是否存在于可访问树中?

페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다.

这里我们可以看出content-visibility: auto是屏幕外的内容在文档对象模型中仍然可用,因此在可访问性树中(与visibility: hidden不同)。这意味着我们可以在页面上搜索并导航到该内容,而无需等待它加载或牺牲渲染性能。

这个功能特性是在chrome 90 中更新的,在 chrome 85-89 中,屏幕外的子元素content-visibility: auto被标记为不可见。

兼容性

content-visibility是chrome85新增的特性,所以兼容性还不是很高,但它是一个非常实用的CSS属性,由于跳过了渲染,如果我们大部分内容都在屏幕外,利用该content-visibility属性可以使初始用户加载速度更快。相信兼容性的问题在不久的将来会得到解决~페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다.

原文地址:https://juejin.cn/post/7168629736838463525

(学习视频分享:web前端

위 내용은 페이지 렌더링 성능을 향상시키는 데 도움이 되는 새로운 CSS 기능인 콘텐츠 가시성에 대해 이야기해 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
css
원천:juejin.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿