Critical
Extract & Inline Critical-path CSS in HTML pages
README
critical
Install
- ```sh
- npm i -D critical
- ```
Build plugins
Demo projects
Usage
- ``` js
- import {generate} from 'critical';
- ```
- ``` js
- 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),
- },
- });
- ```
Generate and inline critical-path CSS
- ``` js
- generate({
- inline: true,
- base: 'test/',
- src: 'index.html',
- target: 'index-critical.html',
- width: 1300,
- height: 900,
- });
- ```
Generate critical-path CSS
- ``` js
- generate({
- base: 'test/',
- src: 'index.html',
- target: 'styles/main.css',
- width: 1300,
- height: 900,
- });
- ```
- ``` js
- generate({
- base: 'test/',
- src: 'index.html',
- target: 'styles/styles.min.css',
- width: 1300,
- height: 900,
- });
- ```
- ``` js
- generate({
- inline: true,
- base: 'test/',
- src: 'index.html',
- target: {
- html: 'index-critical.html',
- css: 'critical.css',
- },
- width: 1300,
- height: 900,
- });
- ```
- ``` js
- generate({
- base: 'test/',
- src: 'index.html',
- width: 1300,
- height: 900,
- inline: true
- }, (err, {css, html, uncritical}) => {
- // You now have critical-path CSS as well as the modified HTML.
- // Works with and without target specified.
- ...
- });
- ```
- ``` js
- generate({
- base: 'test/',
- src: 'index.html',
- width: 1300,
- height: 900
- }).then((({css, html, uncritical})) => {
- // You now have critical-path CSS as well as the modified HTML.
- // Works with and without target specified.
- ...
- }).error(err => {
- ...
- });
- ```
- ``` js
- const {css, html, uncritical} = await generate({
- base: 'test/',
- src: 'index.html',
- width: 1300,
- height: 900,
- });
- ```
Generate critical-path CSS with multiple resolutions
- ``` js
- generate({
- base: 'test/',
- src: 'index.html',
- target: {
- css: 'styles/main.css',
- },
- dimensions: [
- {
- height: 200,
- width: 500,
- },
- {
- height: 900,
- width: 1200,
- },
- ],
- });
- ```
Generate critical-path CSS and ignore specific selectors
- ``` js
- generate({
- base: 'test/',
- src: 'index.html',
- target: {
- css: 'styles/main.css',
- },
- ignore: {
- atrule: ['@font-face'],
- decl: (node, value) => /url\(/.test(value),
- },
- });
- ```
Generate critical-path CSS and specify asset rebase behaviour
- ``` js
- generate({
- base: 'test/',
- src: 'index.html',
- target: {
- css: 'styles/main.css',
- },
- rebase: {
- from: '/styles/main.css',
- to: '/folder/subfolder/index.html',
- },
- });
- ```
- ``` js
- generate({
- base: 'test/',
- src: 'index.html',
- target: {
- css: 'styles/main.css',
- },
- rebase: asset => `https://my-cdn.com${asset.absolutePath}`,
- });
- ```
Options
Name | Type | Default | Description |
---|---|---|---|
---------------- | ---------------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
inline | `boolean`\|`object` | `false` | Inline |
base | `string` | `path.dirname(src)` | Base |
html | `string` | | | |
css | `array` | `[]` | An |
src | `string` | | | |
target | `string` | | | |
width | `integer` | `1300` | Width |
height | `integer` | `900` | Height |
dimensions | `array` | `[]` | An |
extract | `boolean` | `false` | Remove |
inlineImages | `boolean` | `false` | Inline |
assetPaths | `array` | `[]` | List |
maxImageFileSize | `integer` | `10240` | Sets |
rebase | `object` | `undefined` | Critical |
ignore | `array` | `object` | `undefined` |
userAgent | `string` | `''` | User |
penthouse | `object` | `{}` | Configuration |
request | `object` | `{}` | Configuration |
user | `string` | `undefined` | RFC2617 |
pass | `string` | `undefined` | RFC2617 |
strict | `boolean` | `false` | Throw |
CLI
- ```sh
- npm install -g critical
- ```
- ```sh
- cat test/fixture/index.html | critical --base test/fixture --inline > index.critical.html
- ```
- ```bat
- type test\fixture\index.html | critical --base test/fixture --inline > index.critical.html
- ```
- ```sh
- critical test/fixture/index.html --base test/fixture > critical.css
- ```
Gulp
- ``` js
- import gulp from 'gulp';
- import log from 'fancy-log';
- import {stream as critical} from 'critical';
- // Generate & Inline Critical-path CSS
- gulp.task('critical', () => {
- return gulp
- .src('dist/*.html')
- .pipe(
- critical({
- base: 'dist/',
- inline: true,
- css: ['dist/styles/components.css', 'dist/styles/main.css'],
- })
- )
- .on('error', err => {
- log.error(err.message);
- })
- .pipe(gulp.dest('dist'));
- });
- ```
Why?
Why is critical-path CSS important?
CSS is required to construct the render tree for your pages and JavaScript
will often block on CSS during initial construction of the page.
You should ensure that any non-essential CSS is marked as non-critical
(e.g. print and other media queries), and that the amount of critical CSS
and the time to deliver it is as small as possible.
Why should critical-path CSS be inlined?
For best performance, you may want to consider inlining the critical CSS
directly into the HTML document. This eliminates additional roundtrips
in the critical path and if done correctly can be used to deliver a
“one roundtrip” critical path length where only the HTML is a blocking resource.