ホームページ > ウェブフロントエンド > CSSチュートリアル > ページのレンダリング パフォーマンスの向上に役立つ、新しい CSS 機能のコンテンツ可視性について話しましょう。

ページのレンダリング パフォーマンスの向上に役立つ、新しい CSS 機能のコンテンツ可視性について話しましょう。

青灯夜游
リリース: 2022-11-22 20:16:14
転載
2988 人が閲覧しました

ページのレンダリング パフォーマンスの向上に役立つ、新しい CSS 機能のコンテンツ可視性について話しましょう。

フロントエンド担当者にとって、最も問題となるのはページのパフォーマンスです。ユーザーがページにアクセスするとき、ユーザーは常にページが目の前に素早く表示され、インタラクティブであることを望んでいます。 。ページの読み込みが遅すぎると、ユーザーが離れていく可能性があります。したがって、フロントエンド開発者にとってページのパフォーマンスは最優先事項であり、実際、読み込みからレンダリングまでのプロセス全体を理解していれば、どこから始めればよいかがわかります。

まあ、脱線しないでください。今日は主に長いリスト ページのレンダリング パフォーマンスを研究します。

現在のページはますます複雑になっており、ページには多くの場合、多数のデータが含まれています。一部の電子商取引ページで数万の商品リストのレンダリングがフリーズしないようにするにはどうすればよいですか? このような長いリストのレンダリング シナリオに直面した場合、通常はページングまたは仮想リストを使用して速度を低下させます。ページの 1 回限りのレンダリングはプレッシャーですが、これらのメソッドは JS で実装する必要があるため、CSS のみを使用して実装できる解決策はありますか?

答えは「はい」です。今日の主役はコンテンツの可視性 (コンテンツの可視性) です。 [推奨される学習: css ビデオ チュートリアル ]

content-visibility

属性値

content-visibility は CSS の新しい属性で、主にページ レンダリングのパフォーマンスを向上させるために使用されます。要素がコンテンツをレンダリングするかどうかを制御し、ブラウザがこれらの要素のレイアウトとレンダリングをスキップできるようにします。

  • visible: デフォルト値、効果なし。要素のコンテンツは通常どおりにレイアウトされ、レンダリングされます。
  • hidden: 要素はコンテンツをスキップします。スキップされたコンテンツには、ページ内の検索やタブ オーダー ナビゲーションなどのユーザー エージェント機能からアクセスすることはできず、選択したりフォーカスしたりすることもできません。これは、コンテンツに display: none を設定するのと似ています。
  • auto: この要素は、レイアウトの包含、スタイルの包含、および描画の包含をオンにします。また、要素がユーザーに関係ない場合、そのコンテンツはスキップされます。 hidden とは異なり、スキップされたコンテンツは、ページ内の検索、タブ オーダー ナビゲーションなどのユーザー エージェント機能で適切に使用でき、適切にフォーカス可能および選択可能である必要があります。

content-visibility: hidden可視性を手動で管理する

前述のように、content-visibility: hidden の効果は次の場合と同じです。 display: none は似ていますが、実際には 2 つには大きな違いがあります。

  • content-visibility: hidden は子要素のみを非表示にし、それ自体は非表示にしません
  • content-visibility: hidden 非表示のコンテンツのレンダリング状態はキャッシュされるため、コンテンツが削除または表示されると、ブラウザーは再レンダリングせずにキャッシュを適用します。そのため、頻繁に切り替える必要がある場合は、非表示の要素を表示します。このプロパティにより、レンダリングのパフォーマンスが大幅に向上します。

ページのレンダリング パフォーマンスの向上に役立つ、新しい CSS 機能のコンテンツ可視性について話しましょう。

上記のことから、content-visibility:hidden 要素の子要素は実際にはレンダリングされないことがわかりますが、それ自体をレンダリングできます!

content-visibility: レンダリング作業を自動スキップします

慎重に考えてみましょう。ページには多くの要素がありますが、それらはユーザーに表示されるでしょうか?ユーザーが実際に見ることができるのはデバイスの表示領域のコンテンツのみであり、ページがスクロールしない限り、非表示領域のコンテンツは決して表示されません。ユーザーにはそれを見ることはできませんが、ブラウザーは実際にそれをレンダリングするため、パフォーマンスが大幅に浪費されます。したがって、ブラウザが目に見えない領域にコンテンツをレンダリングしないようにすることで、ページのレンダリングのパフォーマンスを向上させる方法を見つける必要があります。

上で説明した仮想リストの原理は、実際にはこれと似ています。最初の画面がロードされると、ビジュアル領域のコンテンツのみがロードされます。ページがスクロールすると、ダイナミクスは計算によって取得され、可視領域のコンテンツと、非可視領域のコンテンツが削除されるため、長いリストのレンダリング パフォーマンスが大幅に向上します。

ただし、これは 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>
ログイン後にコピー

まず第一に、これらの要素が

ページのレンダリング パフォーマンスの向上に役立つ、新しい CSS 機能のコンテンツ可視性について話しましょう。 通常のビジネスでこのように記述すると、ユーザーはこのページに入るときに直接フレグランスを吐き出す可能性があります。パフォーマンスを考慮して、上記を追加します。 :

.card_item {
  content-visibility: auto;
}
ログイン後にコピー

このときの効果を見てみましょう:

ページのレンダリング パフォーマンスの向上に役立つ、新しい 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 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
css
ソース:juejin.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート