github

gajus / usus

  • понедельник, 10 июля 2017 г. в 03:12:42
https://github.com/gajus/usus


Renders page using Chrome Debugging Protocol (CDP). Extracts CSS used to render the page. Renders HTML with the blocking CSS made asynchronous. Inlines the critical CSS.



ūsus

Travis build status Coveralls NPM version Canonical Code Style Twitter Follow

Renders webpage using the Chrome Debugging Protocol (CDP). Extracts CSS used to render the page. Renders HTML with the blocking CSS made asynchronous. Inlines the critical CSS.

Article about ūsus ⚡️🤘: Pre-rendering SPA for SEO and improved perceived page loading speed

Motivation

I have a universal, single page application (SPA). The initial HTML is sent served by the server. I want to inline the CSS used to render the page and delay loading the rest of the CSS until after the page has loaded.

Removing the blocking CSS and inlining the CSS required to render the page increases the perceived page loading speed. Presumably, improves SEO by reducing the page loading time.

Use cases

  • Produce HTML used to render the page. Used to render single page applications (e.g. React and Angular) to produce a static HTML. This can be used as a replacement of https://prerender.io/. Default behaviour.
  • Extract CSS used to render a specific page. Used to capture the critical CSS. Use --extractStyles option.
  • Produce HTML used to render the page with the critical-path CSS inlined and blocking CSS made asynchronous. Use --inlineStyles option.

API

import {
  render
} from 'usus';

/**
 * @see https://github.com/gajus/usus#configuration
 */
const configuration = {}

const css = await render('http://gajus.com/', configuration);

Configuration

The default behaviour is to return the HTML.

  • Using the --extractStyles option returns the CSS used to render the document.
  • Using the --inlineStyles option returns HTML document with CSS inlined.
Name Type Description Default value
delay number Defines how many milliseconds to wait after the "load" event has been fired before capturing the styles used to load the page. This is important if resources appearing on the page are being loaded asynchronously. number
deviceMetricsOverride See deviceMetricsOverride configuration
cookies Array<{name: string, value: string}> Sets a cookie with the given cookie data. N/A
extractStyles boolean Extracts CSS used to render the page. false
inlineStyles boolean Inlines the styles required to render the document. false
formatStyles (styles: string) => Promise<string> Used to format CSS. Useful with --inlineStyles option to format the CSS before it is inlined. N/A
url string The URL to render. N/A

deviceMetricsOverride configuration

Name Type Description Default value
deviceScaleFactor number Overriding device scale factor value. 1
fitWindow boolean Whether a view that exceeds the available browser window area should be scaled down to fit. false
height number Overriding width value in pixels (minimum 0, maximum 10000000). 1080
width number Overriding height value in pixels (minimum 0, maximum 10000000). 1920
mobile boolean Whether to emulate mobile device. This includes viewport meta tag, overlay scrollbars, text autosizing and more. false

For more information about the deviceMetricsOverride configuration, refer to Chrome DevTools Protocol Viewer documentation.

Cookbook

Using via the command line interface (CLI)

$ npm install usus --global
$ usus --help
# Renders static HTML. Equivalent to https://prerender.io/.
$ usus render --url http://gajus.com/
# Extracts CSS used to render the page.
$ usus render --url http://gajus.com/ --extractStyles true
# Inlines styles required to render the page.
$ usus render --url http://gajus.com/ --inlineStyles true
$ usus render --url http://gajus.com/ --cookies foo=bar,baz=qux
# Render emulating the iPhone 6
$ usus render --url http://gajus.com/ --deviceMetricsOverride.deviceScaleFactor 2 --deviceMetricsOverride.fitWindow false --deviceMetricsOverride.height 1334 --deviceMetricsOverride.mobile true --deviceMetricsOverride.width 750

Building Docker container with Chrome

Add the following line to your Dockerfile:

RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
  && sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
  && apt-get update -y \
  && apt-get install google-chrome-stable -y

This assumes that you are extending from the base node image.

Minify the CSS

Use the formatStyles callback to minify/ format/ optimize/ remove CSS before it is inlined.

In this example, I am using csso minifier.

import {
  render
} from 'usus';
import {
  minify
} from 'csso';

return render(url, {
  formatStyles: (styles: string): Promise<string> => {
    return minify(styles).css;
  },
  inlineStyles: true
});

Debugging

Export DEBUG=usus variable to get additional debugging information, e.g.

$ export DEBUG=usus*
$ usus --url http://gajus.com

Implementation

ūsus uses Chrome Debugging Protocol CSS coverage report to generate a stylesheet used to render the document.

Alternatives

The following programs provide equivalent service:

All of these programs are using PhantomJS or JSDom to render the page/ evaluate the scripts.

ūsus is different because it is using Chrome Debugging Protocol and it leverages the Chrome CSS coverage report to generate a stylesheet used to render the document.