随着浏览器的日新月异,网页的性能和速度越来越好,并且对于用户体验来说也越来越重要。
现在有很多优化页面的办法,比如:静态资源的合并和压缩,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: ,
height: ,
// 确保调用打包后的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: ;
left: ;
bottom: ;
right: ;
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: ;
left: ;
bottom: ;
right: ;
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位置的方法解决了这一问题。

原文链接: https://zhuanlan.zhihu.com/p/93876841

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

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

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

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

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

  3. 优化关键渲染路径CRP

    什么是关键渲染路径? 从收到 HTML.CSS 和 JavaScript 字节到对其进行必需的处理,从而将它们转变成渲染的像素这一过程中有一些中间步骤 浏览器渲染页面前需要先构建 DOM 和 CSSO ...

  4. CSS阻塞渲染、怎么防止css阻塞

    浏览器渲染流程: 1.浏览器开始解析目标HTML文件,执行流的顺序为自上而下. 2.HTML解析器将HTML结构转换为基础的DOM(文档对象模型),构建DOM树完成后,触发DomContendLoad ...

  5. 性能优化之html、css、js三者的加载顺序

    前言 我们知道一个页面通常由,html,css,js三部分组成,一般我们会把css文件放在head头部加载,而js文件则放在页面的最底部加载,想要知道为什么大家都会不约而同的按照这个标准进行构建页面, ...

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

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

  7. web性能优化-浏览器渲染原理

    在web性能优化-浏览器工作原理中讲到,浏览器渲染是在renderer process中完成的. 那我们来看下renderer process究竟干了什么? Renderer Process包含的线程 ...

  8. Web前端性能优化详解之CSS与JS加载

    浏览器加载页面和渲染过程 加载过程 浏览器根据DNS 服务器得到域名的IP地坛 向这个 IP 的机器发送 HTTP请求 服务器收到,处理并返回 HTTP请求 浏览器得到返回内容 渲染过程 根据 HTM ...

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

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

随机推荐

  1. 数据库及MySQL基础(1)

    1.数据库概述 关系型数据库:面对关系,Java面向对象. ·常见数据库 Oracle(神喻):甲骨文 DB2:IBM SQL Server:微软 Sybase:赛尔斯 MySQL:甲骨文,最早是开源 ...

  2. SQL Server注入

    1.利用错误消息提取信息 1.1 枚举当前表与列 --' 抛出错误:选择列表中的列 'users.id' 无效,因为该列没有包含在聚合函数或 GROUP BY 子句中. 发现表名为 'users',存 ...

  3. 认识:before和:after伪类

    有时候,我们需要大量的重复代码去实现一个非常简单的功能,这不仅浪费时间,而且效率低下,例如: <div class="aa">你好</div><div ...

  4. 1 使用webpack搭建vue开发环境

    1 先去node.js官网下载nodejs并且安装 安装成功之后在命令行输入node -v 回车,npm -v回车如果显示对应的版本号,说明node安装成功,自带的npm也安装成功 2 在d盘下创建一 ...

  5. JS密码强度检测

    //校验密码强度---沒有匹配到以下級別就提示 function checkPassWord(value){ // 0: 表示第一个级别 1:表示第二个级别 2:表示第三个级别 // 3: 表示第四个 ...

  6. 【Redis】事务 (超详细)

    一.概述 二.相关命令列表 2.1 MULTI 2.2 EXEC 2.3 DISCARD 2.4 WATCH key [key ...] 2.5 UNWATCH 三.命令示例 3.1 事务被正常执行 ...

  7. openpyxl 设置单元格颜色

    在处理excel数据格式的时候,需要对特定单元格进行颜色标注,方便相关人员查看 醒目 # -*- coding: utf-8 -*- from openpyxl import load_workboo ...

  8. python-----opencv截取按帧截取视频

    最近有需求把一个视频从指定帧截取一部分,demo代码如下: import cv2 video_path = r'F:\temp\temp_0806\1\video\test.dat' videoCap ...

  9. Java数组直接选择排序、sort()排序

    /** * 1.数组sort()排序 * 2.直接选择排序(两重for循环排序) */ import java.lang.*; import java.lang.reflect.Array; impo ...

  10. SP703 SERVICE - Mobile Service[DP]

    题意翻译 Description 一个公司有三个移动服务员.如果某个地方有一个请求,某个员工必须赶到那个地方去(那个地方没有其他员工),某一时刻只有一个员工能移动.只有被请求后,他才能移动,不允许在同 ...