【问题标题】:How to stop FOUC when using css loaded by webpack使用webpack加载的css时如何停止FOUC
【发布时间】:2016-04-06 14:15:52
【问题描述】:

在使用 webpack 时,在我的入口点加载 css 时,我得到了 FOUC。如果我从 webpack 加载我的 css 并将其作为普通链接包含在我的 html 文件中,那么 FOUC 的问题就会消失。

注意:这不仅仅是使用引导框架,我已经测试过 Foundation 和 Materialise 的结果相同

下面发布的代码只是我使用 Bootstrap 的问题的测试示例。

HTML代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>
<div class="container">
    <div class="jumbotron">
        <h1>Navbar example</h1>
    </div>
</div> <!-- /container -->

<script src="build/bundle.js"></script>
</body>
</html>

bootstrap.js 主入口点

import "../node_modules/bootstrap/dist/css/bootstrap.css";
import bootstrap from 'bootstrap'

$(document).ready(function () {
   console.log('bootstrap loaded')
});

webpack.config.js

var path = require('path');
const ProvidePlugin = require('webpack/lib/ProvidePlugin');
const webpack = require("webpack");

module.exports = {
  entry: './src/bootstrap.js',
  output: {
    path: path.join(__dirname, 'build'),
    filename: 'bundle.js'
  },
    resolve: {
        extensions: ['', '.js']
    },
    plugins: [
        new webpack.ProvidePlugin({
            $: "jquery",
            jQuery: "jquery",
            'window.jQuery': 'jquery'
        })
    ],
  devtool: 'inline-source-map',
  module: {
      resolve: {
          modulesDirectories: ['node_modules']
      },
    loaders: [
      {
        test: path.join(__dirname, 'src'),
        loader: 'babel-loader',
          query: {
              presets: ['es2015']
          }
      },
        { test: /\.css?$/, loader: 'style!css'},
        { test: /\.html$/, loader: 'html' },
        { test: /\.(png|gif|jpg)$/, loader: 'url', query: { limit: 8192 } },
        { test: /\.woff2(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url', query: { limit: 10000, mimetype: 'application/font-woff2' } },
        { test: /\.woff(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url', query: { limit: 10000, mimetype: 'application/font-woff' } },
        { test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'file' },
    ]
  }
};

【问题讨论】:

    标签: css webpack fouc


    【解决方案1】:

    ExtractTextWebpackPlugin 将允许您将 CSS 输出为单独的文件,而不是将其嵌入到 JS 包中。然后,您可以将此文件包含在您的 HTML 中,正如您所说,这可以防止无样式内容的闪烁。

    我建议仅在生产环境中使用它,因为它会阻止热加载工作并使您的编译时间更长。我将webpack.config.js 设置为仅在process.env.NODE_ENV === "production" 时应用插件;当您进行开发构建/运行开发服务器时,您仍然会获得 FOUC,但我觉得这是一个公平的权衡。

    有关如何设置的更多信息,请查看SurviveJS's guide


    更新:正如 cmets 中所述,ExtractTextWebpackPlugin 现在已被 mini-css-extract-plugin 取代 - 您应该改用它。

    【讨论】:

    • 一种更方便的方法,即使在热重新加载时也有效,是在应用样式表之前隐藏内容。使用 webpack 控制所有加载,我想它更难实现。
    • @LuisCrespo:这也绝对有可能!不过就我个人而言,我认为没有内容的闪现可能和没有样式的内容一样糟糕。我的回答中的方法应该消除两者,因为 CSS 可以正常加载到页面头部,而不是等待 JS 加载。
    • 这个插件的文档不一致
    • @CodeWhisperer:怎么会这样?
    • 如果您使用的是 webpack 4 或更高版本,Extract Text Plugin 的页面现在说要使用“mini-css-extract-plugin”。我做到了,而且对我来说效果很好。不如提取文本插件复杂,但可以满足需要。
    【解决方案2】:

    聚会有点晚了,但我是这样做的。

    虽然我认识到 extract-text-plugin 的优点,但它受到重建错误的困扰,该错误会打乱 css 顺序,并且设置起来很痛苦。并且在 js 中设置超时不是任何人都应该做的事情(它很丑,并且不能保证 100% 防止 fouc)...

    所以我的 index.html 是:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8"/>
        <style>
          #app { display: none }
        </style>
        <title></title>
      </head>
      <body>
        <div id="app"></div>
        <script src="scripts/bundle.js"></script>
      </body>
    </html>
    

    然后,在最后的 client.js 中添加:

    include "./unhide.css";
    

    ...并且 unhide.css 包含一行:

    #app { display: block }
    

    瞧,在加载整个应用程序之前,您什么都看不到。

    【讨论】:

    • 对于我的深色背景应用程序,我将其与&lt;body bgcolor="#19191C"&gt; 结合使用。
    • 我已经尝试过了(仍在试验),FOUC 仍然发生。至少我认为它是 FOUC,它更像是向屏幕中间擦拭。无论如何,我们使用 angular(切换以很快做出反应),我怀疑与它有更多关系。
    • 好的,所以现在的问题是用户会盯着一个空白区域一段时间......在我的例子中是 3 秒,+/- 1 秒。好吧,当然现在这是加载动画的机会。好的,但要让加载动画看起来不卡顿,它必须至少有 3 秒(至少一个动画循环周期)。所以我们从 FOUC 转到了 3 秒的加载动画。好吧,这些都是根据具体情况选择的主题。我更喜欢在早期展示一些结构,并且在加载时没有跳转界面。
    【解决方案3】:

    这很麻烦,但我将 ReactDom.render() 包装在我的根 index.js 文件中的 setTimeout() 中。

    setTimeout(ReactDOM.render(...), 0)

    【讨论】:

    • 最简单的解决方案。这只能针对开发模式有条件地完成。
    猜你喜欢
    • 2016-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-28
    • 2018-07-04
    • 2016-03-30
    • 2019-09-21
    相关资源
    最近更新 更多