【W(wǎng)ebpack】867- Webpack 優(yōu)化阻塞的 CSS

http://interview.poetries.top/
隨著瀏覽器的日新月異,網(wǎng)頁的性能和速度越來越好,并且對于用戶體驗來說也越來越重要。
現(xiàn)在有很多優(yōu)化頁面的辦法,比如:
靜態(tài)資源的合并和壓縮,code splitting,DNS預(yù)讀取等等
本文介紹的是另一種優(yōu)化方法:首屏阻塞css優(yōu)化
原理:
首先我們了解一下頁面的基本渲染流程
webkit渲染過程:

Gecko渲染過程:

那么,為什么要做這種優(yōu)化呢?上面的流程圖就是原因:首先解析
html生成dom樹,同時解析css生成css樹,之后結(jié)合兩者生成渲染樹,然后渲染到屏幕上。不但如此,如果css后面有其他javascript,并且css加載時間過長,也會阻塞后面的js執(zhí)行,因為js可能會操作dom節(jié)點或者css樣式,所以需要等待render樹完成。那么,如果我們能優(yōu)化css,那么就能大大減少頁面渲染出來的時間,從而提升pv,增加黏性
怎么做呢:
目前我知道的比較實用的辦法是webpack集成
critical,critical是一個提取關(guān)鍵css,內(nèi)聯(lián)到html中,并且使用preload和noscript兼容加載非關(guān)鍵css的工具。
那么,我們開門見山,直接從webpack配置開始:
const?HtmlWebpackPlugin?=?require('html-webpack-plugin');?//?創(chuàng)建html來服務(wù)你的資源
const?MiniCssExtractPlugin?=?require('mini-css-extract-plugin');?//?提取css到分離的文件,需要webpack4
const?HtmlCriticalWebpackPlugin?=?require('html-critical-webpack-plugin');?//?集成critical的html-webpack-plugin版本
const?path?=?require('path');
//?用于設(shè)置Chromium,因為Chromium使用npm或者yarn經(jīng)常有問題
process.env['PUPPETEER_EXECUTABLE_PATH']?=
????'你電腦中的Chromium地址';
module.exports?=?{
????mode:?'none',
????module:?{
????????rules:?[
????????????{
????????????????test:?/\.css$/,
????????????????//?使用MiniCssExtractPlugin.loader代替style-loader
????????????????use:?[MiniCssExtractPlugin.loader,?'css-loader']
????????????},
????????????{
????????????????test:?/\.js$/,
????????????????use:?{
????????????????????loader:?'babel-loader',
????????????????????options:?{
????????????????????????presets:?['@babel/preset-env']
????????????????????}
????????????????}
????????????}
????????]
????},
????plugins:?[
????????new?HtmlWebpackPlugin({?template:?'./index.html'?}),
????????new?MiniCssExtractPlugin({}),
????????new?HtmlCriticalWebpackPlugin({
????????????base:?path.resolve(__dirname,?'dist'),
????????????src:?'index.html',
????????????dest:?'index.html',
????????????inline:?true,
????????????minify:?true,
????????????extract:?true,
????????????width:?375,
????????????height:?565,
????????????//?確保調(diào)用打包后的JS文件
????????????penthouse:?{
????????????????blockJSRequests:?false
????????????}
????????})
????]
};
然后是html文件:
html>
<html?lang="en">
????<head>
????????<meta?charset="UTF-8"?/>
????????<meta?name="viewport"?content="width=device-width,?initial-scale=1.0"?/>
????????<meta?http-equiv="X-UA-Compatible"?content="ie=edge"?/>
????????<title>Documenttitle>
????head>
????<body>
????????<div?class="div">div>
??<h2>hello?worldh2>
??<div?class="mask">這是一個彈窗div>
????body>
html>
接著是css文件:
.div?{
????width:?200px;
????height:?100vh;
????background-color:?red;
}
h2?{
????color:?blue;
}
.mask?{
????width:?500px;
????height:?500px;
????display:?none;
????position:?absolute;
????top:?0;
????left:?0;
????bottom:?0;
????right:?0;
????margin:?auto;
?background-color:?yellowgreen;
}
運行
webpack后,查看打包后的html文件:
//?省略...
<style>
????.div?{
????????width:?200px;
????????height:?100vh;
????????background-color:?red;
????}
????.mask?{
????????width:?500px;
????????height:?500px;
????????display:?none;
????????position:?absolute;
????????top:?0;
????????left:?0;
????????bottom:?0;
????????right:?0;
????????margin:?auto;
????????background-color:?#9acd32;
????}
style>
<link
????href="main.80dc2a9c.css"
????rel="preload"
????as="style"
????onload="this.onload=null;this.rel='stylesheet'"
/>
<noscript><link?href="main.80dc2a9c.css"?rel="stylesheet"/>noscript>
//?省略...
可以看到,
h2標(biāo)簽的css樣式?jīng)]有出現(xiàn)在內(nèi)聯(lián)style里,而是出現(xiàn)在main.[hash].css中,因為它不再所設(shè)置首屏范圍內(nèi),這就是所謂的首屏css優(yōu)化
相關(guān)內(nèi)容
在上面打包后的html文件里,我們看到了有一個
link內(nèi)有rel="preload" as="style"字段,緊接著下面就有一個noscript標(biāo)簽,這兩個是做什么的呢?
rel="preload" as="style"``:用于進(jìn)行頁面預(yù)加載,rel="preload"通知瀏覽器開始獲取非關(guān)鍵CSS以供之后用。其關(guān)鍵在于,preload`不阻塞渲染,無論資源是否加載完成,瀏覽器都會接著繪制頁面。并且,搭配as使用,可以指定將要預(yù)加載內(nèi)容的類型,可以讓瀏覽器:更精確地優(yōu)化資源加載優(yōu)先級。 匹配未來的加載需求,在適當(dāng)?shù)那闆r下,重復(fù)利用同一資源。 為資源應(yīng)用正確的內(nèi)容安全策略。 為資源設(shè)置正確的 Accept請求頭。noscript:如果頁面上的腳本類型不受支持或者當(dāng)前在瀏覽器中關(guān)閉了腳本,則在HTMLxxxx国产 | 国产精品99久久久久久猫咪 | 中文在线资源天堂 | 麻豆精品国产 | 免费的看污片丝瓜视频 |
