critical 是怎么做到提取关键CSS的?

https://github.com/addyosmani/critical 是怎么做到提取关键 CSS 资源的?个人理解首屏需要注入数据后才能提取到大部分首屏需要的css,critical 能做到吗?我还没有研究与尝试,只是简单看了一下文档,想了解工作原理。

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

  // Your base directory
  base: 'dist/',

  // HTML source
  html: '<html>...</html>',

  // HTML source file
  src: 'index.html',

  // Your CSS Files (optional)
  css: ['dist/styles/main.css'],

  // Viewport width
  width: 1300,

  // Viewport height
  height: 900,

  // Output results to file
  target: {
    css: 'critical.css',
    html: 'index-critical.html',
    uncritical: 'uncritical.css',
  },

  // Extract inlined styles from referenced stylesheets
  extract: true,

  // ignore CSS rules
  ignore: {
    atrule: ['@font-face'],
    rule: [/some-regexp/],
    decl: (node, value) => /big-image\.png/.test(value),
  },
});
阅读 2.9k
1 个回答

需要你的构建产物里本身已经在 HTML 里注入了 CSS,不能是运行时再通过 JS 动态加载 CSS 了。

原理是内置了个无头浏览器。你贴的这个依赖于 penthouse,而 penthouse 又依赖于 puppeteer。puppeteer 是啥大家应该耳熟能详了。等到浏览器跑起来了以后,再通过 css-tree 这个库将读到的样式表内容转为 AST 语法树,再遍历 DOM 里每个元素看匹配结果。剩下的就是把匹配到的样式变为内联的了。

推荐问题