等待CSS加载,然后再在React [FOUC]中使用JS

Gre*_*egg 11 css rendering sass reactjs code-splitting

我们将完全使用React构建我们的新网站,并利用代码拆分和scss。每当请求新页面时,它首先将原始HTML加载到浏览器中,然后瞬间加载CSS样式,这似乎是一个FOUC问题。这带来了可怕的体验,我们需要弄清楚如何在渲染组件之前确保CSS已加载。有人对这个有经验么?当前,此问题似乎缺少在线信息。我们目前有10个js块,但只有一个main.XXXXXXX.css。

Tim*_*ish 7

如果你只有一个 main.XXXXXXX.css 文件,那么你应该手动将它注入到<head>初始 html 视图的部分,并在你的应用程序(也就是初始 JS 文件或一些 webpack manifest 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>
Run Code Online (Sandbox Code Playgroud)

我假设您有一个服务器,它至少提供一个与上述类似的页面。在这种情况下(上图),您的 CSS 将在您的 JS 之前加载,您应该避免 FOUC 问题。

如果您有许多 css 文件,并且在您拆分应用程序时动态生成(通过代码拆分),这个问题就会变得更加困难,但听起来您还没有遇到这个问题。

编辑:刚刚意识到您可能不知道如何将动态创建的 css 表注入到您的条目 html 文件中。如果您使用mini-css-extract-plugin,那么您可以指定它生成的文件名。在此示例中,您可以看到您可以选择包含或不包含 [hash]。你很容易不想要哈希。

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',
        ],
      }
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 在 `&lt;head&gt;` 拥有样式并不能保证它们会在位于 `&lt;body&gt;` 的 `&lt;script&gt;` 之前被解析,即使是使用 `rel='preload'` (2认同)