webpack-优化阻塞的css

作者 : 开心源码 本文共3020个字,预计阅读时间需要8分钟 发布时间: 2022-05-13 共286人阅读
随着浏览器的日新月异,网页的性能和速度越来越好,并且对于客户体验来说也越来越重要。现在有很多优化页面的办法,比方:静态资源的合并和压缩,code splitting,DNS预读取等等。本文详情的是另一种优化方法:首屏阻塞css优化
原理:

首先我们理解一下页面的基本渲染流程(参考):

webkit渲染过程:

image.png

Gecko渲染过程:

image.png

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


怎样做呢:

目前我知道的比较实用的办法是webpack集成critical,critical是一个提取关键css,内联到html中,并且使用preload和noscript兼容加载非关键css的工具。
那么,我们开门见山,直接从webpack配置开始:

const HtmlWebpackPlugin = require('html-webpack-plugin'); // 创立html来服务你的资源const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 提取css到分离的文件,需要webpack4const 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',            inline: true,            minify: true,            extract: true,            width: 375,            height: 565,            // 确保调用打包后的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进行实战练习

可以看到,h2标签的css样式没有出现在内联style里,而是出现在main.[hash].css中,由于它不再所设置首屏范围内,这就是所谓的首屏css优化。

相关内容

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

  • rel="preload" as="style": 用于进行页面预加载,rel="preload"通知浏览器开始获取非关键CSS以供之后用。其关键在于,preload不阻塞渲染,无论资源能否加载完成,浏览器都会接着绘制页面。并且,搭配as使用,可以指定将要预加载内容的类型,可以让浏览器:
    1. 更准确地优化资源加载优先级。
    2. 匹配未来的加载需求,在适当的情况下,重复利用同一资源。
    3. 为资源应用正确的内容安全策略。
    4. 为资源设置正确的 Accept 请求头。
  • noscript:假如页面上的脚本类型不受支持或者者当前在浏览器中关闭了脚本,则在HTML <noscript> 元素中定义脚本未被执行时的替代内容。换句话说,就是当浏览器不支持js脚本或者者客户主动关闭脚本,那么就会展现noscript里的内容,而critical则是利用这一点做了向后兼容
总结

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

文中如若有不对的地方,还望之处,共同交流。

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » webpack-优化阻塞的css

发表回复