今天看啥  ›  专栏  ›  俄小发

详解Vue项目如何提取Critical Css

俄小发  · 掘金  ·  · 2021-04-02 16:31
阅读 13

详解Vue项目如何提取Critical Css

什么是Critical Css

首屏关键css

网页渲染时,浏览器解析只有在完成 <head> 部分 CSS 样式的加载、解析之后才会渲染页面。这种渲染方式意味着,如果 CSS 文件很大,那么用户就必须等待很长的时间才能看到渲染结果。针对这一问题,提出一种非常规的解决方案,提高页面的渲染速度,这一方案常被称为 critical rendering path(关键渲染路径)。我们要做的优化就是找出渲染首屏的最小 CSS 集合(Critical CSS),并把它们写到 <head> 部分,从而让浏览器接收到 HTML 文件后就尽快渲染出页面。对于剩余部分的 CSS,我们可以使用异步的方式进行加载。

总结:Critical Css就是渲染首屏的最小CSS集合。

通过criticalcss网站获取页面critical css【收费】

如何提取Critical css

vue如何提取css

vue-cli4为例

css.extract

介绍

  • Type: boolean | Object
  • Default: 生产环境下是 true,开发环境下是 false

是否将组件中的 CSS 提取至一个独立的 CSS 文件中 (而不是动态注入到 JavaScript 中的 inline 代码)。

同样当构建 Web Components 组件时它总是会被禁用 (样式是 inline 的并注入到了 shadowRoot 中)。

当作为一个库构建时,你也可以将其设置为 false 免得用户自己导入 CSS。

提取 CSS 在开发环境模式下是默认不开启的,因为它和 CSS 热重载不兼容。然而,你仍然可以将这个值显性地设置为 true 在所有情况下都强制提取。

  • 开发环境

extractfalse,样式内嵌到 head 中。 开发环境.png

  • 生产环境

extracttrue,样式分离,外链到 head 中。

形成两个css文件:

app.[contetHash].css:vue组件抽离出来的css

chunk-vendors.[contentHash].css:第三方库依赖的css

生产环境.png

内部插件

不足

要么样式全部内嵌在head中导致html文件过大,要么外链,如果出现网络问题,页面白屏时间过长。

针对这一不足,我们看一下在vue项目中如何提取首屏渲染csscritical css

vue如何提取critical css

使用webpack插件critical-css-webpack-plugin

critical-css-webpack-plugin

项目配置

vue-cli4.x为例

Install
npm install critical-css-webpack-plugin -D
复制代码
vue.config.js
const criticalCssWebpackPlugin = require('critical-css-webpack-plugin')

/ critical css Options
const criticalCssOptions = {
    // type: boolean/object,是否inline生成的critical-path css。
    // true:生成html,false:生成css,object:向`inline-critical`传递配置对象
    inline: true,
    // type: string,读取和写入源的目录
    base: resolve('dist'),
    // type: string,要操作的html源代码,此选项优先于src选项
    // html: '',
    // type: array,css路径的数组
    // css: [],
    // type: string,要操作的html源代码的位置
    src: 'index.html',
    // type: string,保存操作输出的位置,如果要同时存储`html`和`css`,使用`html`和`css`的对象
    target: 'index.html',
    // type: integer,1300,目标视口的宽度
    width: 1300,
    // type: integer,900,目标视口的高度
    height: 900,
    // type: array,包含宽度和高度的数组,如果设置,优先于width和height选项
    dimensions: [],
    // type: boolean,是否压缩生成的critical-path css
    minify: true,
    // type: boolean,小心使用,从html中删除inline样式,它会基于提取的内容生成新的引用,因此可以安全地在多个html文件引用同一样式文件。删除每页的关键css会为每个页面生成唯一一个异步加载css。意味着你不能跨多页面缓存
    extract: false,
    // type: boolean,inline图片
    inlineImages: true,
    // type: array,内联程序开始查询assets时的目录/url列表
    assetPaths: [],
    // 设置base64内联图片的最大大小(以字节为单位)
    maxImageFileSize: 10240000,
    // type: object/function,critical尝试相对文档的assets path
    rebase: undefined,
    // type: array
    ignore: [],
    // type: string,获取远程src时的用户代理
    // userAgent: '',
    // type: object,penthouse的配置选项
    penthouse: {
        // propertiesToRemove: ['background'],
        forceInclude: ['.card', '.card__list', '.card__main', '.card__img', '.card__article'],
        forceExclude: []
    },
    // type: object,got的配置选项
    request: {},
    // type: string,RFC2617授权:user
    user: undefined,
    // type: string,RFC2617授权:pass
    pass: undefined,
    // type: boolean,如果找不到css,则抛出错误
    strict: false
};

module.exports = {
    chainWebpack: config => {
        config.plugin('critical')
                .use(criticalCssWebpackPlugin,
                    [
                        criticalCssOptions
                    ]
                ).tap(error => {
                    console.log(error, 'critical css generate error');
                    return error
                })
    }
}
复制代码

配置完毕后,执行npm run build构建,查看dist/index.html,可以看到提取的critical css插入到head中,剩余css仍以外链形式引入。

这样index.html文件也不会很大,也可以保证在网络不稳定时,显示简单页面样式。

image.png

critical-css-webpack-plugin插件的核心是criticalcritical核心使用penthouse,接下来再详解一下criticalpenthouse

critical插件

critical插件介绍,使用到核心组件库penthouse

html中提取critical css,并将critical-path内联到html中

Install
npm i -D critical
复制代码
Usage

配置文件critical.js

const critical = require('critical');
critical.generate({
  // Inline the generated critical-path CSS
  // - true generates HTML
  // - false generates CSS
  inline: true,
  ...
});
复制代码

node环境下执行配置文件critical.js即可

node critical.js
复制代码
Critical Options

摘自www.npmjs.com/package/cri…

NameTypeDefaultDescription
inlineboolean/objectfalseInline critical-path CSS using filamentgroup's loadCSS. Pass an object to configure inline-critical
basestringpath.dirname(src) or process.cwd()Base directory in which the source and destination are to be written
htmlstringHTML source to be operated against. This option takes precedence over the src option.
cssarray[]An array of paths to css files, file globs or Vinyl file objects.
srcstringLocation of the HTML source to be operated against
targetstring or objectLocation of where to save the output of an operation. Use an object with 'html' and 'css' props if you want to store both
widthinteger1300Width of the target viewport
heightinteger900Height of the target viewport
dimensionsarray[]An array of objects containing height and width. Takes precedence over width and height if set
minifybooleantrueEnable minification of generated critical-path CSS
extractbooleanfalseRemove the inlined styles from any stylesheets referenced in the HTML. It generates new references based on extracted content so it's safe to use for multiple HTML files referencing the same stylesheet. Use with caution. Removing the critical CSS per page results in a unique async loaded CSS file for every page. Meaning you can't rely on cache across multiple pages
inlineImagesbooleanfalseInline images
assetPathsarray[]List of directories/urls where the inliner should start looking for assets
maxImageFileSizeinteger10240Sets a max file size (in bytes) for base64 inlined images
rebaseobject or functionundefinedCritical tries it's best to rebase the asset paths relative to the document. If this doesn't work as expected you can always use this option to control the rebase paths. See postcss-url for details. (github.com/pocketjoso/….
ignorearrayobjectundefined
userAgentstring''User agent to use when fetching a remote src
penthouseobject{}Configuration options for penthouse.
requestobject{}Configuration options for got.
userstringundefinedRFC2617 basic authorization: user
passstringundefinedRFC2617 basic authorization: pass
strictbooleanfalseThrow an error if no css is found
Global Install And Cli
npm install -g critical
复制代码
critical test/fixture/index.html --base test/fixture > critical.css
复制代码

penthouse

penthouse介绍

关键路径css生成器

Install
npm i -D penthouse
复制代码
Usage
penthouse({
  url: 'http://google.com',
  cssString: 'body { color: red }'
  ...
})
.then(criticalCss => {
  // use the critical css
  fs.writeFileSync('outfile.css', criticalCss);
})
复制代码
Options

对应critical插件中的penthouseoptions

NameTypeDefaultDescription
urlstringAccessible url. Use file:/// protocol for local html files.
cssStringstringOriginal css to extract critical css from
cssstringPath to original css file on disk (if using instead of cssString)
widthinteger1300Width for critical viewport
heightinteger900Height for critical viewport
screenshotsobjectConfiguration for screenshots (not used by default). See Screenshot example
keepLargerMediaQueriesbooleanfalseKeep media queries even for width/height values larger than critical viewport.
forceIncludearray[]Array of css selectors to keep in critical css, even if not appearing in critical viewport. Strings or regex (f.e. ['.keepMeEvenIfNotSeenInDom', /^.button/])
forceExcludearray[]Array of css selectors to remove in critical css, even if appearing in critical viewport. Strings or regex (f.e. ['.doNotKeepMeEvenIfNotSeenInDom', /^.button/])
propertiesToRemovearray['(.)transition(.)', 'cursor', 'pointer-events', '(-webkit-)?tap-highlight-color', '(.*)user-select'] ] Css properties to filter out from critical css
timeoutinteger30000Ms; abort critical CSS generation after this time
puppeteerobjectSettings for puppeteer. See Custom puppeteer browser example
pageLoadSkipTimeoutinteger0Ms; stop waiting for page load after this time (for sites when page load event is unreliable)
renderWaitTimeinteger100ms; wait time after page load before critical css extraction starts (also before "before" screenshot is taken, if used)
blockJSRequestsbooleantrueset to false to load JS (not recommended)
maxEmbeddedBase64Lengthinteger1000characters; strip out inline base64 encoded resources larger than this
maxElementsToCheckPerSelectorintegerundefinedCan be specified to limit nr of elements to inspect per css selector, reducing execution time.
userAgentstring'Penthouse Critical Path CSS Generator'specify which user agent string when loading the page
customPageHeadersobjectet extra http headers to be sent with the request for the url.
cookiesarray[]For formatting of each cookie, see Puppeteer setCookie docs
strictbooleanfalseMake Penthouse throw on errors parsing the original CSS. Legacy option, not recommended.
allowedResponseCodenumber|regex|functionLet Penthouse stop if the server response code is not matching this value. number and regex types are tested against the response.status(). A function is also allowed and gets Response as argument. The function should return a boolean.

参考文档




原文地址:访问原文地址
快照地址: 访问文章快照