"렌더링 차단 JavaScript 및 CSS 제거". 제가 항상 고수하는 Google Page Speed Insights 권장 사항입니다. Google에서는 처음에 필요한 CSS를 인라인(인라인)하고 페이지가 로드될 준비가 되면 CSS의 나머지 부분을 로드할 것을 권장합니다.
웹페이지에 액세스할 때 Google은 초기 보기에 유용한 항목만 로드하고 유휴 시간을 사용하여 다른 콘텐츠를 로드합니다. 이렇게 하면 사용자는 최대한 빨리 페이지를 볼 수 있습니다.
코드 분할, 트리 쉐이킹, 캐싱 등 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>
웹 브라우저가 이 페이지를 로드하면 처음부터 끝까지 읽습니다. 브라우저가 링크 태그에 도달하면 즉시 스타일 시트 다운로드를 시작하고 완료될 때까지 페이지를 렌더링하지 않습니다.
대규모 사이트, 특히 Bootstrap과 같은 대규모 프레임워크가 있는 사이트의 경우 스타일시트가 수백 kb에 달할 수 있으므로 사용자는 완전히 다운로드될 때까지 인내심을 갖고 기다려야 합니다.
그럼 렌더링이 차단되지 않는 본문의 스타일시트에 연결해야 할까요? 그렇게 할 수는 있지만 테넌트를 차단하는 것이 전적으로 나쁜 것은 아니며 실제로 이를 활용하고 싶습니다. . CSS가 로드되지 않은 채 페이지가 렌더링되면 보기 흉한 "플래시 스타일 없는 콘텐츠"가 생성됩니다.
우리가 원하는 가장 좋은 지점은 렌더링할 위치이며, 스타일링에 필요한 디자인 기본 보기인 중요한 CSS로 페이지를 차단하는 것입니다. 그러나 중요하지 않은 모든 CSS는 초기 렌더링 후에 로드됩니다.
Key CSS
제가 Bootstrap과 Webpack으로 만든 이 간단한 페이지를 살펴보세요. 첫 번째 렌더링 후의 모습은 다음과 같습니다.
이 페이지에는 "지금 등록" 버튼을 통해 열 수 있는 모달도 있습니다. 일단 열면 다음과 같습니다:
페이지의 첫 번째 렌더링에는 탐색 모음, 점보트론, 버튼에 대한 CSS 규칙과 레이아웃 및 글꼴에 대한 기타 일반 규칙이 필요합니다. 그러나 모달 규칙은 즉시 표시되지 않으므로 필요하지 않습니다. 이를 염두에 두고 중요한 CSS와 중요하지 않은 CSS를 구분할 수 있습니다.
tical.css
.nav { ... } .jumbtron { ... } .btn { ... }
non_tical.css
.modal { ... }
이 개념에 동의하면 다음 두 가지 질문에 관심이 있을 수 있습니다.
중요한 CSS와 중요하지 않은 CSS를 프로그래밍 방식으로 어떻게 구별할 수 있나요?
첫 번째 렌더링 전에 페이지에서 중요한 CSS를 로드하고 첫 번째 렌더링 후에 중요하지 않은 CSS를 로드하도록 만드는 방법은 무엇입니까?
예제 프로젝트
해결책을 찾았을 때 빠르게 소화하실 수 있도록 이 프로젝트의 기본 설정을 간략하게 안내해 드리겠습니다.
먼저, 부트스트랩 SASS를 입력 파일에 로드합니다.
main.js
require("bootstrap-sass/assets/stylesheets/_bootstrap.scss");
저는 sass-loader를 사용하여 이를 처리하고 이를 Extract Text 플러그인과 결합하여 컴파일된 CSS를 자체 파일에 넣습니다.
또한 HTML Webpack 플러그인을 사용하여 빌드에서 HTML 파일을 생성합니다. 곧 알게 되겠지만, 이 솔루션은 필수적입니다.
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 }) ] };
빌드를 실행한 후 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 모듈입니다. 곧 살펴보겠지만 그 외에도 더 많은 것이 있습니다.
중요한 CSS를 식별하는 Critical의 방법은 지정된 화면 크기를 사용하여 PhantomJS를 사용하여 페이지를 로드하고 페이지 렌더링에 사용된 CSS 규칙을 추출하는 것입니다.
이 프로젝트를 위해 설정한 방법은 다음과 같습니다.
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 중국어 웹사이트의 기타 관련 기사를 참조하세요!