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要素内で行うようにし、ユーザエクスペリエンスの低下を最小限に抑えるよう努めましょう。