web-dev-qa-db-ja.com

React [FOUC]のJSの前にCSSがロードされるのを待ちます

新しいウェブサイトを完全にReactで構築し、コード分割とscssを利用しています。新しいページがリクエストされるたびに、最初に生のHTMLがブラウザに読み込まれ、その後数秒後にcssスタイリングが入り、FOUCの問題のようです。これはひどい経験になり、コンポーネントをレンダリングする前にCSSがロードされていることを確認する方法を理解する必要があります。誰かがこれを経験したことがありますか?現在、この問題に関するオンライン情報が不足しています。現在、jsチャンクは10個ありますが、main.XXXXXXX.cssは1つだけです。

11
Gregg

Main.XXXXXXX.cssファイルが1つしかない場合は、それを最初のhtmlビューの<head>セクションに手動で挿入し、アプリへのエントリ(別名、最初のJSファイルまたはWebpackマニフェスト)を用意する必要があります。 JSファイル)同じhtmlビューの下部にロードされます。

例えば

<html>
   <head>
      ...some header stuff
      <link type="text/css" rel="stylesheet" href="/path/to/main.XXXXXXX.css">
   </head>
   <body>
      <div id="react-app"></div>
      <script src="/path/to/vendor.js"></script>
      <script src="/path/to/app_entry_or_webpack_manifest.js"></script>
   <body>
</html>

少なくとも上記のようなページを提供しているサーバーがあると想定しています。この場合(上記)、CSSはJSの前に読み込まれるため、FOUCの問題を回避する必要があります。

この問題は、アプリを分解するときに動的に生成されるcssファイルが多数ある場合(コード分割を介して)、はるかに困難になりますが、まだその問題があるようには思えません。

編集:動的に作成されたcssシートをエントリのhtmlファイルに挿入する方法がわからない可能性があることに気づきました。 mini-css-extract-plugin を使用する場合は、生成するファイル名を指定できます。この例では、オプションで[ハッシュ]を含めるかどうかを確認できます。あなたはハッシュを欲しくない。

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const devMode = process.env.NODE_ENV !== 'production'

module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // both options are optional
      filename: devMode ? '[name].css' : '[name].[hash].css',
      chunkFilename: devMode ? '[id].css' : '[id].[hash].css',
    })
  ],
  module: {
    rules: [
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader',
          'sass-loader',
        ],
      }
    ]
  }
}
4
Timothy Beamish

私は2つのオプションを考えることができます:

  1. 反応アプリのindex.js内でcssを呼び出します。
  2. DOMがロードされた後にreactアプリをレンダリングします。 index.js反応ファイルに次のようなものを追加してみてください。
    document.addEventListener("DOMContentLoaded", function(event) {
      ReactDOM.render(
        <App />,
        document.getElementById('root')
      );
    });

ベストプラクティスは、ReactJSコンポーネントによってレンダリングされたHTMLスタイルをそのコンポーネントで呼び出すことだと思います。したがって、オプション1を選択します。注:cssファイルがグローバルファイルの場合、リファクタリングはコンポーネント内のコンポーネントのスタイルのみを持つと見なすことができます。

1
Nico Diz