UNPKG

12.8 kBMarkdownView Raw
1# critical [![NPM version][npm-image]][npm-url] [![Build Status][ci-image]][ci-url] [![dependencies Status][depstat-image]][depstat-url] [![devDependencies Status][devdepstat-image]][devdepstat-url]
2
3Critical extracts & inlines critical-path (above-the-fold) CSS from HTML
4
5<img src="https://raw.githubusercontent.com/addyosmani/critical/1.x/preview.png" alt="Preview" width="378">
6
7
8## Install
9
10```
11$ npm install --save critical
12```
13
14## Build plugins
15
16- [grunt-critical](https://github.com/bezoerb/grunt-critical)
17- Gulp users should use Critical directly
18- For Webpack use [html-critical-webpack-plugin](https://github.com/anthonygore/html-critical-webpack-plugin)
19
20## Demo projects
21
22- [Optimize a basic page with Gulp](https://github.com/addyosmani/critical-path-css-demo) with a [tutorial](https://github.com/addyosmani/critical-path-css-demo#tutorial)
23- [Optimize an Angular boilerplate with Gulp](https://github.com/addyosmani/critical-path-angular-demo)
24- [Optimize a Weather app with Gulp](https://github.com/addyosmani/critical-css-weather-app)
25
26
27## Usage
28
29Include:
30
31```js
32var critical = require('critical');
33```
34
35Full blown example with available options:
36
37```js
38critical.generate({
39 // Inline the generated critical-path CSS
40 // - true generates HTML
41 // - false generates CSS
42 inline: true,
43
44 // Your base directory
45 base: 'dist/',
46
47 // HTML source
48 html: '<html>...</html>',
49
50 // HTML source file
51 src: 'index.html',
52
53 // Your CSS Files (optional)
54 css: ['dist/styles/main.css'],
55
56 // Viewport width
57 width: 1300,
58
59 // Viewport height
60 height: 900,
61
62 // Target for final HTML output.
63 // use some CSS file when the inline option is not set
64 dest: 'index-critical.html',
65
66 // Minify critical-path CSS when inlining
67 minify: true,
68
69 // Extract inlined styles from referenced stylesheets
70 extract: true,
71
72 // Complete Timeout for Operation
73 timeout: 30000,
74
75 // Prefix for asset directory
76 pathPrefix: '/MySubfolderDocrot',
77
78 // ignore CSS rules
79 ignore: ['font-face',/some-regexp/],
80
81 // overwrite default options
82 ignoreOptions: {}
83});
84```
85
86### Generate and inline critical-path CSS
87
88Basic usage:
89
90```js
91critical.generate({
92 inline: true,
93 base: 'test/',
94 src: 'index.html',
95 dest: 'index-critical.html',
96 width: 1300,
97 height: 900
98});
99```
100
101### Generate critical-path CSS
102
103Basic usage:
104
105```js
106critical.generate({
107 base: 'test/',
108 src: 'index.html',
109 dest: 'styles/main.css',
110 width: 1300,
111 height: 900
112});
113```
114
115Generate and minify critical-path CSS:
116
117```js
118critical.generate({
119 base: 'test/',
120 src: 'index.html',
121 dest: 'styles/styles.min.css',
122 minify: true,
123 width: 1300,
124 height: 900
125});
126```
127
128Generate, minify and inline critical-path CSS:
129
130```js
131critical.generate({
132 inline: true,
133 base: 'test/',
134 src: 'index.html',
135 dest: 'index-critical.html',
136 minify: true,
137 width: 1300,
138 height: 900
139});
140```
141
142Generate and return output via callback:
143
144```js
145critical.generate({
146 base: 'test/',
147 src: 'index.html',
148 width: 1300,
149 height: 900
150}, function (err, output) {
151 // You now have critical-path CSS
152 // Works with and without dest specified
153 ...
154});
155```
156
157Generate and return output via promise:
158
159```js
160critical.generate({
161 base: 'test/',
162 src: 'index.html',
163 width: 1300,
164 height: 900
165}).then(function (output) {
166 // You now have critical-path CSS
167 // Works with and without dest specified
168 ...
169}).error(function (err) {
170 ...
171});
172```
173
174### Generate critical-path CSS with multiple resolutions
175
176When your site is adaptive and you want to deliver critical CSS for multiple screen resolutions this is a useful option.
177*note:* (your final output will be minified as to eliminate duplicate rule inclusion)
178
179```js
180critical.generate({
181 base: 'test/',
182 src: 'index.html',
183 dest: 'styles/main.css',
184 dimensions: [{
185 height: 200,
186 width: 500
187 }, {
188 height: 900,
189 width: 1200
190 }]
191});
192```
193
194### Generate critical-path CSS and ignore specific selectors
195
196This is a useful option when you e.g. want to defer loading of webfonts or background images.
197
198```js
199critical.generate({
200 base: 'test/',
201 src: 'index.html',
202 dest: 'styles/main.css',
203 ignore: ['@font-face',/url\(/]
204});
205```
206
207
208### Options
209
210| Name | Type | Default | Description |
211| ---------------- | ------------------ | ------------- |------------- |
212| inline | `boolean`&#124;`object` | `false` | Inline critical-path CSS using filamentgroup's loadCSS. Pass an object to configure [`inline-critical`](https://github.com/bezoerb/inline-critical#inlinehtml-styles-options) |
213| base | `string` | `path.dirname(src)` or `process.cwd()` | Base directory in which the source and destination are to be written |
214| html | `string` | | HTML source to be operated against. This option takes precedence over the `src` option. |
215| folder           | `string`           | | HTML source folder. Required to compute relative asset paths in conjunction with the `html` option |
216| css | `array` | `[]` | An array of paths to css files, or an array of [Vinyl](https://www.npmjs.com/package/vinyl) file objects.
217| src | `string` | | Location of the HTML source to be operated against |
218| dest | `string` | | Location of where to save the output of an operation (will be relative to base if no absolute path is set) |
219| destFolder | `string` | `''` | Subfolder relative to base directory. Only relevant without src (if raw html is provided) or if the destination is outside base |
220| styleTarget | `string` | | Target file to store the generated critical-path styles |
221| width | `integer` | `900` | Width of the target viewport |
222| height | `integer` | `1300` | Height of the target viewport |
223| dimensions | `array` | `[]` | An array of objects containing height and width. Takes precedence over `width` and `height` if set
224| minify | `boolean` | `false` | Enable minification of generated critical-path CSS |
225| extract | `boolean` | `false` | Remove 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 |
226| inlineImages | `boolean` | `false` | Inline images
227| assetPaths | `array` | `[]` | List of directories/urls where the inliner should start looking for assets
228| maxImageFileSize | `integer` | `10240`| Sets a max file size (in bytes) for base64 inlined images
229| timeout | `integer` | `30000`| Sets a maximum timeout for the operation
230| pathPrefix | `string` | `/` | Path to prepend CSS assets with. You *must* make this path absolute if you are going to be using critical in multiple target files in disparate directory depths. (eg. targeting both `/index.html` and `/admin/index.html` would require this path to start with `/` or it wouldn't work.)
231| include | `array` | `[]` | Force include CSS rules. See [`penthouse#usage`](https://github.com/pocketjoso/penthouse#usage-1).
232| ignore | `array` | `[]` | Ignore CSS rules. See [`filter-css`](https://github.com/bezoerb/filter-css) for usage examples.
233| ignoreOptions | `object` | `{}` | Ignore options. See [`filter-css#options`](https://github.com/bezoerb/filter-css#options).
234| userAgent | `string` | `''` | User agent to use when fetching a remote src
235| penthouse | `object` | `{}` | Configuration options for [`penthouse`](https://github.com/pocketjoso/penthouse).
236| user | `string` | `undefined` | RFC2617 basic authorization: user
237| pass | `string` | `undefined` | RFC2617 basic authorization: pass
238
239
240## CLI
241
242```
243$ npm install -g critical
244```
245
246critical works well with standard input.
247
248```
249$ cat test/fixture/index.html | critical --base test/fixture --inline > index.critical.html
250```
251
252You can also pass in the critical CSS file as an option.
253
254```
255$ critical test/fixture/index.html --base test/fixture > critical.css
256```
257
258
259## Gulp
260
261```js
262var gulp = require('gulp');
263var log = require('fancy-log');
264var critical = require('critical').stream;
265
266// Generate & Inline Critical-path CSS
267gulp.task('critical', function () {
268 return gulp.src('dist/*.html')
269 .pipe(critical({base: 'dist/', inline: true, css: ['dist/styles/components.css','dist/styles/main.css']}))
270 .on('error', function(err) { log.error(err.message); })
271 .pipe(gulp.dest('dist'));
272});
273```
274
275## Why?
276
277### Why is critical-path CSS important?
278
279> CSS is required to construct the render tree for your pages and JavaScript
280will often block on CSS during initial construction of the page.
281You should ensure that any non-essential CSS is marked as non-critical
282(e.g. print and other media queries), and that the amount of critical CSS
283and the time to deliver it is as small as possible.
284
285### Why should critical-path CSS be inlined?
286
287> For best performance, you may want to consider inlining the critical CSS
288directly into the HTML document. This eliminates additional roundtrips
289in the critical path and if done correctly can be used to deliver a
290“one roundtrip” critical path length where only the HTML is a blocking resource.
291
292
293## FAQ
294
295### Are there any sample projects available using Critical?
296
297Why, yes!. Take a look at [this](https://github.com/addyosmani/critical-path-css-demo) Gulp project
298which demonstrates using Critical to generate and inline critical-path CSS. It also includes a mini-tutorial
299that walks through how to use it in a simple webapp.
300
301### When should I just use Penthouse directly?
302
303The main differences between Critical and [Penthouse](https://github.com/pocketjoso/penthouse), a module we
304use, are:
305
306* Critical will automatically extract stylesheets from your HTML from which to generate critical-path CSS from,
307whilst other modules generally require you to specify this upfront.
308* Critical provides methods for inlining critical-path CSS (a common logical next-step once your CSS is generated)
309* Since we tackle both generation and inlining, we're able to abstract away some of the ugly boilerplate otherwise
310involved in tackling these problems separately.
311
312That said, if your site or app has a large number of styles or styles which are being dynamically injected into
313the DOM (sometimes common in Angular apps) I recommend using Penthouse directly. It will require you to supply
314styles upfront, but this may provide a higher level of accuracy if you find Critical isn't serving your needs.
315
316### What other alternatives to Critical are available?
317
318FilamentGroup maintain a [criticalCSS](https://github.com/filamentgroup/criticalCSS) node module, which
319similar to [Penthouse](https://github.com/pocketjoso/penthouse) will find and output the critical-path CSS for
320your pages.
321
322### Is Critical stable and suitable for production use?
323
324Critical has been used on a number of production sites that have found it stable for everyday use.
325That said, we welcome you to try it out on your project and report bugs if you find them.
326
327## Can I contribute?
328
329Of course. We appreciate all of our [contributors](https://github.com/addyosmani/critical/graphs/contributors) and
330welcome contributions to improve the project further. If you're uncertain whether an addition should be made, feel
331free to open up an issue and we can discuss it.
332
333## Maintainers
334
335This module is brought to you and maintained by the following people:
336
337* Addy Osmani - Creator ([Github](https://github.com/addyosmani) / [Twitter](https://twitter.com/addyosmani))
338* Ben Zörb - Primary maintainer ([Github](https://github.com/bezoerb) / [Twitter](https://twitter.com/bezoerb))
339
340## License
341
342Apache-2.0 © Addy Osmani, Ben Zörb
343
344
345[npm-url]: https://www.npmjs.com/package/critical
346[npm-image]: https://img.shields.io/npm/v/critical.svg
347[ci-url]: https://github.com/addyosmani/critical/actions?workflow=Tests
348[ci-image]: https://github.com/addyosmani/critical/workflows/Tests/badge.svg
349[depstat-url]: https://david-dm.org/addyosmani/critical
350[depstat-image]: https://david-dm.org/addyosmani/critical/status.svg
351
352[devdepstat-url]: https://david-dm.org/addyosmani/critical?type=dev
353[devdepstat-image]: https://david-dm.org/addyosmani/critical/dev-status.svg