Heim > Artikel > Web-Frontend > Detaillierte Erläuterung automatisierter Methoden zur Reduzierung von Render-blockierendem CSS
„Renderblockierendes JavaScript und CSS beseitigen“. Das ist die Empfehlung von Google Page Speed Insights, an die ich mich immer halte. Google empfiehlt, dass Sie das CSS, das Sie zunächst benötigen, einbinden (Inline) und den Rest des CSS laden, wenn die Seite zum Laden bereit ist Nutzen Sie die Leerlaufzeit, um andere Inhalte zu laden. Auf diese Weise können Benutzer die Seite so früh wie möglich sehen.
Es gibt viele Dinge, die wir tun können, um die Blockierung der JavaScript-Delegierung zu minimieren, wie z. B. Code-Splitting, Tree-Shaking, Caching usw.
Was ist mit CSS? Um dies zu erreichen, können wir die Blockierung von Delegaten minimieren, indem wir das für die oben genannten Zwecke verwendete CSS (d. h. das kritische CSS) isolieren und es zuerst laden. Dann können wir unkritisches CSS laden.
Das Isolieren von kritischem CSS ist programmgesteuert möglich, und in diesem Artikel zeige ich Ihnen, wie Sie es an die Webpack-Pipeline delegieren.
Was bedeutet Renderblockierung? Wenn eine Ressource „Rendering-blockierend“ ist, bedeutet das, dass der Browser die Seite erst anzeigen kann, wenn die Ressource heruntergeladen oder verarbeitet wurde.
Normalerweise würden wir das CSS auf blockierende Weise laden, indem wir auf das Stylesheet am Kopf des Dokuments verlinken, etwa so:
<head> <link rel="stylesheet" href="/style.css"> ... </head> <body> <p>I can't be seen until style.css has been loaded!</p> </body>
Wenn der Webbrowser diese Seite lädt, liest er sie von Anfang bis Ende. Nehmen Sie es. Wenn der Browser das Link-Tag erreicht, beginnt er sofort mit dem Herunterladen des Stylesheets und rendert die Seite erst, wenn der Vorgang abgeschlossen ist.
Bei großen Websites, insbesondere solchen mit großen Frameworks wie Bootstrap, kann das Stylesheet Hunderte von KB groß sein, und Benutzer müssen geduldig warten, bis es vollständig heruntergeladen ist.
Sollten wir also auf das Stylesheet im Text verlinken, wo das Rendering nicht blockiert? Das können Sie tun, aber die Sache ist, dass das Blockieren von Mandanten nicht unbedingt eine schlechte Sache ist, wir wollen es tatsächlich ausnutzen. Wenn die Seite ohne geladenes CSS gerendert wird, erhalten wir hässliche „Flash-Styleless-Inhalte“:
Der Sweet Spot, den wir wollen, ist, wo gerendert werden soll, und blockiert die Seite mit dem kritischen CSS, das die Design-Hauptansicht darstellt, die für das Styling erforderlich ist , aber alle nicht kritischen CSS werden nach dem ersten Rendern geladen.
Key CSS Schauen Sie sich diese einfache Seite an, die ich mit Bootstrap und Webpack erstellt habe. So sieht es nach dem ersten Rendern aus:
Die Seite verfügt außerdem über ein Modal, das über den Button „Jetzt registrieren“ geöffnet werden kann. Nach dem Öffnen sieht es so aus:
Für das erste Rendern der Seite benötigen wir CSS-Regeln für Navigationsleiste, Jumbotron, Schaltflächen und einige andere allgemeine Regeln für Layout und Schriftarten. Aber wir brauchen die Modalregeln nicht, weil sie nicht sofort angezeigt werden. Vor diesem Hintergrund können wir kritisches CSS von unkritischem CSS trennen:
critical.css
.nav { ... } .jumbtron { ... } .btn { ... }
non_critical.css
.modal { ... }
Wenn Sie mit diesem Konzept einverstanden sind, könnten Sie die folgenden zwei Fragen interessieren:
Beispielprojekt Ich werde Sie kurz durch den grundlegenden Aufbau dieses Projekts führen, damit Sie es schnell verstehen können, wenn wir eine Lösung finden.
Zuerst lade ich Bootstrap-SASS in meine Eingabedatei.
main.js
require("bootstrap-sass/assets/stylesheets/_bootstrap.scss");
Ich bearbeite dies mit dem Sass-Loader und kombiniere ihn mit dem Extract Text Plugin, um das kompilierte CSS in einer eigenen Datei abzulegen.
Ich verwende auch das HTML-Webpack-Plugin, um HTML-Dateien im Build zu erstellen. Wie Sie gleich sehen werden, ist diese Lösung unerlässlich.
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 }) ] };
Nach dem Ausführen des Builds sieht die HTML-Datei so aus. Beachten Sie, dass das CSS im Kopf geladen wird und daher das Rendern blockiert.
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>
Kritisches CSS programmgesteuert identifizierenKritisches CSS manuell identifizieren kann mühsam sein. Um dies programmgesteuert zu tun, können wir ein Tool mit dem treffenden Namen „Critical“ von Addy Osmani verwenden. Dies ist ein Node.js-Modul, das ein HTML-Dokument liest und kritisches CSS identifiziert. Es steckt noch mehr dahinter, wie wir gleich sehen werden.
Criticals Methode zur Identifizierung von kritischem CSS besteht darin, die Seite mit PhantomJS zu laden, die angegebenen Bildschirmabmessungen zu verwenden und alle CSS-Regeln zu extrahieren, die beim Rendern der Seite verwendet werden. So haben wir es für dieses Projekt eingerichtet:
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/
更多编程相关知识,请访问:编程课程!!
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung automatisierter Methoden zur Reduzierung von Render-blockierendem CSS. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!