"Éliminez JavaScript et CSS bloquant le rendu". C'est la recommandation de Google Page Speed Insights à laquelle je m'en tiens toujours. Google vous recommande d'intégrer le CSS dont vous avez initialement besoin (inline) et de charger le reste du CSS lorsque la page est prête à être chargée
Lorsqu'une page Web est consultée, Google souhaite qu'elle charge uniquement ce qui est utile pour la vue initiale et utilisez le temps d'inactivité pour charger d'autres contenus. De cette façon, les utilisateurs peuvent voir la page le plus tôt possible.
Il existe de nombreuses choses que nous pouvons faire pour minimiser le blocage des délégués en JavaScript, telles que le fractionnement du code, le tremblement d'arborescence, la mise en cache, etc.
Qu'en est-il du CSS ? Pour ce faire, nous pouvons minimiser le blocage des délégués en isolant le CSS utilisé pour ce qui précède (c'est-à-dire le CSS critique) et en le chargeant en premier. Ensuite, nous pouvons charger du CSS non critique.
Isoler les CSS critiques est possible par programmation, et dans cet article je vais vous montrer comment le déléguer au pipeline Webpack.
Que signifie le blocage du rendu ?
Si une ressource « bloque le rendu », cela signifie que le navigateur ne peut pas afficher la page tant que la ressource n'est pas téléchargée ou traitée.
Normalement, on charge le CSS de manière bloquante en créant un lien vers la feuille de style dans l'en-tête du document, comme ceci :
<head> <link rel="stylesheet" href="/style.css"> ... </head> <body> <p>I can't be seen until style.css has been loaded!</p> </body>
Quand le navigateur web chargera cette page, il la lira du début à la fin. Lorsque le navigateur atteint la balise de lien, il commencera immédiatement à télécharger la feuille de style et n'affichera pas la page tant qu'elle n'aura pas terminé.
Pour les grands sites, en particulier ceux dotés de grands frameworks comme Bootstrap, la feuille de style peut faire des centaines de Ko et les utilisateurs doivent attendre patiemment jusqu'à ce qu'elle soit complètement téléchargée.
Alors, devrions-nous créer un lien vers la feuille de style dans le corps, où le rendu ne sera pas bloqué ? Vous pouvez le faire, mais le fait est que bloquer les locataires n'est pas entièrement une mauvaise chose, nous voulons en fait le faire ? profitez-en. Si la page s'affiche sans aucun CSS chargé, nous obtenons un "contenu flash sans style" laid :
Le point idéal que nous voulons est l'endroit où rendre, avec la clé Le CSS bloque le page, qui est nécessaire pour styliser la vue principale, mais tous les CSS non critiques sont chargés après le rendu initial.
Clé CSS
Regardez cette page simple que j'ai construite avec Bootstrap et Webpack. Voici à quoi cela ressemble après le premier rendu :
La page dispose également d'un modal qui peut être ouvert via le bouton "S'inscrire maintenant". Une fois ouvert, cela ressemble à ceci :
Pour le premier rendu de la page, nous avons besoin d'une barre de navigation, d'un jumbotron, d'un bouton et de quelques autres règles générales de mise en page et des règles CSS des polices . Mais nous n'avons pas besoin des règles modales car elles ne seront pas affichées immédiatement. Dans cette optique, nous pouvons séparer les CSS critiques des CSS non critiques :
critical.css
.nav { ... } .jumbtron { ... } .btn { ... }
non_critical.css
.modal { ... }
Si vous êtes d'accord avec ce concept, vous probablement Vous serez intéressé par les deux questions suivantes :
Comment distinguer les CSS critiques et non critiques grâce à la programmation ?
Comment créer la page Charger le CSS critique avant le premier rendu et le CSS non critique après le premier rendu ?
Exemple de projet
Je vais vous présenter brièvement la configuration de base de ce projet afin que vous puissiez le digérer rapidement lorsque nous trouverons une solution.
Tout d’abord, je charge bootstrap SASS dans mon fichier d’entrée.
main.js
require("bootstrap-sass/assets/stylesheets/_bootstrap.scss");
J'utilise sass-loader pour gérer cela et je le combine avec le plugin Extract Text pour mettre le CSS compilé dans son propre fichier.
J'utilise également le plugin HTML Webpack pour créer les fichiers HTML dans le build. Comme vous le verrez bientôt, cette solution est indispensable.
webpack.config.js
module.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 }) ] };
Après avoir exécuté la build, le fichier HTML ressemble à ceci. A noter que le CSS est chargé dans le head et bloque donc le rendu.
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>
Identifier les CSS critiques par programmation
L'identification manuelle des CSS critiques peut être fastidieuse. Pour ce faire par programmation, nous pouvons utiliser l'outil bien nommé Critical d'Addy Osmani. Il s'agit d'un module Node.js qui lira un document HTML et identifiera les CSS critiques. Il y a bien plus que cela, comme nous le verrons bientôt.
La méthode de Critical pour identifier les CSS critiques consiste à charger la page à l'aide de PhantomJS, en utilisant les dimensions d'écran spécifiées, et à extraire toutes les règles CSS utilisées dans le rendu de la page.
Voici comment nous l'avons configuré pour ce projet :
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/
更多编程相关知识,请访问:编程课程!!
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!