随着浏览器的日新月异,网页的性能和速度越来越好,并且对于用户体验来说也越来越重要。
现在有很多优化页面的办法,比如:静态资源的合并和压缩,code splitting,DNS预读取等等。
本文介绍的是另一种优化方法:首屏阻塞css优化
原理:

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

webkit渲染过程:



Gecko渲染过程:



那么,为什么要做这种优化呢?上面的流程图就是原因:首先解析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到分离的文件,需要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',
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位置的方法解决了这一问题。

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

webpack-优化阻塞的css的更多相关文章

  1. webpack - 优化阻塞渲染的css

    随着浏览器的日新月异,网页的性能和速度越来越好,并且对于用户体验来说也越来越重要. 现在有很多优化页面的办法,比如:静态资源的合并和压缩,code splitting,DNS预读取等等. 本文介绍的是 ...

  2. 翻译 | 关键CSS和Webpack: 减少阻塞渲染的CSS的自动化解决方案

    原文地址: Critical CSS and Webpack: Automatically Minimize Render-Blocking CSS 原文作者: Anthony Gore 译者: 蜗牛 ...

  3. 关键CSS和Webpack: 减少阻塞渲染的CSS的自动化解决方案

    原文地址: Critical CSS and Webpack: Automatically Minimize Render-Blocking CSS 原文作者: Anthony Gore 译者: 蜗牛 ...

  4. Webpack学习笔记九 webpack优化总结

    webpack 优化笔记 webpack4 自带的优化包括 swingTree(摇摆树)和作用域提升 swingTree 比如入口文件 index.js引入通用方法 util, 里面有 10个方法, ...

  5. webpack快速入门——实战技巧:webpack优化黑技能

    1.抽离jquery,vue(多个第三方类库抽离) 修改入口文件(webpack.config.js中) entry: { entry: './src/entry.js', jquery:'jquer ...

  6. 浅谈webpack优化

    webpack优化方案 1. 优化开发体验 1-1. 加快构建速度 ① 缩小文件搜索范围 由于 Loader 对文件的转换操作很耗时,需要让尽可能少的文件被 Loader 处理,用include和ex ...

  7. 常用的webpack优化方法

    1. 前言 关于webpack,相信现在的前端开发人员一定不会陌生,因为它已经成为前端开发人员必不可少的一项技能,它的官方介绍如下: webpack 是一个模块打包器.webpack的主要目标是将 J ...

  8. 记一次真实的webpack优化经历

    前言 公司目前现有的一款产品是使用vue v2.0框架实现的,配套的打包工具为webpack v3.0.整个项目大概有80多个vue文件,也算不上什么大型项目. 只不过每次头疼的就是打包所耗费的时间平 ...

  9. webpack中加载CSS

    webpack强大之处在于可以将CSS当做一个资源模块进行管理和加载 基本使用: 安装webpack的加载插件style-loader和css-loader: npm install style-lo ...

  10. 走近webpack(4)--css相关拓展

    我们前面已经学了很多webpack基本的处理情况,一句话总结就是,一个优秀的webpack项目,主要的核心用法就是整合loader和plugin去处理你想要的任何需求. 下面,咱们一起来学学如何用we ...

随机推荐

  1. C/c.pp:贪心,二分答案

    说是贪心有点牵强. 其次,答案满足单调性,如果在k次操作能完成那么在k+1次操作内也能完成. 因为大不了你就把多的一次对方操作再进行一次就好了. 怎么操作呢? 我们从头扫这个序列,遇到每一个不匹配位置 ...

  2. P4544 [USACO10NOV]购买饲料Buying Feed

    额,直接思路就dp吧.(我还想了想最短路之类的233但事实证明不行2333.....) 直入主题: 化简题意:在x轴上有n个点,坐标为xi.从原点出发,目标点为e,在途中需要收集K重量的物品,在每个点 ...

  3. starUML 3.0.2文件 百度云

    文件百度云---链接:https://pan.baidu.com/s/1BVX9Ze40bkgd3k_4WFb99A 提取码:t7kj 使用方法:将starUML安装目录(一般为 C:\Program ...

  4. 将 /u 转变为 utf-8 编码

    将 /u 转变为 utf-8 编码 PHP实例: $result = {"errno":-1,"message":"\u8bbf\u95ee\u5fa ...

  5. Fedora27(CentOS7)快捷键

    设置快捷键参考文档https://jingyan.baidu.com/article/f7ff0bfc1e2a322e26bb13d5.html Termial: 启动新的Terminal  需要自己 ...

  6. 使用ASP.NET Core 3.x 构建 RESTful API - 3.2 路由和HTTP方法

    ASP.NET Core 3.x 的路由 路由机制会把一个请求的URI映射到一个Controller上面的Action,所以当你发送一个HTTP请求的时候,MVC框架会解析这个请求的URI,并尝试着把 ...

  7. HTML建立超链接

      链接是HTML文档的最基本特征之一.超文本链接英文名为hyperlink,它能够让浏览器在各个独立的页面之间方便地跳转.超链接有外部链接.电子邮件链接.锚点链接等. a标签   网页中<a& ...

  8. 深入理解跳表在Redis中的应用

    本文首发于:深入理解跳表在Redis中的应用微信公众号:后端技术指南针持续输出干货 欢迎关注 前面写了一篇关于跳表基本原理和特性的文章,本次继续介绍跳表的概率平衡和工程实现, 跳表在Redis.Lev ...

  9. PostGIS mysql_fdw使用(Linux)

    ##前文讲了mysql_fdw的安装,此文主要讲mysql_fdw的配置以及使用 ##附上前文链接:https://www.cnblogs.com/giser-s/p/11208803.html 背景 ...

  10. Ubuntu--pip3 -V 问题

    问题原因:可能是因为重新下载或更新python版本的时候,将系统的‘软连接’破坏掉了 解决办法: 1.重新创建--软连接: 进入bin目录:cd /usr/bin 删除pip3连接:rm pip3 重 ...