Home

Awesome

dr-css-inliner

Puppeteer script to inline above-the-fold CSS on a webpage.

Inlining CSS for above-the-fold content (and loading stylesheets in a non-blocking manner) will make pages render instantly. This script will help extract the CSS needed.

As proposed by the Google Pagespeed team: Optimizing the Critical Rendering Path for Instant Mobile Websites - Velocity SC - 2013

How it works

There are two ways of processing a webpage; loaded via the url argument or piped in through stdin. When using stdin it is required that you use the --fake-url option in conjunction.

Once Puppeteer has loaded the page all stylesheets with no media set or with media set to screen or all are loaded again through XHR to avoid browser engine bias when parsing CSS.

The CSS is inlined as per the supplied options and all stylesheets and style elements stripped from the webpage html. You can opt to expose the stripped stylesheets as an array in a script tag through the -e (--expose-stylesheets) option.

Install

npm install dr-css-inliner -g

Usage:

dr-css-inliner <url> [options]

Options:

Examples:
CSS options

Only inline the needed above-the-fold CSS for smaller devices:

dr-css-inliner http://www.mydomain.com/index.html -w 350 -h 480 -m -o index-mobile.html

Inline all needed CSS for the above-the-fold content on all devices (default 1200px and smaller):

dr-css-inliner http://www.mydomain.com/index.html -h 800 -o index-page-top.html

Inline all needed CSS for webpage:

dr-css-inliner http://www.mydomain.com/index.html -o index-full-page.html

Inline all needed CSS for webpage with extra required selectors:

dr-css-inliner http://www.mydomain.com/index.html -r ".foo > .bar, #myId" -o index-full-page.html

Inline all needed CSS for webpage with extra required regexp selector filters:

dr-css-inliner http://www.mydomain.com/index.html -r '["\\.foo > ", "\\.span-\\d+"]' -o index-full-page.html
Output options

The examples listed below use the following index.css and index.html samples (unless specified otherwise):

index.css:

.foo {
	color: #BADA55;
}
.bar {
	color: goldenrod;
}

index.html:

<!doctype html>
<html>
	<head>
		<title>Foo</title>
		<link href="index.css" rel="stylesheet" media="screen" />
		<link href="print.css" rel="stylesheet" media="print" />
	</head>
	<body>
		<h1 class="foo">Inlining CSS is in</h1>
	</body>
</html>

Doing:

dr-css-inliner index.html

...would get you:

<!doctype html>
<html>
	<head>
		<title>Foo</title>
		<style>
			.foo {
				color: #BADA55;
			}
		</style>
	</head>
	<body>
		<h1 class="foo">Inlining CSS is in</h1>
	</body>
</html>
Only output CSS

-c, --css-only

dr-css-inliner index.html -c

...would get you:

.foo {
	color: #BADA55;
}
Exposing the stripped stylesheets for later consumption

-e, --expose-stylesheets [string]

Single global variable:

dr-css-inliner index.html -e stylesheets

...would get you:

<!doctype html>
<html>
	<head>
		<title>Foo</title>
		<style>
			.foo {
				color: #BADA55;
			}
		</style>
		<script>
			var stylesheets = [{url: "index.css", media: "screen"}, {url: "print.css", media: "print"}];
		</script>
	</head>
	<body>
		<h1 class="foo">Inlining CSS is in</h1>
	</body>
</html>

Namespaced property:

dr-css-inliner index.html -e myNamespace.stylesheets

provided you had an index.html like:

<!doctype html>
<html>
	<head>
		<title>Foo</title>
		<script>
			var myNamespace = {};
		</script>
		<link href="index.css" rel="stylesheet" media="screen" />
		<link href="print.css" rel="stylesheet" media="print" />
	</head>
	<body>
		<h1 class="foo">Inlining CSS is in</h1>
	</body>
</html>

...would get you:

<!doctype html>
<html>
	<head>
		<title>Foo</title>
		<script>
			var myNamespace = {};
		</script>
		<style>
			.foo {
				color: #BADA55;
			}
		</style>
		<script>
			myNamespace.stylesheets = [{url: "index.css", media: "screen"}, {url: "print.css", media: "print"}];
		</script>
	</head>
	<body>
		<h1 class="foo">Inlining CSS is in</h1>
	</body>
</html>
Controlling where to insert the inlined CSS

-t, --insertion-token [string]

provided you had an index.html like:

<!doctype html>
<html>
	<head>
		<title>Foo</title>
		<!-- CSS goes here -->
		<script>
			var myNamespace = {};
		</script>
		<link href="index.css" rel="stylesheet" media="screen" />
		<link href="print.css" rel="stylesheet" media="print" />
	</head>
	<body>
		<h1 class="foo">Inlining CSS is in</h1>
	</body>
</html>
dr-css-inliner index.html -t "<!-- CSS goes here -->"

...would get you:

<!doctype html>
<html>
	<head>
		<title>Foo</title>
		<style>
			.foo {
				color: #BADA55;
			}
		</style>
		<script>
			var myNamespace = {};
		</script>
	</head>
	<body>
		<h1 class="foo">Inlining CSS is in</h1>
	</body>
</html>
Avoid loading unneeded resources

-s, --strip-resources [string]

Doing:

dr-css-inliner index.html -s '["\\.(jpg|gif|png)$","webstat\\.js$"]'

... would avoid loading images and a given web statistic script.

Debug info

-d, --debug

Doing:

dr-css-inliner index.html -d

...would get you:

<!doctype html>
<html>
	<head>
		<title>Foo</title>
		<style>
			.foo {
				color: #BADA55;
			}
		</style>
	</head>
	<body>
		<h1 class="foo">Inlining CSS is in</h1>
	</body>
</html>
<!--
	{"time":300,"loadTime":155,"processingTime":145,"requests":[...],"stripped":[...],"cssLength":5050}
-->
Adding an id to the inlined style tag

-i, --css-id [string]

Doing:

dr-css-inliner index.html -i my-inline-css

...would get you:

<!doctype html>
<html>
	<head>
		<title>Foo</title>
		<style id="my-inline-css">
			.foo {
				color: #BADA55;
			}
		</style>
	</head>
	<body>
		<h1 class="foo">Inlining CSS is in</h1>
	</body>
</html>
Piping in HTML content through stdin

-f, --fake-url [string]

If you need to parse HTML that is not yet publicly available you can pipe it into dr-css-inliner. Below is a contrived example (in a real-world example imagine an httpfilter or similar in place of cat):

cat not-yet-public.html | dr-css-inliner -f http://www.mydomain.com/index.html

All loading of assets will be loaded relative to the fake url - meaning they need to be available already.


Changelog

0.9.8

0.9.6

0.9.5

0.9.4

0.9.3

0.9.2

0.9.1

0.9.0

0.8.12

0.8.11

0.8.10

0.8.9

0.8.8

0.8.7

0.8.6

0.8.5

0.8.4

0.8.3

0.8.2

0.8.1

0.8.0

0.7.9

0.7.8

0.7.7

0.7.6

0.7.5

0.7.4

0.7.3

0.7.2

0.7.1

0.7.0

0.6.0

Features:

Changes:

0.5.4

css-inliner bin removed due to not working on unix.