レンダリング ブロック CSS

公開日: 2014 年 3 月 31 日

デフォルトでは、CSS はレンダリング ブロック リソースとして扱われます。つまり、ブラウザは、CSSOM の構築が完了するまで、処理済みコンテンツのレンダリングを保留します。CSS のサイズを小さくし、できるだけ早く配信されるようにし、メディアタイプやメディアクエリを利用してレンダリングのブロックを解除してください。

レンダリング ツリーの構築で説明したように、クリティカル レンダリング パスでは、レンダリング ツリーの構築に DOM と CSSOM の両方が必要でした。このことは、パフォーマンス上重要な意味を持ちます。HTML と CSS の両方がレンダリング ブロック リソースです。DOM がなければレンダリングできないのですから HTML については理解できます。しかし、CSS が必要である理由はわかりにくいかもしれません。CSS でレンダリングをブロックせずに一般的なページをレンダリングしようとすると、どうなりますか。

概要

  • デフォルトでは、CSS はレンダリング ブロック リソースとして扱われます。
  • メディアタイプやメディアクエリを利用すると、一部の CSS リソースを非レンダリング ブロックとして指定することができます。
  • CSS リソースは、ブロック リソースであるか非ブロック リソースであるかにかかわらず、すべてブラウザでダウンロードされます。
NYTimes と CSS
The New York Times と CSS
CSS なしの NYTimes
CSS なしの The New York Times(FOUC)

上記の例では、CSS ありと CSS なしで New York Times のウェブサイトを表示しています。これを見ると、CSS の準備が整うまでレンダリングがブロックされる理由がわかります。CSS がない場合、ページは実質的に利用できません。右側のような状態は、FOUC(Flash of Unstyled Content)と呼ばれます。ブラウザは、DOM と CSSOM の両方を取得するまでレンダリングをブロックします。

CSS はレンダリング ブロック リソースです。できるだけ早くクライアントに配信して、最初のレンダリングまでの時間を最適化する必要があります。

しかし、ページが印刷されている場合や大きなモニターに投影されている場合など、特定の条件でのみ使用される CSS スタイルがある場合はどうでしょうか。これらのリソースでレンダリングをブロックする必要がないと便利です。

CSS の「メディアタイプ」「メディアクエリ」次のようなユースケースに対応できます

<link href="style.css" rel="stylesheet" />
<link href="print.css" rel="stylesheet" media="print" />
<link href="other.css" rel="stylesheet" media="(min-width: 40em)" />

メディアクエリは、メディアタイプと、特定のメディア機能の条件をチェックする 0 個以上の式で構成されます。たとえば、先ほどのスタイルシートの宣言ではメディアタイプやメディアクエリを指定していないため、すべての場合に適用されます。つまり 常にレンダリング ブロックになります一方、2 番目のスタイルシート宣言は、コンテンツが印刷される場合にのみ適用されます。たとえば、レイアウトの並べ替え、フォントの変更、印刷に関するその他の重要なデザイン上の考慮事項などです。したがって、このスタイルシート宣言では、ページが最初に読み込まれるときにページのレンダリングをブロックする必要はありません。最後のスタイルシート宣言では「メディアクエリ」を指定しています。によって実行されます。条件が一致した場合、ブラウザはスタイルシートがダウンロードされて処理されるまで、レンダリングをブロックします。

メディアクエリを利用することで、表示用と印刷用など、具体的なユースケースに合わせて体裁を調整でき、画面方向の変化やサイズ変更イベントなど、動的な条件に合わせて調整を行うこともできます。スタイルシート アセットを宣言する場合は、メディアタイプとクエリに細心の注意を払ってください。クリティカル レンダリング パスのパフォーマンスに大きく影響します。

次のような例を想定します。

<link href="style.css" rel="stylesheet" />
<link href="style.css" rel="stylesheet" media="all" />
<link href="portrait.css" rel="stylesheet" media="orientation:portrait" />
<link href="print.css" rel="stylesheet" media="print" />
  • 最初の宣言はレンダリング ブロックで、すべての条件に一致します。
  • 2 つ目の宣言もレンダリング ブロックです。"all" はデフォルトのタイプであるため、タイプを指定しなかった場合、暗黙的に "all" に設定されます。したがって、1 つ目と 2 つ目の宣言は、実のところ同等です。
  • 3 つ目の宣言には、ページの読み込み時に評価される動的メディアクエリが含まれています。ページが読み込まれるときの端末画面の向きに応じて、portrait.css がレンダリング ブロックになるかどうかが決まります。
  • 最後の宣言は、ページが印刷される際にのみ適用されます("print")。したがって、ページが最初にブラウザに読み込まれる際にはレンダリング ブロックにはなりません。

最後に「レンダリング ブロック」はこれは、ブラウザがそのリソースでページの初期レンダリングを保持する必要があるかどうかのみを指します。いずれの場合も、ブラウザは CSS アセットをダウンロードしますが、ブロックしないリソースの優先度は低くなります。

フィードバック