关键CSS和Webpack:自动最小化渲染阻止CSS

2023-05-16

“消除渲染阻止的JavaScript和CSS”。 这是我始终坚持使用的Google Page Speed Insights建议。Google建议您在页面加载准备就绪时将最初需要的CSS(内插)CSS内嵌并加载CSS的其余部分

当访问web页面时,谷歌希望它只加载对初始视图有用的内容,并使用空闲时间来加载其他内容。这样,用户可以尽早看到页面。

1.jpg

我们可以做很多事情来最小化JavaScript的委托阻塞,比如代码分割、树抖动、缓存等等。

那么CSS呢?为此,我们可以通过隔离用于上述内容的CSS(即关键的CSS)并首先加载它来最小化委托阻塞。然后我们可以加载非关键的CSS。

隔离关键的CSS是可以通过编程实现的,在本文中,我将向您展示如何将其委派给Webpack管道。

渲染阻止是什么意思?

如果资源是“渲染阻止”,则意味着浏览器在下载或处理该资源之前无法显示该页面。

通常情况下,我们会通过链接到文档头部的样式表来以一种阻塞的方式加载CSS,如下所示:

<head>
  <link rel="stylesheet" href="/style.css">
  ...
</head>
<body>
  <p>I can't be seen until style.css has been loaded!</p>
</body>

当web浏览器加载这个页面时,它将从头到尾地读取它。当浏览器到达链接标记时,它将立即开始下载样式表,并且在完成之前不会呈现页面。

对于大型站点,特别是具有Bootstrap这样的大框架的站点,样式表可能是几百kb,用户必须耐心等待,直到完全下载完毕。

那么,我们是否应该链接到主体中的样式表,在那里呈现不会被阻塞?你可以这么做,但问题是,阻止租客并不完全是坏事,我们实际上想利用它。如果页面渲染没有任何CSS加载,我们会得到丑陋的“flash无风格的内容”:

2.jpg我们想要的最佳点是在哪里渲染,用关键的css阻塞页面,这是设计主视图样式所必需的,但是所有非关键的css都是在初始渲染之后加载的。

关键的CSS

看看我用Bootstrap和Webpack构建的这个简单页面。这是它第一次渲染后的样子:

3.jpg该页面还有一个模式,可通过“立即注册”按钮打开。 打开后,它看起来像这样:

4.jpg对于页面的第一次呈现,我们需要nav bar、jumbotron、button和其他一些布局和字体的一般规则的css规则。但我们不需要模态的规则,因为它不会立即显示。考虑到这一点,我们可以将关键css与非关键css分离:

critical.css

.nav {
  ...
}

.jumbtron {
  ...
}

.btn {
  ...
}

non_critical.css

.modal {
  ...
}

如果你认同这个概念,你可能会对以下两个问题感兴趣:

  • 我们如何通过编程来区分关键的和非关键的CSS ?

  • 如何让页面在第一次渲染前加载关键的CSS,在第一次渲染后加载非关键的CSS ?

示例项目

我将简要地向您介绍这个项目的基本设置,以便在我们找到解决方案时能够很快地消化。

首先,我加载引导SASS到我的输入文件。

main.js

require("bootstrap-sass/assets/stylesheets/_bootstrap.scss");

我正在使用sass-loader处理此问题,并将其与Extract Text Plugin结合使用,以便将已编译的CSS放入其自己的文件中。

我还使用HTML Webpack插件在构建中创建HTML文件。 如您将很快看到的,该解决方案是必不可少的。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: ['css-loader', 'sass-loader']
        })
      },
      ...
    ]
  },
  ...
  plugins: [
    new ExtractTextPlugin({ filename: 'style.css' }),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.html',
      inject: true
    })
  ] 
};

运行构建后,HTML文件是这样的。注意CSS是在头部加载的,因此会阻塞渲染。

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>vuestrap-code-split</title>
    <link href="/style.css" rel="stylesheet">
</head>
<body>
  <!--App content goes here, omitted for brevity.-->
  <script type="text/javascript" src="/build_main.js"></script>
</body>
</html>

以编程方式识别关键css

手动识别关键CSS会很麻烦。 要以编程方式做到这一点,我们可以使用Addy Osmani恰当地命名为Critical的工具。 这是一个Node.js模块,它将读取HTML文档,并标识关键的CSS。 除此之外,它的作用还不止于此,我们很快就会看到。

Critical识别关键CSS的方法是使用PhantomJS加载页面,使用指定的屏幕维度,并提取呈现页面中使用的任何CSS规则。

以下是我们如何为这个项目设置:

const critical = require("critical");

critical.generate({
  
  /* The path of the Webpack bundle */
  base: path.join(path.resolve(__dirname), 'dist/'),
  src: 'index.html',
  dest: 'index.html',
  inline: true,
  extract: true,

  /* iPhone 6 dimensions, use whatever you like*/
  width: 375,
  height: 565,
  
  /* Ensure that bundled JS file is called */
  penthouse: {
    blockJSRequests: false,
  }
});

执行时,这将把Webpack包输出中的HTML文件更新为:

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>Bootstrap Critical</title>
  <style type="text/css">
    /* Critical CSS is inlined into the document head, abbreviated here. */
    body {
      font-family: Helvetica Neue,Helvetica,Arial,sans-serif;
      font-size: 14px;
      line-height: 1.42857;
      color: #333;
      background-color: #fff;
    }
    ...
  </style>
  <link href="/style.96106fab.css" rel="preload" as="style" onload="this.rel='stylesheet'">
  <noscript>
      <link href="/style.96106fab.css" rel="stylesheet">
  </noscript>
  <script>
    /*A script for loading the non-critical CSS goes here, omitted for brevity.*/
  </script>
</head>
<body>
  <!--App content goes here, omitted for brevity.-->
  <script type="text/javascript" src="/build_main.js"></script>
</body>
</html>

它还将输出一个新的css文件,例如style.96106fab.css(文件名会自动添加一个散列)。这个css文件与原始样式表相同,只是去掉了关键的css。

内联关键css

您将注意到关键的CSS已内联到文档的头部。这是最优的,因为页面不必从服务器加载它。

预加载非关键CSS

您还将注意到,非关键CSS加载了外观精美的链接。 preload值告诉浏览器开始获取非关键CSS供挂起使用。 但至关重要的是,预加载不是渲染阻止,因此无论预加载资源是否完成,浏览器都将继续绘制页面。

链接中的onload属性允许我们在非关键的CSS最终加载后运行脚本。关键模块自动将脚本内联到文档中,从而提供跨浏览器兼容的方式将非关键样式表加载到页面中。

<link href="/style.96106fab.css" rel="preload" as="style" onload="this.rel='stylesheet'">

将critical放入webpack管道

我制作了一个名为html关键webpack plugin的webpack插件,它仅仅是关键模块的包装器。它将在您的文件从HTML网页包插件发出后运行。

以下是如何将它包含在Webpack项目中:

const HtmlCriticalPlugin = require("html-critical-webpack-plugin");

module.export = {
  ...
  plugins: [
    new HtmlWebpackPlugin({ ... }),
    new ExtractTextPlugin({ ... }),
    new HtmlCriticalPlugin({
      base: path.join(path.resolve(__dirname), 'dist/'),
      src: 'index.html',
      dest: 'index.html',
      inline: true,
      minify: true,
      extract: true,
      width: 375,
      height: 565,
      penthouse: {
        blockJSRequests: false,
      }
    })
  ] 
};

注意:您可能只应该在生产构建中使用它,而不是在开发中,因为它会使您的构建非常慢!

性能结果

现在我已经隔离了关键的CSS,并在空闲时间加载了非关键的CSS,那么如何改进性能呢?

我使用Chrome的灯塔扩展来寻找答案。请记住,我们试图优化的度量标准是第一次有意义的绘制的时间,它基本上告诉我们用户看到某些东西需要多长时间。

在实施关键的CSS:

5.jpg关键的CSS实现后:

6.JPG如您所见,我的应用程序在整整一秒钟前就获得了一幅有意义的画作,并且在半秒钟前就实现了交互。

实际上,你可能不会在你的应用程序中得到如此显著的改进,因为我的css已经完全膨胀了(我包括了整个引导库),在这样一个简单的应用程序中,我没有很多关键的css规则。

英文原文地址:https://vuejsdevelopers.com/2017/07/24/critical-css-webpack/

 想要了解更多相关知识,可访问 前端学习网站!!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关键CSS和Webpack:自动最小化渲染阻止CSS 的相关文章

  • 如何垂直对齐div内的图像

    如何在包含的内容中对齐图像div Example 在我的示例中 我需要将 img in the div with class frame div class frame style height 25px img src http jsfi
  • 如何让CSS选择以字符串开头的ID(不是Javascript)?

    如果 HTML 中有这样的元素 id product42 id product43 如何匹配所有以 product 开头的 id 我已经看到了完全使用 javascript 执行此操作的答案 但是如何仅使用 CSS 执行此操作 id pro
  • 将图像编码为base64有什么效果?

    如果我将图像 jpg 或 png 转换为 base64 那么它会更大 还是具有相同的大小 会大多少呢 是否建议在我的网站上使用 Base64 编码的图像 大约会大 37 非常粗略地说 Base64 编码的二进制数据的最终大小等于原始数据大小
  • 从字体到跨度(大小和颜色)和背面的正则表达式(VB.NET)

    我正在寻找一个正则表达式 可以将我的字体标签 仅具有大小和颜色属性 转换为具有相关内联CSS的span标签 如果有帮助的话 这将在 VB NET 中完成 我还需要一个正则表达式来实现相反的效果 下面详细说明的是我正在寻找的转换示例 font
  • 编辑类名中带有空格的元素的 css 样式

    我正在创建一个 tumblr 我必须编写一个外部 CSS 文件 但我在编辑 post 元素的 css 样式时遇到问题 这是它的结构 li class post quote other code li 问题是类名中有空格 我如何创建一个 CS
  • TDD/测试 CSS 和 HTML? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 有没有办法测试 CSS 和 HTML 例如 有时某些通知会受到某些 CSS 更改的影响 我不想每次进行更改时都手动测试所有通知 Tha
  • 如何将大于整个页面 100% 的元素居中对齐?

    我有一个宽度为 100 的 div 并且隐藏了一个宽度为 3000px 的 div 我希望3000px的div左右均匀地被切断 我会使用背景位置 中心 然而 事情比这更复杂 3000px div 包含 30 100px div 我尝试过在
  • 如何强制折断不可折断的字符串?

    我有一个根据数据库中包含的数据生成的 HTML 页面 数据库有时包含浏览器无法分解的长字符串 因为这些字符串不包含可分解的字符 空格 点 逗号等 有没有办法使用 html css 甚至 javascript 来解决这个问题 看到这个link
  • 找不到“节点”的类型定义文件

    更新 Angular Webpack 和 TypeScript 后出现奇怪的错误 知道我可能会错过什么吗 当我使用 npm start 运行应用程序时 出现以下错误 at loader Cannot find type definition
  • 将输入中每个单词的第一个字符设为大写

    我想知道如何在输入区域自动生成单词的第一个字符 目前我的代码是 Name
  • Twitter bootstrap 3表单水平和单行多个输入列

    我需要将多列输入放在单行中 如下所示 我通过将多个输入分组为一个来做到这一点form group 但是这样我不能使用has error class div class form group div
  • 没有类的 CSS 选择器

    我正在使用选择器来选择不具有一个类的所有元素 list th not foo some rules 我怎样才能将其应用到多个班级 list th not foo list th not bar some rules 上面的 CSS 当然不会
  • 在 Bootstrap 中使用 CakePHP 时如何修改包装器 div 错误类

    我在用着Bootstrap 3 0RC1 with CakePHP 2 3 6 尝试利用那些漂亮的课程 例如has error and has warning for 验证状态 http getbootstrap com css forms
  • 动态表单标签宽度的 CSS

    我目前正在重构我们的表单控制器之一 以便我们可以将其用于面向公众的网站 目前它正在为表单生成表格布局 但我正在尝试使用 CSS 表单来完成它 我正在尝试重现看起来像这样的东西http www stylephreak com uploads
  • CSS:水平滚动时背景不存在

    好的 我的背景设置如下 HTML div div CONTENT HERE div div CSS container background url image gif content width 800px margin auto 因此
  • 使用 CSS 自定义字体?

    我见过一些在其网站上使用自定义字体的新网站 除了常规的 Arial Tahoma 等 他们支持大量的浏览器 如何做到这一点 同时 如果可能的话 还会阻止人们免费下载该字体 一般来说 您可以使用自定义字体 font face在你的 CSS 中
  • 调整文本区域大小

    我需要使用文本区域来显示一些文本 问题是 如果我放置 4 5 行文本 就会出现滚动条 如何使用 CSS HTML 使文本区域与其内容一样大 没有滚动条 文本区域不需要动态更改其大小 我仅使用它来显示文本 我也可以使用禁用的文本区域 我希望文
  • 如何将此 HTML 表格布局解决方案转换为浮动 div 解决方案?

    我经常需要列出各种尺寸的项目images在左边和text在右边 像这样 替代文本 http www deviantsart com upload 7s01l5 png http www deviantsart com upload 7s01
  • 显示覆盖以覆盖整个页面

    我有一个正在加载的网络应用程序iframe 我需要显示一个覆盖 div 来覆盖整个页面 问题是叠加层当前仅显示在iframe区域而不覆盖整个页面 我们的应用程序 子应用程序 是加载的一组应用程序的一部分iframe 你可以做这样的事情 di
  • 带显示块的SPAN

    和默认有什么区别 div 元素和默认值 span 元素与display block HTML 元素的有效性和语义存在差异 否则它们是相同的 div and span两者都被定义为通用容器 在 HTML 方面没有更深层次的含义 一个默认为块显

随机推荐

  • 深入解析Javascript闭包及实现方法

    什么是闭包和闭包的几种写法和用法 1 什么是闭包 闭包 xff0c 官方对闭包的解释是 xff1a 一个拥有许多变量和绑定了这些变量的环境的表达式 xff08 通常是一个函数 xff09 xff0c 因而这些变量也是该表达式的一部分 闭包的
  • 理解JavaScript中的语法和代码结构

    所有编程语言都必须遵守特定的规则才能运行 确定编程语言的正确结构的这组规则称为语法 许多编程语言主要由具有语法变化的类似概念组成 在本教程中 xff0c 我们将介绍JavaScript语法和代码结构的许多规则和约定 功能性和可读性 在开始使
  • 深入CSS,让网页开发少点“坑”

    通常我们在学习CSS的时候 xff0c 感觉语法很容易掌握 xff0c 实际应用中却碰到各式各样难以填补的 坑 xff0c 为避免大家受到同样的困惑与不解 xff0c 本文详细讲解了CSS中优先级和Stacking Context等高级特性
  • 如何巧用 canvas(画布)为图片加水印?

    在前端中 xff0c 如何巧用 canvas xff08 画布 xff09 为图片加水印 xff1f 下面本篇文章就来给大家介绍一下使用 canvas 给图片添加水印的方法 有一定的参考价值 xff0c 有需要的朋友可以参考一下 xff0c
  • EKF(扩展卡尔曼滤波)参数理解

    EKF VELNE NOISE xff1a 速度在坐标轴 NE 方向上的噪声 通常是在 0 上下波动 设置方法 xff1a 将飞机上电静置若干分钟 xff08 时间尽量长一点 xff09 记录飞 行日志 xff0c 由 EKF3 的 IVN
  • 详解HTML文档声明(DOCTYPE)

    HTML文档通常以类型声明开始 xff0c 该声明将帮助浏览器确定其尝试解析和显示的HTML文档类型 本文将详细介绍文档声明DOCTYPE 特点 文档声明必须是HTML文档的第一行 且顶格显示 xff0c 对大小写不敏感 因为任何放在DOC
  • CSS 不定宽高的垂直水平居中(9种方法)

    垂直居中 xff0c 在 CSS 中是一个老生常谈的问题 xff0c 面试的时候也会时常被提及 所以 xff0c 今天我们就来聊聊 9 种不同的居中方法 有常见的 flex transform absolute 等等 也有 CSS3 的网格
  • html5不常用标签应用场景

    作为一个前端开发 xff0c 在浏览别人家的页面时总是会习惯性的查看他们页面的源码 xff0c 发现大多数网站的页面 xff0c 包括我自己写的页面中用到的最多的布局元素无外乎就是div p span ul dl ol li dt dd s
  • HTML的16个全局属性介绍

    在HTML中 xff0c 属性能表达相当丰富的语义 xff0c 而且属性也会额外提供很多实用的功能 xff0c HTML共支持16个常见的全局属性 HTML原有属性 accesskey 作用 xff1a 浏览器用来创建激活或聚焦元素的快捷键
  • 聊聊JavaScript作用域

    几乎所有的语言都有作用域的概念 xff0c 简单的说 xff0c 作用域就是变量和函数的可访问范围 xff0c 即作用域控制在变量和函数的可见性和生命周期 变量作用域 是程序源代码中定义这个变量的区域 1 全局变量拥有全局作用域 xff0c
  • CSS布局方案大全【整理】

    我们在日常开发中经常遇到布局问题 xff0c 下面罗列几种常用的css布局方案话不多说 xff0c 上代码 xff01 居中布局 以下居中布局均以不定宽为前提 xff0c 定宽情况包含其中 1 水平居中 a inline block 43
  • 你必须知道的一些HTML优化技巧

    如何提升Web页面的性能 xff0c 很多开发人员从多个方面来下手如JavaScript 图像优化 服务器配置 xff0c 文件压缩或是调整CSS 很显然HTML 已经达到了一个瓶颈 xff0c 尽管它是开发Web 界面必备的核心语言 HT
  • 常见的CSS图形绘制合集

    展示40多个常见的纯CSS绘制图形 xff0c 效果实时 xff0c 含源代码 xff0c 想要什么效果直接复制粘贴就好了 就算项目用不到 xff0c 看看别人代码怎么写的也有助于提高CSS的基本功 以下这些造型简单的图形都是纯CSS外加一
  • 扩展Vue.js组件

    您的Vue应用程序中是否有共享类似选项的组件 xff0c 甚至模板标记 使用公共选项和标记创建基本组件 xff0c 然后扩展基本组件以创建子组件 xff0c 这是一个好主意 这样的体系结构将帮助您在代码中应用DRY原则 不要重复您自己 xf
  • Node.js日志记录指南

    当你开始用 JavaScript 进行开发时 xff0c 可能学到的第一件事就是如何用 console log 将内容记录到控制台 如果你去搜索如何调试 JavaScript xff0c 会发现数百篇博文和 StackOverflow 文章
  • 软件测试的测试方法及测试流程

    一 测试方法 xff1a 白盒测试 xff1a 把软件比作一个打开的盒子 xff0c 可以看到软件代码的实现 xff0c 针对代码的实现验证代码是否存在问题 单元测试阶段采用的测试方法 灰盒测试 xff1a 介于白盒和黑盒测试之间 灰盒测试
  • 18个用于创建漂亮图表的JavaScript库推荐

    几乎不可能想象没有图形和图表的任何仪表盘 它们快速有效地呈现复杂的统计数据 此外 xff0c 一个好的图表还可以增强网站的整体设计 在本文中 xff0c 我将向您展示一些用于图形和图表的最佳JavaScript库 这些库将帮助您为将来的项目
  • JavaScript基础--引用数据类型 (对象)

    本文主要讲述了JavaScript对象的属性和对象的引用 xff0c 以及对象的读取 赋值 删除和获取对象键名的操作 1 对象 对象就是一组 键值对 xff08 key value xff09 的集合 xff0c 是一种无序的复合数据集合
  • javascript面向对象设计

    javascript和java语言不一样 xff0c 它没有类这个说法 xff0c 更没有子类父类一说 xff0c 所以它所谓的继承机制 xff0c 也是和其他语言完全不同的 创建对象三种方式 1 最简单的方式 xff0c 创建一个obje
  • 关键CSS和Webpack:自动最小化渲染阻止CSS

    消除渲染阻止的JavaScript和CSS 这是我始终坚持使用的Google Page Speed Insights建议 Google建议您在页面加载准备就绪时将最初需要的CSS 内插 CSS内嵌并加载CSS的其余部分 当访问web页面时