🌊

Next.js + CSS ModulesでFOUC(CSSの適用遅れによるちらつき)が発生したときの暫定対策

2021/02/09に公開
3

発生していた問題

https://twitter.com/Meijin_garden/status/1356172726856126465

はじめて https://zenn.dev を読み込んだときに、一瞬スタイルがあたっていない状態で表示されてしまう問題が発生していました。

いわゆるFOUC(Flash of unstyled content)と呼ばれる現象です。少し遅れてスタイルがあたるため、ちらつき・がたつきが生じてユーザー体験がよくありません。

ちなみに発生する条件は以下です。

  • Next.js で CSS Modulesを使用(styled-componentsでは問題なし)
    • 後述のIssueではstyled-jsxでも同じ問題が報告されている
  • Google Chrome (FireFoxとSafariでは問題なし)
  • SSRしたとき(クライアントでのページ遷移時は問題なし)

なんとなくChromeのpreload周りの挙動に原因がありそうなのですが、検証はできていません。

該当するIssue

色々と探してみたところ下記のIssueに行き着きました。今回発生していた問題はおそらくこちらに該当します。

https://github.com/vercel/next.js/issues/18769

2021/02/09時点ではまだ未解決ですが、メンテナにより「bug」ラベルがつけられているので、そのうちNext.js側で対応される可能性があります。

現状のワークアラウンド

上述のIssueにコメントされているのですが、空の<script>を、<body>の直後に配置すると問題が発生しなくなりました。

_document.tsx
 import Document, { Html, Head, Main, NextScript } from 'next/document';
 
 class MyDocument extends Document {
   render() {
     return (
       <Html lang="ja">
         <Head />
         <body>
+          <script> </script>
           <Main />
           <NextScript />
         </body>
       </Html>
     );
   }
 } 

 export default MyDocument;

このハックはFirefox での FOUC 対策 - jxckで見たことがあったのですが、今回はChromeで効果がありました。

参考:Various websites like GitHub load with flash of unstyled content (FOUC)

根本的な解決ではないので、引き続き情報を追っていきたいと思います。

Discussion