【Webpack】867- Webpack 优化阻塞的 CSS

共 3623字,需浏览 8分钟

 ·

2021-02-12 13:16

http://interview.poetries.top/


随着浏览器的日新月异,网页的性能和速度越来越好,并且对于用户体验来说也越来越重要。

现在有很多优化页面的办法,比如:静态资源的合并和压缩code splittingDNS预读取等等

本文介绍的是另一种优化方法:首屏阻塞css优化

原理:

首先我们了解一下页面的基本渲染流程

webkit渲染过程:

Gecko渲染过程:

那么,为什么要做这种优化呢?上面的流程图就是原因:首先解析html生成dom树,同时解析css生成css树,之后结合两者生成渲染树,然后渲染到屏幕上。不但如此,如果css后面有其他javascript,并且css加载时间过长,也会阻塞后面的js执行,因为js可能会操作dom节点或者css样式,所以需要等待render树完成。那么,如果我们能优化css,那么就能大大减少页面渲染出来的时间,从而提升pv,增加黏性

怎么做呢:

目前我知道的比较实用的办法是webpack集成criticalcritical是一个提取关键css,内联到html中,并且使用preloadnoscript兼容加载非关键css的工具。

那么,我们开门见山,直接从webpack配置开始:

const HtmlWebpackPlugin = require('html-webpack-plugin'); // 创建html来服务你的资源
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 提取css到分离的文件,需要webpack4
const HtmlCriticalWebpackPlugin = require('html-critical-webpack-plugin'); // 集成critical的html-webpack-plugin版本
const path = require('path');

// 用于设置Chromium,因为Chromium使用npm或者yarn经常有问题
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',
            inlinetrue,
            minifytrue,
            extracttrue,
            width375,
            height565,
            // 确保调用打包后的JS文件
            penthouse: {
                blockJSRequestsfalse
            }
        })
    ]
};

然后是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 {
    width200px;
    height100vh;
    background-color: red;
}
h2 {
    color: blue;
}
.mask {
    width500px;
    height500px;
    display: none;
    position: absolute;
    top0;
    left0;
    bottom0;
    right0;
    margin: auto;
 background-color: yellowgreen;
}

运行webpack后,查看打包后的html文件:

// 省略...
<style>
    .div {
        width200px;
        height100vh;
        background-color: red;
    }
    .mask {
        width500px;
        height500px;
        display: none;
        position: absolute;
        top0;
        left0;
        bottom0;
        right0;
        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标签的css样式没有出现在内联style里,而是出现在main.[hash].css中,因为它不再所设置首屏范围内,这就是所谓的首屏css优化

相关内容

在上面打包后的html文件里,我们看到了有一个link内有rel="preload" as="style"字段,紧接着下面就有一个noscript标签,这两个是做什么的呢?

  • rel="preload" as="style"``:用于进行页面预加载,rel="preload"通知浏览器开始获取非关键CSS以供之后用。其关键在于,preload`不阻塞渲染,无论资源是否加载完成,浏览器都会接着绘制页面。并且,搭配as使用,可以指定将要预加载内容的类型,可以让浏览器:
    • 更精确地优化资源加载优先级。
    • 匹配未来的加载需求,在适当的情况下,重复利用同一资源。
    • 为资源应用正确的内容安全策略。
    • 为资源设置正确的 Accept 请求头。
  • noscript:如果页面上的脚本类型不受支持或者当前在浏览器中关闭了脚本,则在HTML

利用critical可以大大提高页面渲染速度,但是由于其使用puppeteer,所以下载安装比较麻烦,上面的webpack中使用设置envpuppeteer位置的方法解决了这一问题。

end


1. JavaScript 重温系列(22篇全)
2. ECMAScript 重温系列(10篇全)
3. JavaScript设计模式 重温系列(9篇全)
4. 正则 / 框架 / 算法等 重温系列(16篇全)
5. Webpack4 入门(上)|| Webpack4 入门(下)
6. MobX 入门(上) ||  MobX 入门(下)
7. 100+篇原创系列汇总

回复“加群”与大佬们一起交流学习~

点击“阅读原文”查看 100+ 篇原创文章

浏览 1
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报