Skip to content

Generate critical CSS path from HTML pages to enable instantaneous rendering

License

Notifications You must be signed in to change notification settings

tbela99/critical

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

66 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CRITICAL PATH GENERATOR

npm jsr NPM Downloads screenshot

Critical path generator tools using node oe the web browser.

Web browser script

Extract critical CSS path for the current viewport in the current page.

Using modules

<script type="module">

  import {parse, render} from 'https://esm.sh/@tbela99/css-parser@0.7.1/web';
  import {extract} from 'https://esm.sh/@tbela99/critical@1.2.0/browser';

  const results = await extract({fonts: true});
  // css is optimized using https://www.npmjs.com/package/@tbela99/css-parser
  // pretty print css
  const css = await parse(results.styles.join('\n')).then(result => render(result.ast, {minify: false}).code);

  console.debug(css);
</script>

Without using modules

<script src="https://cdn.jsdelivr.net/gh/tbela99/critical@1.2.0/dist/browser-umd.js"></script>
<script src="https://cdn.jsdelivr.net/gh/tbela99/css-parser@0.7.1/dist/index-umd-web.js"></script>
<script>

  (async () => {

    const {parse, render} = CSSParser;

    const results = await critical.extract({fonts: true});
    // optimize and pretty print css
    const css = await parse(results.styles.join('\n')).then(result => render(result.ast, {minify: false}).code);

    console.debug(css);
  })();
</script>

Options

  • options: object
    • fonts: bool? generate Javascript to load web fonts dynamically
    • html: bool? generate an HTML page containing inlined critical css
    • signal: AbortSignal? abort critical extraction using AbortSignal

Limitations

The web browser script is subject to the same origin policy and CSP. This can prevent the script from reading external stylesheets.

Node script

Generate critical CSS path from your nodejs script

import {critical} from "@tbela99/critical";

const urls = [
    'http://github.com',
    'https://docs.npmjs.com/cli/v8/configuring-npm/package-json#directories'
];

urls.forEach(async url => critical(url, {
    html: true,
    console: true,
    screenshot: true,
    secure: false,
    // dimensions can be specified as an array of string or object
    dimensions: ['1400x900', '1200x675', '992x558'],
    advanced: true
}).then((results) => {

    // print extracted CSS
    console.log(results.styles.join('\n'));
}));

Node script options

  • options: object

    browser settings

    • headless: bool. start the browser in headless mode. default true
    • browser: string. browser to use [choices: "chromium", "firefox", "webkit", "edge", "chrome"] default "chromium"
    • browserType: string. use a desktop or mobile browser [choices: 'desktop', 'mobile']
    • randomBrowser: use a random web browser
    • randomUserAgent: bool. use a random user agent

    runtime settings

    • container: bool. turn off additional security features, required to run inside a container
    • secure: bool. enforce browser security features such as CSP and same origin policy. default false

    screenshots settings

    • screenshot: bool. generate screenshot for each viewport mentioned. default false
    • colorScheme: string. force a color scheme [choices: 'dark', 'light']
    • filename: string. prefix of the generated files
    • width: int. viewport width. default 800
    • height: int. viewport height. default 600
    • dimensions: array or string. array of viewports. this takes precedence over height and width. viewports can be specified as objects with width and height property or a string.

    input settings

    • input: string. specify HTML input
    • base: string. specify HTML of the HTML input

    output settings

    • base: string. specify HTML for URL
    • html: bool. generate an HTML page containing the inlined critical css
    • output: string. change output directory. default './output/'
    • fonts: bool. generate javascript to load web fonts. default true
    • json: bool. dump result as JSON
    • advanced: bool. remove parts of css selectors that do not match any element. default false

    debugging settings

    • console: bool. log console messages from the pages. default true
    • verbose: bool. enable verbose mode

Command line script

Use with npx

$ npx @tbela99/critical@latest --help
$ npx @tbela99/critical@latest -r -i -e --html https://github.com/ https://nodejs.org

Use with bun

$ bunx @tbela99/critical@latest --help
$ bunx @tbela99/critical@latest -r -i -e --html https://github.com/ https://nodejs.org

Install from npm

$ npm install @tbela99/critical

Install from jsr

install for deno specific project

$ deno add @tbela99/critical

Install globally

when installed globally, it is available as critical-cli

$ npm install -g @tbela99/critical
$ critical-cli -i http://google.com

Usage

$ critical-cli.js [options+] url [url+]
run the command line tools:
Example: critical-cli.js -d 800x600 -d 1024x768 -i https://facebook.com

Options:
      --help            Show help                                      [boolean]
      --version         Show version number                            [boolean]
  -t, --headless        enable or disable headless mode[boolean] [default: true]
  -g, --base            base path using reading data from stdin         [string]
  -b, --browser         browser to use
  [string] [choices: "chromium", "firefox", "webkit", "edge", "chrome"] [default
                                                                   : "chromium"]
  -k, --browser-type    use a mobile browser
                                         [string] [choices: "mobile", "desktop"]
  -r, --random-browser  use a random browser          [boolean] [default: false]
  -u, --random-user-agent  use a random user agent    [boolean] [default: false]
  -i, --screenshot      Generate screenshots                           [boolean]
  -s, --secure          enable or disable security settings such as CSP and same
                         origin policy                                 [boolean]
  -m, --color-scheme    color scheme
                           [string] [choices: "light", "dark"] [default: "dark"]
  -o, --output          Output directory                                [string]
  -n, --filename        prefix of the generated files                   [string]
  -w, --width           Viewport width                                  [number]
  -a, --height          Viewport height                                 [number]
  -d, --dimensions      Array of viewports, override height/width settings
                                                                         [array]
  -f, --fonts           Generate javascript to load fonts dynamically
                                                       [boolean] [default: true]
  -l, --console         Show console messages from the browser         [boolean]
  -c, --container       Disable additional security settings to run inside a con
                        tainer                                         [boolean]
  -p, --html            Generate an HTML page containing inlined critical css
                                                                       [boolean]
      --json            print result in JSON format   [boolean] [default: false]
  -e, --advanced        remove parts of css selectors that do not match any elem
                        ent                           [boolean] [default: false]
  -v, --verbose         Enable verbose mode           [boolean] [default: false]

Example

Read data from URL

$ critical-cli https://github.com/ https://nodejs.org --secure=no -i -d '1440x900' -d '1366x768' --json

Read data from file(s)

$ critical-cli pages/dashboard.html pages/404.html --secure=no -i -d '1440x900' -d '1366x768' --json

Read data from STDIN

$ cat pages/dashboard.html | critical-cli --base=pages/ --secure=no -i -d '1440x900' -d '1366x768' --json

CHANGELOG

V1.2.0

  • accept files parameters in addition to urls
  • add missing cli argument 'random-user-agent'

V1.1.1

  • fix node 22 compatibility issues
  • publish to jsr.io

V1.1.0

  • read data from STDIN
  • remove unused selectors
  • dump cli result as JSON

V1.0.1

  • fix package.json dependencies and dev dependencies mix up

V1.0.0

  • converted to typescript
  • changed default export to es module
  • optimized generated css (merge rule, remove duplicate, minify, generate nested css)
  • specify color scheme [dark/light]