読者です 読者をやめる 読者になる 読者になる

ふろしき.js

Web + Mobile + UX + Performance Tech

CSSのロードタイミングの不備が引き起こす、FOUCとは?

CSS 用語・TIPS Web制作者向け SI向け Webパフォーマンス

FOUC(Flash of Unstyled Content)とは、Webページへアクセスした直後、CSSによるデザインが有効でないページが一瞬だけ表示される現象のことです。

まず、下の例をご覧下さい。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf8" />
    <title>Example</title>
    <link rel="stylesheet" href="hoge.css" type="text/css" />
  </head>
  <body>
    ・・・
  </body>
</html>


この例では、CSSの外部ファイルをhead要素内から呼び出しています。この方法はもうずっと昔から守られている伝統で、誰しもが無意識のうちにやっていることでしょう。

しかしCSSの外部ファイル参照は、head要素の外でやっても問題なく動作します。つまり、以下のような書き方も許容されるわけです。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf8" />
    <title>Example</title>
  </head>
  <body>
    ・・・
    <link rel="stylesheet" href="hoge.css" type="text/css" />
  </body>
</html>

この例では、bodyタグの一番後ろの要素にCSSファイルの参照を行わせています。もちろんこれでも動作はしますが、問題を孕んでいます。

Webブラウザはページをロードする際、ロードしたページの内容、つまりHTMLファイルを上から順に読み込み処理します。html要素を読み込み、head要素を読み込み、body要素を読み込み、body内のdivやul要素を読み込み・・・、と順番にDOMを解釈してはレンダリングを行うといった動作をするのです。

これはScriptやStyle要素でも同様で、script要素を見つけたらscript要素内のJavaScriptコンパイルし実行、style要素を見つけたらStyle要素内のCSSをパースしプロパティをロード、これは外部ファイルであっても同じ動きになります。HTMLファイル内を構成する各要素は、例えスクリプトであってもデザインの指定であっても、直列に解釈され処理されていくことになります。

するとどうなるでしょう。2番目に挙げた例では、CSSのロードをbody要素の最後で行っていました。body要素内の全てのDOMツリーのロードが終わり、せっかくレンダリングが完了しているのに、最後の最後というタイミングでCSSのプロパティが読み込まれてしまいます。せっかくレンダリングしたのに、CSSが最後に読み込まれてしまったことで、変更後の装飾された状態のDOMを再び計算しレンダリングすることになるのです。

もし参照されているCSSファイルのロードが遅い場合、或いは直前のJavaScriptで重い処理を行った場合、ブラウザ上には一瞬だけ、CSSで装飾される前の状態が表示されることになります。これがFOUCと呼ばれる現象です。

かつてはWebブラウザの作りの悪さを揶揄する言葉でした。IE5は如何なる時でも、このような動作を行っていたためです。しかし改善が進んだ今、この問題は、Webブラウザの作りでなくWebコンテンツの作りによって引き起こされます。

作りによっては、FOUCをどうしても避けられないケースもあります。ただそれは本当に限られたケーススタディのはずです。基本的にはCSSの読み込みをhead要素内で行うようにし、ユーザエクスペリエンスの低下を最小限に抑えるよう努めましょう。

広告を非表示にする