webpack減少阻塞渲染的css(別名首屏阻塞css優(yōu)化)

隨著瀏覽器的日新月異,網(wǎng)頁的性能和速度越來越好倒脓,并且對于用戶體驗來說也越來越重要。
現(xiàn)在有很多優(yōu)化頁面的辦法埃脏,比如:靜態(tài)資源的合并和壓縮,code splitting东羹,DNS預(yù)讀取等等愕难。
本文介紹的是另一種優(yōu)化方法:首屏阻塞css優(yōu)化

原理:

首先我們了解一下頁面的基本渲染流程(參考):
webkit渲染過程:
[圖片上傳失敗...(image-93b228-1543318972487)]
Gecko渲染過程:
[圖片上傳失敗...(image-f8fd83-1543318972487)]
那么,為什么要做這種優(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文件:

<!DOCTYPE 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>Document</title>
    </head>
    <body>
        <div class="div"></div>
        <h2>hello world</h2>
        <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>
// 省略...

代碼倉庫在此,點擊fork進行實戰(zhàn)練習(xí)

可以看到烁涌,h2標簽的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標簽蜓肆,這兩個是做什么的呢?

  • rel="preload" as="style": 用于進行頁面預(yù)加載谋币,rel="preload"通知瀏覽器開始獲取非關(guān)鍵CSS以供之后用仗扬。其關(guān)鍵在于,preload不阻塞渲染蕾额,無論資源是否加載完成早芭,瀏覽器都會接著繪制頁面。并且诅蝶,搭配as使用退个,可以指定將要預(yù)加載內(nèi)容的類型,可以讓瀏覽器:
    1. 更精確地優(yōu)化資源加載優(yōu)先級调炬。
    2. 匹配未來的加載需求语盈,在適當?shù)那闆r下,重復(fù)利用同一資源筐眷。
    3. 為資源應(yīng)用正確的內(nèi)容安全策略黎烈。
    4. 為資源設(shè)置正確的 Accept 請求頭。
  • noscript:如果頁面上的腳本類型不受支持或者當前在瀏覽器中關(guān)閉了腳本匀谣,則在HTML <noscript> 元素中定義腳本未被執(zhí)行時的替代內(nèi)容照棋。換句話說,就是當瀏覽器不支持js腳本或者用戶主動關(guān)閉腳本武翎,那么就會展示noscript里的內(nèi)容烈炭,而critical則是利用這一點做了向后兼容
總結(jié)

利用critical可以大大提高頁面渲染速度,但是由于其使用puppeteer宝恶,所以下載安裝比較麻煩符隙,上面的webpack中使用設(shè)置env中puppeteer位置的方法解決了這一問題趴捅。

文中如若有不對的地方,還望之處霹疫,共同交流拱绑。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市丽蝎,隨后出現(xiàn)的幾起案子猎拨,更是在濱河造成了極大的恐慌,老刑警劉巖屠阻,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件红省,死亡現(xiàn)場離奇詭異,居然都是意外死亡国觉,警方通過查閱死者的電腦和手機吧恃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來麻诀,“玉大人痕寓,你說我怎么就攤上這事≌爰ⅲ” “怎么了厂抽?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長丁眼。 經(jīng)常有香客問我筷凤,道長,這世上最難降的妖魔是什么苞七? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任藐守,我火速辦了婚禮,結(jié)果婚禮上蹂风,老公的妹妹穿的比我還像新娘卢厂。我一直安慰自己,他們只是感情好惠啄,可當我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布慎恒。 她就那樣靜靜地躺著,像睡著了一般撵渡。 火紅的嫁衣襯著肌膚如雪融柬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天趋距,我揣著相機與錄音粒氧,去河邊找鬼。 笑死节腐,一個胖子當著我的面吹牛外盯,可吹牛的內(nèi)容都是我干的摘盆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼饱苟,長吁一口氣:“原來是場噩夢啊……” “哼孩擂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起掷空,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤肋殴,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后坦弟,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡官地,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年酿傍,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片驱入。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡赤炒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出亏较,到底是詐尸還是另有隱情莺褒,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布雪情,位于F島的核電站遵岩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏巡通。R本人自食惡果不足惜尘执,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望宴凉。 院中可真熱鬧誊锭,春花似錦、人聲如沸弥锄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽籽暇。三九已至温治,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間图仓,已是汗流浹背罐盔。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留救崔,地道東北人惶看。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓捏顺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親纬黎。 傳聞我的和親對象是個殘疾皇子幅骄,可洞房花燭夜當晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容