Repository: addyosmani/critical Branch: master Commit: 29651ee367f0 Files: 126 Total size: 592.7 KB Directory structure: gitextract_6mprb1p7/ ├── .editorconfig ├── .gitattributes ├── .github/ │ └── workflows/ │ ├── docker.yml │ └── test.yml ├── .gitignore ├── .npmrc ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Dockerfile ├── README.md ├── cli.js ├── index.js ├── license ├── package.json ├── src/ │ ├── array.js │ ├── config.js │ ├── core.js │ ├── errors.js │ └── file.js └── test/ ├── array.test.js ├── blackbox.test.js ├── cli.test.js ├── config.test.js ├── core.test.js ├── expected/ │ ├── generate-adaptive-useragent.css │ ├── generate-adaptive.css │ ├── generate-default-nostyle.css │ ├── generate-default-nostyle.html │ ├── generate-default.css │ ├── generate-ignore.css │ ├── generate-ignorefont.css │ ├── generate-ignorefont.html │ ├── generate-image-absolute.css │ ├── generate-image-big.css │ ├── generate-image-relative-subfolder.css │ ├── generate-image-relative.css │ ├── generate-image-skip.css │ ├── generate-image.css │ ├── generateInline-external-extract.html │ ├── generateInline-external-extract2.html │ ├── generateInline-external-minified.html │ ├── generateInline-external-minified2.html │ ├── generateInline-extract.html │ ├── generateInline-svg.html │ ├── generateInline.html │ ├── ignore.css │ ├── inline-image.html │ ├── inline-minified.html │ ├── inline.html │ ├── issue-192.css │ ├── issue-395.css │ ├── issue-566.css │ ├── main.css │ ├── path-prefix.css │ └── streams-default.html ├── file.test.js ├── fixtures/ │ ├── 403-css.html │ ├── 404-css.html │ ├── error.html │ ├── folder/ │ │ ├── generate-default.html │ │ ├── generate-image.html │ │ ├── index.html │ │ ├── relative-different.html │ │ ├── relative.html │ │ ├── styles/ │ │ │ └── issue-566.css │ │ └── subfolder/ │ │ ├── generate-image-absolute.html │ │ ├── head.html │ │ ├── issue-216.css │ │ └── relative.html │ ├── generate-adaptive-base64.html │ ├── generate-adaptive-inline.html │ ├── generate-adaptive.html │ ├── generate-default-nostyle.html │ ├── generate-default-querystring.html │ ├── generate-default.html │ ├── generate-ignorefont.html │ ├── generate-image.html │ ├── generateInline-external.html │ ├── generateInline-external2.html │ ├── generateInline-svg.html │ ├── generateInline.html │ ├── head.html │ ├── ignore.html │ ├── ignoreInlinedStyles.html │ ├── include.html │ ├── inline-image.html │ ├── inline.html │ ├── issue-192.html │ ├── issue-304-nostyle.html │ ├── issue-304.html │ ├── issue-314.html │ ├── issue-395.html │ ├── issue-415.html │ ├── issue-562.html │ ├── issue-566.html │ ├── media-attr.html │ ├── path-prefix.html │ ├── preload.html │ ├── print.html │ ├── relative-different.html │ ├── remote-different.html │ ├── streams-default.html │ ├── styles/ │ │ ├── adaptive.css │ │ ├── bootstrap.css │ │ ├── critical-image-pregenerated.css │ │ ├── critical-pregenerated.css │ │ ├── font.css │ │ ├── ignore.css │ │ ├── image-absolute.css │ │ ├── image-big.css │ │ ├── image-relative.css │ │ ├── include.css │ │ ├── issue-192.css │ │ ├── issue-304.css │ │ ├── issue-415.css │ │ ├── issue-562.css │ │ ├── main.css │ │ ├── media-attr.css │ │ ├── path-prefix.css │ │ ├── print.css │ │ └── some/ │ │ └── path/ │ │ └── image.css │ └── useragent/ │ ├── generate-default-useragent.html │ └── styles/ │ ├── bootstrap.css │ └── main.css ├── helper/ │ └── index.js └── index.test.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ root = true [*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.css] insert_final_newline = false [package.json] indent_style = space indent_size = 2 [*.md] trim_trailing_whitespace = false ================================================ FILE: .gitattributes ================================================ # Enforce Unix newlines * text=auto eol=lf ================================================ FILE: .github/workflows/docker.yml ================================================ # This workflow uses actions that are not certified by GitHub. # They are provided by a third-party and are governed by # separate terms of service, privacy policy, and support # documentation. # GitHub recommends pinning actions to a commit SHA. # To get a newer version, you will need to update the SHA. # You can also reference a tag or branch, but the action may change without warning. name: Create and publish a Docker image on: push: branches: - master env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} jobs: build-and-push-image: runs-on: ubuntu-latest permissions: contents: read packages: write steps: - name: Checkout repository uses: actions/checkout@v3 with: fetch-depth: 0 - name: Log in to the Container registry uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - name: Build and push Docker image uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc with: context: . push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} ================================================ FILE: .github/workflows/test.yml ================================================ name: Tests on: [push, pull_request] env: CI: true jobs: run: name: Node ${{ matrix.node }} on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: node: [18, 20] os: [ubuntu-latest, windows-latest] steps: - name: Clone repository uses: actions/checkout@v3 with: persist-credentials: false - name: Set up Node.js uses: actions/setup-node@v3 with: node-version: ${{ matrix.node }} cache: npm - name: Install npm dependencies run: npm ci - name: Run tests run: npm test - name: Patch lcov.info run: sed -i -- 's/SF:..\//SF:.\//g' ./coverage/lcov.info - name: Coveralls Parallel uses: coverallsapp/github-action@master env: NODE_COVERALLS_DEBUG: 1 with: github-token: ${{ secrets.github_token }} flag-name: run-${{ matrix.os }}-${{ matrix.node }} parallel: true finish: needs: run runs-on: ubuntu-latest steps: - name: Coveralls Finished uses: coverallsapp/github-action@master with: github-token: ${{ secrets.github_token }} parallel-finished: true ================================================ FILE: .gitignore ================================================ /coverage/ /node_modules/ /test/fixture/bower_components/bootstrap/dist/css/* /test/fixture/test-* /test/fixture/tmp-* /test/fixtures/styles/bootstrap.beffebca.css /test/fixtures/styles/main.d41d8cd9.css ================================================ FILE: .npmrc ================================================ lockfile-version=2 ================================================ FILE: CHANGELOG.md ================================================ # v2.0.0 / 2020-06-16 - Drop support for Node.js < 10 - Bump dependencies - Use Jest for testing - Drop `include` and `timeout` options as they can be specified in the `penthouse` options. - Drop options `styleTarget` & `dest` in favour of `target` You can specify either a **css** file, an **html** file or an object `{css: dest.css, html: dest.html}` if you want to store both. We may also add an extract target here in a future release. - Drop options `destFolder`, `folder` and `pathPrefix`. We tried our best to improve the way critical auto-detects the paths to used assets in the critical css which should suit for most cases. If this doesn't work out you can use the new `rebase` option to either specify the location of the css & the html file like this: `{from: '/styles/main.css', to: '/en/test.html'}`. You can also pass a callback function to dynamically compute the path or specify a cdn for example. We utilize [`postcss-url`](https://github.com/postcss/postcss-url#options-list) for this task. - Due to some limitations with modern css features we replaced `filter-css` as the library of choice for handling ignores with [postcss-discard](https://github.com/bezoerb/postcss-discard/). We tried to keep things backwards compatible but you may have to change your `ignore` configuration. - Add `concurrency` option to specify how many operations can run in parallel. - Add the ability to specify used css files using file globs. See supported `minimatch` [patterns](https://github.com/isaacs/minimatch#usage). # v1.3.4 / 2018-07-19 - fix: return `Promise.reject` instead of re-throw - fix: handle `PAGE_UNLOADED_DURING_EXECUTION` error (#314) - output warning on invalid extract setting - Add user agent option (#316) - Bump dependencies - npm audit fix # v1.3.3 / 2018-06-06 - Bump dependencies - Docs: fix typo (#310) - Reduced vulnerabilities (#308) # v1.3.2 / 2018-05-15 - Switched to async-exit-hook # v1.3.1 / 2018-05-14 - Bump dependencies - Removed `process.exit` on cleanup - Adding html-webpack-critical-plugin to README (#306) # v1.3.0 / 2018-05-02 - Add basic auth option (#295) # v1.2.2 / 2018-04-02 - Improved handling of protocol-relative asset URLs (#288) - Adjust test files according to (#293) - Improve error reporting (#258) - Replace gutil with fancy-log (#297) - Update README.md (#296) # v1.2.1 / 2018-03-26 - Add license file # v1.2.0 / 2018-03-19 - Allow external stylesheets to be passed as css option (#290) - Add Tests for #277 # v1.1.1 / 2018-03-15 - Bump dependencies # v1.1.0 / 2017-12-02 - 1.1.0 - Remove temporary files - Bump inline-critical - Fix corrupted `File.contents` (#191, #218) # v1.0.0 / 2017-11-06 - Bump dependencies - Removed deprecated methods - Don't enforce strict SSL for external assets (#171) - Allow http 2xx response codes (#244) - Replace `|` with its HTML character entity reference (#248) - Headless chrome (#246) - Add `folder` option to readme (#245) # v0.9.1 / 2017-09-04 - AppVeyor tweaks - Use yarn with AppVeyor - Added package missing in AppVeyor - Remove AppVeyor cache - Try to reinstall "css" dependencies - Upgrade Penthouse - Update readme according to #220 # v0.9.0 / 2017-07-19 - Bump dependencies - Library options (#178) - Ignore print styles (#113) (#221) - Prefer `let` & `const` + arrow functions - Run tests on Node.js 8 - Support for passing CSS files as Vinyl objects. (#204) # v0.8.4 / 2017-03-01 - Better remote handling (#198) - Bump inline-critical # v0.8.3 / 2017-02-17 - Fixed multi-dimension critical-path CSS # v0.8.2 / 2017-02-11 - Bump dependencies - Update README.md # v0.8.1 / 2016-11-24 - Added missing comma - Add tmpfile to garbage collector - Bump dependencies - Vinyl (#120) # v0.8.0 / 2016-08-30 - Revise production-use messaging. - Consistent CSS capitalization in README. - Remove object.assign; require Node.js 4. - Fix all tests to run on Windows. - Enforce LF. - Fix xo errors. - Update dependencies. - Fix test failures. (#155) - Travis: add explicitly Node.js 4 and 6. (#154) - Update .gitignore. - package.json: remove duplicate dep. (#153) - Remove JSHint leftovers. (#152) - Update README.md (#151) - Update appveyor.yml (#150) - added penthouse timeout option (#140) - CSS Rel Preload support (#129) # v0.7.3 / 2016-05-30 - Bump package.json version - Add test for 404 case - Remove trailing whitespace - Fix silly typo - Ignore 404 requests, reject promise with `Error` not `String` - Fixed #130 - Better error message for unresolved css files - cli: exit after `stdout.write` - Remove `uncaughtException` listener; log error instead - Fixed import-order - Bump dependencies - Added changelog (#123) # v0.7.2 / 2016-03-17 - Add include option (#125) # v0.7.1 / 2016-02-26 - Dropped JSHint and added xo - Adjust tests for penthouse 0.8.4 - Bump dependencies - Remove listeners on exit - Update Readme # v0.7.0 / 2015-12-22 - bump penthouse - Test #79 - some debug logs - trigger cleanup - added missing deps - Switch to http server for local files (#94) - ignore generated css - tests adjusted for penthouse 0.7.1 - minor tweaks - Fix AppVeyor tests - local url for phantomjs (#94) - penthouse bump - Bump dependencies - Bump inline-critical - Update README.md - use default base - add a test for query string in file name - fix local files query string `ENOENT` exception - fixed tests for bumped deps - Bump dependencies - AppVeyor file tweaks - Actually Emit Critical Error in Stream - cleanup - Switched to postcss-image-inliner - bump inline-critical - AppVeyor tweaks - cleanup - added gc to address #82 - Added CLI remote test - some cleanup - fixed phantom on missing file extension - use loadCSS 0.1.8 - allow remote resources - Bump dependencies # v0.6.0 / 2015-07-07 - added testcase for #88 - testcase for bc53420 issue - Fixed issue from bc53420 - Update README.md - backwards compatibility - drop Node.js 0.10 - simplify CLI help creation - minor style tweaks - Merged master - Fixed tests & locked clean-css version - Bump filter-css - Fixed CLI tests - minor package.json tweaks - Bump devDependencies - Correct expectation for adaptive - Updated tests for new clean-css 3.2.7 - some cleanup - Bump dependencies - Update README.md - Don't encode entities - Removed parallel testcase - Add 'ignore' option - Deprecated some things - deprecated htmltarget & styletarget for CLI and introduced --inline - Added pathPrefix support for CLI - normalize newlines - added test for pathPrefix option - allows pathPrefix to be set through options. Updates README - Added stream wrapper # v0.5.7 / 2015-04-12 - AppVeyor tweaks - Automated Windows tests using AppVeyor - Fixed tests on Windows - Added some badges - Bump dependencies - cleancss syntax change - modified tests to use new cleancss output # v0.5.6 / 2015-03-16 - catch cancellation - Fix callbacks on error # v0.5.5 / 2015-03-03 - Fixed CLI error codes - renaming - Added jshint - Added tests for #63 & #64 - Bump dependencies - up dimensions used in tests, update expected result files - fix typo - up dimensions used for generate in index.js - up dimensions used in README examples - Fix multi test - bump dependency - fix #67 - Add support for multi-dimension critical css. - improve file structure - readme tweaks - fix .gitignore - codestyle - Bump dependencies - updated tests for penthouse 0.3.0 # v0.5.4 / 2015-02-09 - Update .travis.yml - Use `os.tmpdir()` folder for temporary css - add `preferGlobal` prop to package.json # v0.5.3 / 2015-01-18 - Bump dependencies # v0.5.2 / 2015-01-12 - #56 Locked penthouse version # v0.5.1 / 2014-12-28 - Fixed tests - inline-critical version bump - Fixed CLI Tests for Windows - Added tests and additional CLI fixes for #52 - Fix for #52 # v0.5.0 / 2014-11-28 - inline critical version bump - Increased mocha timeout - Fixed newline character in css to address #14 - Updated version of inline-critical to address #14 - Added bin/critical to files #49 - added CLI / changed structure - Update README.md - Remove inlined CSS rules from source stylesheets #39 - Fixed backslash in rebased paths on Windows - fixed fa77c44 - Return critical css even if unlinking of the temporary file fails - Ignores external stylesheets # v0.4.0 / 2014-10-04 - Add build tasks - Update UUID dep - Changed inlineImages default to false - Fixed tests for #35 # v0.3.1 / 2014-09-16 - Fixed parallel calls mentioned in #34 # v0.3.0 / 2014-09-09 - Update fixtures to account for dep. bump - Bump dependencies # v0.2.0 / 2014-08-30 - fixed implementation in #30 - Skipped max size for inlined images - Added image inlining to generate - removed dynamic test file - Adds a maxImageFileSize for inlined images and rebases relative css resource paths # v0.1.6 / 2014-07-30 - Update to Penthouse 0.2.5 to addr raised issues - change penthouse test to critical css test - some code formatting - Fixed tests - fixed fixtures - changed test size to only include header nav - prevent catching callback test errors - Format code - Make CSS files/path configurable - CSS Images fix - Add more demo projects. - Add demo projects. - Move viewport settings up. - Improve formatting of first example. # v0.1.5 / 2014-07-16 - Improve the Critical / Penthouse section - Readme corrections - Add contributing guide - Readme revisions - Add mention of criticalCSS module. - More edits - Infra revisions - Add note about unit tests. - Add better comments to inline-styles. - Tweaks to readme. - Minor revisions. # v0.1.4 / 2014-07-11 - Add note about sample project - Strap update - improve tests - Tweak to readme. - Update README.md - fix all the things - Attempt to fix builds - README.md: break long lines. - Lint fixes. - Whitespace normalization - package.json: Add missing properties. # v0.1.3 / 2014-07-04 - Add support for generateInline # v0.1.2 / 2014-07-04 - Address path issues post-integration testing # v0.1.1 / 2014-07-04 - Add missing file to package - Update to latest Oust, API - Add syntax highlighting to code blocks # v0.1.0 / 2014-06-30 - Consistency of example order - Add minification for inline styles - Fix some style, cb issues - Revisions for minification - Add support for minification - Add options to readme - Fixes #9 - adds defaults for w/h - Add note about FAQs, license - Expand on joined paths - Move reads - Improve test descriptions - Improve callbacks, add more tests - Fixes #2, passes errors - Path joins for #6, test > fixture for #10, other fixes - Fixes #4 - drop log statements - Fixes #5 - switch to readFile/writeFile only - Fixes #7 - throw if src/base not specified - Should fix #1 - only write to disk if dest specified - Switch to integers - Readme revisions # v0.0.1 / 2014-06-28 - API revisions, readme updates, cleanup - Various fixes - Add implementation. - Add tests. - Add testing rig. - Add README. - Initial package. - Initial commit ================================================ FILE: CONTRIBUTING.md ================================================ Critical is an open source project. It is licensed using the [Apache Software License 2.0](http://www.apache.org/licenses/LICENSE-2.0.html). We really appreciate pull requests and bug reports, here are our guidelines: 1. If filing a bug report, please verify the issue is with Critical first. A good sanity check is: does the issue have to do with styles not being correctly captured? If so, test with [Penthouse](https://github.com/pocketjoso/penthouse). If it works with Penthouse then it's a Critical bug and we encourage you to open up a [new ticket](https://github.com/addyosmani/critical/issues/new) with details. Does the bug have to do with inlining styles, general module failures or installation issues? Those are also possibly Critical bugs and we will strive to take a look at them. 1. Working on a patch? File a bug at https://github.com/addyosmani/critical/issues (if there isn’t one already). If your patch is going to be large it might be a good idea to get the discussion started early. We are happy to discuss it in a new issue beforehand. 1. Make sure that patches provide justification for why they should be merged. ================================================ FILE: Dockerfile ================================================ FROM node:20-slim ARG CRITICAL_VERSION=5.0.4 ARG PACKAGES="\ libx11-6\ libx11-xcb1\ libxcomposite1\ libxcursor1\ libxdamage1\ libxext6\ libxi6\ libxtst6\ libglib2.0-0\ libnss3\ libcups2\ libxss1\ libexpat1\ libxrandr2\ libasound2\ libatk1.0-0\ libatk-bridge2.0-0\ libpangocairo-1.0-0\ libgtk-3-0\ " RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache # hadolint ignore=DL3008 RUN --mount=type=cache,id=build-apt-cache,sharing=locked,target=/var/cache/apt \ --mount=type=cache,id=build-apt-lib,sharing=locked,target=/var/lib/apt \ apt-get update -qq \ && apt-get install --no-install-recommends -y ${PACKAGES} \ && rm -rf /var/lib/apt/lists /var/cache/apt/archives RUN --mount=type=cache,id=build-npm-cache,sharing=locked,target=/root/.npm \ npm install -g critical@${CRITICAL_VERSION} WORKDIR /site CMD ["critical", "--help"] ================================================ FILE: README.md ================================================ [![NPM version][npm-image]][npm-url] [![Build Status][ci-image]][ci-url] [![Coverage][coveralls-image]][coveralls-url] # critical Critical extracts & inlines critical-path (above-the-fold) CSS from HTML Preview ## Install ```sh npm i -D critical ``` ## Build plugins - [grunt-critical](https://github.com/bezoerb/grunt-critical) - Gulp users should use Critical directly - For Webpack use [html-critical-webpack-plugin](https://github.com/anthonygore/html-critical-webpack-plugin) ## Demo projects - [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) - [Optimize an Angular boilerplate with Gulp](https://github.com/addyosmani/critical-path-angular-demo) - [Optimize a Weather app with Gulp](https://github.com/addyosmani/critical-css-weather-app) ## Usage Include: ```js import {generate} from 'critical'; ``` Full blown example with available options: ```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 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 Basic usage: ```js generate({ inline: true, base: 'test/', src: 'index.html', target: 'index-critical.html', width: 1300, height: 900, }); ``` ### Generate critical-path CSS Basic usage: ```js generate({ base: 'test/', src: 'index.html', target: 'styles/main.css', width: 1300, height: 900, }); ``` Generate and minify critical-path CSS: ```js generate({ base: 'test/', src: 'index.html', target: 'styles/styles.min.css', width: 1300, height: 900, }); ``` Generate, minify and inline critical-path CSS: ```js generate({ inline: true, base: 'test/', src: 'index.html', target: { html: 'index-critical.html', css: 'critical.css', }, width: 1300, height: 900, }); ``` Generate and return output via callback: ```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. ... }); ``` Generate and return output via promise: ```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. }).catch(err => { // … }); ``` Generate and return output via async function: ```js const {css, html, uncritical} = await generate({ base: 'test/', src: 'index.html', width: 1300, height: 900, }); ``` ### Generate critical-path CSS with multiple resolutions When your site is adaptive and you want to deliver critical CSS for multiple screen resolutions this is a useful option. _note:_ (your final output will be minified as to eliminate duplicate rule inclusion) ```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 This is a useful option when you e.g. want to defer loading of webfonts or background images. ```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 critical-path CSS using filamentgroup's loadCSS. Pass an object to configure [`inline-critical`](https://github.com/bezoerb/inline-critical#inlinehtml-styles-options) | | base | `string` | `path.dirname(src)` or `process.cwd()` | Base directory in which the source and destination are to be written | | html | `string` | | HTML source to be operated against. This option takes precedence over the `src` option. | | css | `array` | `[]` | An array of paths to css files, file globs, [Vinyl](https://www.npmjs.com/package/vinyl) file objects or source CSS strings. | | src | `string` | | Location of the HTML source to be operated against | | target | `string` or `object` | | Location of where to save the output of an operation. Use an object with 'html' and 'css' props if you want to store both | | width | `integer` | `1300` | Width of the target viewport | | height | `integer` | `900` | Height of the target viewport | | dimensions | `array` | `[]` | An array of objects containing height and width. Takes precedence over `width` and `height` if set | | 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 | | inlineImages | `boolean` | `false` | Inline images | | assetPaths | `array` | `[]` | List of directories/urls where the inliner should start looking for assets | | maxImageFileSize | `integer` | `10240` | Sets a max file size (in bytes) for base64 inlined images | | rebase | `object` or `function` | `undefined` | Critical 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`](https://github.com/postcss/postcss-url) for details. (https://github.com/pocketjoso/penthouse#usage-1). | | ignore | `array` or `object` | `undefined` | Ignore CSS rules. See [`postcss-discard`](https://github.com/bezoerb/postcss-discard) for usage examples. If you pass an array all rules will be applied to atrules, rules and declarations; | | ignoreInlinedStyles | `boolean` | `false` | Ignore inlined stylesheets | | userAgent | `string` | `''` | User agent to use when fetching a remote src | | penthouse | `object` | `{}` | Configuration options for [`penthouse`](https://github.com/pocketjoso/penthouse). | | request | `object` | `{}` | Configuration options for [`got`](https://github.com/sindresorhus/got). | | cleanCSS | `object` | `{level: { 1: { all: true }, 2: { all: false, removeDuplicateFontRules: true, removeDuplicateMediaBlocks: true, removeDuplicateRules: true, removeEmpty: true, mergeMedia: true } }}` | Configuration options for [`CleanCSS`](https://github.com/clean-css/clean-css) which let's you configure the optimization level for the generated critical css | | user | `string` | `undefined` | RFC2617 basic authorization: user | | pass | `string` | `undefined` | RFC2617 basic authorization: pass | | strict | `boolean` | `false` | Throw an error on css parsing errors or if no css is found. | ## CLI ```sh npm install -g critical ``` critical works well with standard input. ```sh cat test/fixture/index.html | critical --base test/fixture --inline > index.critical.html ``` Or on Windows: ```bat type test\fixture\index.html | critical --base test/fixture --inline > index.critical.html ``` You can also pass in the critical CSS file as an option. ```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. ## FAQ ### Are there any sample projects available using Critical? Why, yes!. Take a look at [this](https://github.com/addyosmani/critical-path-css-demo) Gulp project which demonstrates using Critical to generate and inline critical-path CSS. It also includes a mini-tutorial that walks through how to use it in a simple webapp. ### When should I just use Penthouse directly? The main differences between Critical and [Penthouse](https://github.com/pocketjoso/penthouse), a module we use, are: - Critical will automatically extract stylesheets from your HTML from which to generate critical-path CSS from, whilst other modules generally require you to specify this upfront. - Critical provides methods for inlining critical-path CSS (a common logical next-step once your CSS is generated) - Since we tackle both generation and inlining, we're able to abstract away some of the ugly boilerplate otherwise involved in tackling these problems separately. That said, if your site or app has a large number of styles or styles which are being dynamically injected into the DOM (sometimes common in Angular apps) I recommend using Penthouse directly. It will require you to supply styles upfront, but this may provide a higher level of accuracy if you find Critical isn't serving your needs. ### What other alternatives to Critical are available? FilamentGroup maintain a [criticalCSS](https://github.com/filamentgroup/criticalCSS) node module, which similar to [Penthouse](https://github.com/pocketjoso/penthouse) will find and output the critical-path CSS for your pages. The PageSpeed Optimization modules for nginx, apache, IIS, ATS, and Open Lightspeed can do all the heavy lifting automatically when you enable the [prioritize_critical_css](https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery) filter ### Is Critical stable and suitable for production use? Critical has been used on a number of production sites that have found it stable for everyday use. That said, we welcome you to try it out on your project and report bugs if you find them. ## Can I contribute? Of course. We appreciate all of our [contributors](https://github.com/addyosmani/critical/graphs/contributors) and welcome contributions to improve the project further. If you're uncertain whether an addition should be made, feel free to open up an issue and we can discuss it. ## Maintainers This module is brought to you and maintained by the following people: - Addy Osmani - Creator ([Github](https://github.com/addyosmani) / [Twitter](https://twitter.com/addyosmani)) - Ben Zörb - Primary maintainer ([Github](https://github.com/bezoerb) / [Twitter](https://twitter.com/bezoerb)) ## License [Apache-2.0 © Addy Osmani, Ben Zörb](license) [npm-url]: https://www.npmjs.com/package/critical [npm-image]: https://img.shields.io/npm/v/critical.svg [ci-url]: https://github.com/addyosmani/critical/actions?workflow=Tests [ci-image]: https://github.com/addyosmani/critical/workflows/Tests/badge.svg [coveralls-url]: https://coveralls.io/github/addyosmani/critical?branch=master [coveralls-image]: https://img.shields.io/coveralls/github/addyosmani/critical/master.svg ================================================ FILE: cli.js ================================================ #!/usr/bin/env node import os from 'node:os'; import process from 'node:process'; import stdin from 'get-stdin'; import groupArgs from 'group-args'; import indentString from 'indent-string'; import {escapeRegExp, isObject, isString, reduce} from 'lodash-es'; import meow from 'meow'; import pico from 'picocolors'; import {validate} from './src/config.js'; import {generate} from './index.js'; const help = ` Usage: critical [