ホームページ > 記事 > ウェブフロントエンド > レンダリングを妨げる CSS を削減する自動化方法の詳細な説明
「レンダリングをブロックする JavaScript と CSS を削除する」。これは私が常にこだわっている Google Page Speed Insights の推奨事項です。 Google では、最初に必要な CSS をインライン化(インライン)し、ページを読み込む準備ができたら残りの CSS を読み込み、アイドル時間を他のコンテンツの読み込みに使用することを推奨しています。こうすることで、ユーザーはできるだけ早くそのページを見ることができます。
コード分割、ツリーシェイキング、キャッシュなど、JavaScript のデリゲートブロックを最小限に抑えるために、さまざまなことができます。
CSS についてはどうでしょうか? これを行うには、上記のコンテンツに使用される CSS (つまり、重要な CSS) を分離し、最初にロードすることで、デリゲートのブロックを最小限に抑えることができます。次に、重要ではない CSS を読み込むことができます。
重要な CSS をプログラム的に分離することは可能です。この記事では、それを Webpack パイプラインに委任する方法を説明します。
#レンダリングのブロックとは何を意味しますか?リソースが「レンダリング ブロック」である場合、リソースがダウンロードまたは処理されるまでブラウザーはページを表示できないことを意味します。
通常、次のようにドキュメントの先頭にあるスタイルシートにリンクすることで、CSS をブロックする方法で読み込みます。<head> <link rel="stylesheet" href="/style.css"> ... </head> <body> <p>I can't be seen until style.css has been loaded!</p> </body>Web ブラウザーがこのページを読み込むと、それが読み取られます。初めから最後まで。ブラウザがリンク タグに到達すると、すぐにスタイル シートのダウンロードが開始され、完了するまでページは表示されません。 大規模なサイト、特に Bootstrap のような大規模なフレームワークを備えたサイトの場合、スタイルシートは数百 kb になる場合があり、ユーザーは完全にダウンロードされるまで辛抱強く待つ必要があります。 それでは、レンダリングがブロックされない本文内のスタイルシートにリンクする必要がありますか? それは可能ですが、実際のところ、テナントをブロックすることは完全に悪いことではなく、実際にはそうしたいのです。それの利点。 CSS をロードせずにページをレンダリングすると、醜い「スタイルのないフラッシュ コンテンツ」が表示されます。
必要なスイート スポットは、キーを使用してレンダリングする場所です。CSS は、ページ。メイン ビューのスタイルを設定するために必要ですが、重要でない CSS はすべて最初のレンダリング後に読み込まれます。
Bootstrap と Webpack を使用して作成したこの単純なページを見てください。最初にレンダリングされた後の外観は次のとおりです。
このページには、[今すぐ登録] ボタンから開くことができるモーダルもあります。開くと、次のようになります:
ページの最初のレンダリングでは、ナビゲーション バー、ジャンボトロン、ボタン、およびレイアウトに関するその他の一般的なルールとフォント CSS ルールが必要です。 。ただし、モーダル ルールはすぐには表示されないため、必要ありません。これを念頭に置いて、重要な CSS を非クリティカル CSS から分離できます。
.nav {
...
}
.jumbtron {
...
}
.btn {
...
}non_critical.css.modal {
...
} この概念に同意する場合は、おそらく次の 2 つの質問に興味があるでしょう:
プログラム的に重要な CSS と非重要な CSS をどのように区別しますか?解決策が見つかったときにすぐに理解できるように、このプロジェクトの基本的なセットアップについて簡単に説明します。
まず、ブートストラップ SASS を入力ファイルにロードします。 main.jsrequire("bootstrap-sass/assets/stylesheets/_bootstrap.scss");私は sass-loader を使用してこれを処理し、それを Extract Text Plugin と組み合わせて、コンパイルされた CSS を独自のファイルに入れています。 また、HTML Webpack プラグインを使用して、ビルド内で HTML ファイルを作成します。すぐにわかるように、この解決策は不可欠です。 webpack.config.jsmodule.exports = {
module: {
rules: [
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'sass-loader']
})
},
...
]
},
...
plugins: [
new ExtractTextPlugin({ filename: 'style.css' }),
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
})
]
};ビルドを実行すると、HTML ファイルは次のようになります。 CSS はヘッドに読み込まれるため、レンダリングがブロックされることに注意してください。 index.html<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>vuestrap-code-split</title>
<link href="/style.css" rel="stylesheet">
</head>
<body>
<!--App content goes here, omitted for brevity.-->
<script type="text/javascript" src="/build_main.js"></script>
</body>
</html>
重要な CSS をプログラムで特定する重要な CSS を手動で特定するのは面倒な場合があります。これをプログラムで行うには、Addy Osmani による Critical
という適切な名前のツールを使用できます。これは、HTML ドキュメントを読み取り、重要な CSS を識別する Node.js モジュールです。すぐに説明するように、それだけではありません。 このプロジェクトの設定方法は次のとおりです:const critical = require("critical");
critical.generate({
/* The path of the Webpack bundle */
base: path.join(path.resolve(__dirname), 'dist/'),
src: 'index.html',
dest: 'index.html',
inline: true,
extract: true,
/* iPhone 6 dimensions, use whatever you like*/
width: 375,
height: 565,
/* Ensure that bundled JS file is called */
penthouse: {
blockJSRequests: false,
}
});
执行时,这将把Webpack包输出中的HTML文件更新为:
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Bootstrap Critical</title>
<style type="text/css">
/* Critical CSS is inlined into the document head, abbreviated here. */
body {
font-family: Helvetica Neue,Helvetica,Arial,sans-serif;
font-size: 14px;
line-height: 1.42857;
color: #333;
background-color: #fff;
}
...
</style>
<link href="/style.96106fab.css" rel="preload" as="style" onload="this.rel='stylesheet'">
<noscript>
<link href="/style.96106fab.css" rel="stylesheet">
</noscript>
<script>
/*A script for loading the non-critical CSS goes here, omitted for brevity.*/
</script>
</head>
<body>
<!--App content goes here, omitted for brevity.-->
<script type="text/javascript" src="/build_main.js"></script>
</body>
</html>它还将输出一个新的css文件,例如style.96106fab.css(文件名会自动添加一个散列)。这个css文件与原始样式表相同,只是去掉了关键的css。
内联关键css
您将注意到关键的CSS已内联到文档的头部。这是最优的,因为页面不必从服务器加载它。
预加载非关键CSS
您还将注意到,非关键CSS加载了外观精美的链接。 preload值告诉浏览器开始获取非关键CSS供挂起使用。 但至关重要的是,预加载不是渲染阻止,因此无论预加载资源是否完成,浏览器都将继续绘制页面。
链接中的onload属性允许我们在非关键的CSS最终加载后运行脚本。关键模块自动将脚本内联到文档中,从而提供跨浏览器兼容的方式将非关键样式表加载到页面中。
<link href="/style.96106fab.css" rel="preload" as="style" onload="this.rel='stylesheet'">
将critical放入webpack管道
我制作了一个名为html关键webpack plugin的webpack插件,它仅仅是关键模块的包装器。它将在您的文件从HTML网页包插件发出后运行。
以下是如何将它包含在Webpack项目中:
const HtmlCriticalPlugin = require("html-critical-webpack-plugin");
module.export = {
...
plugins: [
new HtmlWebpackPlugin({ ... }),
new ExtractTextPlugin({ ... }),
new HtmlCriticalPlugin({
base: path.join(path.resolve(__dirname), 'dist/'),
src: 'index.html',
dest: 'index.html',
inline: true,
minify: true,
extract: true,
width: 375,
height: 565,
penthouse: {
blockJSRequests: false,
}
})
]
};注意:您可能只应该在生产构建中使用它,而不是在开发中,因为它会使您的构建非常慢!
性能结果
现在我已经隔离了关键的CSS,并在空闲时间加载了非关键的CSS,那么如何改进性能呢?
我使用Chrome的灯塔扩展来寻找答案。请记住,我们试图优化的度量标准是第一次有意义的绘制的时间,它基本上告诉我们用户看到某些东西需要多长时间。
在实施关键的CSS:

关键的CSS实现后:
如您所见,我的应用程序在整整一秒钟前就获得了一幅有意义的画作,并且在半秒钟前就实现了交互。
实际上,你可能不会在你的应用程序中得到如此显著的改进,因为我的css已经完全膨胀了(我包括了整个引导库),在这样一个简单的应用程序中,我没有很多关键的css规则。
英文原文地址:https://vuejsdevelopers.com/2017/07/24/critical-css-webpack/
更多编程相关知识,请访问:编程课程!!
以上がレンダリングを妨げる CSS を削減する自動化方法の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。