Code Monkey home page Code Monkey logo

critical's Introduction

NPM version Build Status Coverage

critical

Critical extracts & inlines critical-path (above-the-fold) CSS from HTML

Preview

Install

npm i -D critical

Build plugins

Demo projects

Usage

Include:

import {generate} from 'critical';

Full blown example with available options:

generate({
  // Inline the generated critical-path CSS
  // - true generates HTML
  // - false generates CSS
  inline: true,

  // Your base directory
  base: 'dist/',

  // HTML source
  html: '<html>...</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:

generate({
  inline: true,
  base: 'test/',
  src: 'index.html',
  target: 'index-critical.html',
  width: 1300,
  height: 900,
});

Generate critical-path CSS

Basic usage:

generate({
  base: 'test/',
  src: 'index.html',
  target: 'styles/main.css',
  width: 1300,
  height: 900,
});

Generate and minify critical-path CSS:

generate({
  base: 'test/',
  src: 'index.html',
  target: 'styles/styles.min.css',
  width: 1300,
  height: 900,
});

Generate, minify and inline critical-path CSS:

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:

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:

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.
    ...
}).error(err => {
    ...
});

Generate and return output via async function:

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)

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.

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

generate({
  base: 'test/',
  src: 'index.html',
  target: {
    css: 'styles/main.css',
  },
  rebase: {
    from: '/styles/main.css',
    to: '/folder/subfolder/index.html',
  },
});
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
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 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 for details. (https://github.com/pocketjoso/penthouse#usage-1).
ignore array or object undefined Ignore CSS rules. See 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.
request object {} Configuration options for got.
cleanCSS object {level: { 1: { all: true }, 2: { all: false, removeDuplicateFontRules: true, removeDuplicateMediaBlocks: true, removeDuplicateRules: true, removeEmpty: true, mergeMedia: true } }} Configuration options for CleanCSS 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

npm install -g critical

critical works well with standard input.

cat test/fixture/index.html | critical --base test/fixture --inline > index.critical.html

Or on Windows:

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.

critical test/fixture/index.html --base test/fixture > critical.css

Gulp

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 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, 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 node module, which similar to 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 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 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:

License

Apache-2.0 © Addy Osmani, Ben Zörb

critical's People

Contributors

addyosmani avatar andersdjohnson avatar anthonygore avatar bezoerb avatar dependabot[bot] avatar dlubitz avatar fhuitelec avatar gherkz avatar grgur avatar jlukic avatar kentr avatar killercup avatar leifniem avatar leogdion avatar micahblu avatar midzer avatar oskarrough avatar patrikholcak avatar phaistonian avatar pocketjoso avatar rivajunior avatar samccone avatar scrusader avatar sgerrand avatar sindresorhus avatar tamorim avatar tbroadley avatar vladh avatar xhmikosr avatar xty avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

critical's Issues

Don't console.log

Reusable modules put anything implicitly to the stdout/stderr. I you really needed it you could use events or the debug module, but I don't really see the value here, so I would just drop them.

installing github master produces errors

following the advice in the issue regarding the toString errors.. i chose to install the github master version of critical using:

sudo npm install http://github.com/addyosmani/critical/tarball/master

towards the end of the terminal output, i saw more errors:

Received 12854K total.
Extracting tar contents (via spawned process)
Removing /mypath/critical-working/node_modules/critical/node_modules/penthouse/node_modules/phantomjs/lib/phantom
Copying extracted folder /mypath/critical-working/node_modules/critical/node_modules/penthouse/node_modules/phantomjs/phantomjs/phantomjs-1.9.8-linux-x86_64.tar.bz2-extract-1416739729376/phantomjs-1.9.8-linux-x86_64 -> /mypath/critical-working/node_modules/critical/node_modules/penthouse/node_modules/phantomjs/lib/phantom
Removing /mypath/critical-working/node_modules/critical/node_modules/penthouse/node_modules/phantomjs/phantomjs/phantomjs-1.9.8-linux-x86_64.tar.bz2-extract-1416739729376
Writing location.js file
Done. Phantomjs binary available at /mypath/critical-working/node_modules/critical/node_modules/penthouse/node_modules/phantomjs/lib/phantom/bin/phantomjs
npm ERR! Error: ENOENT, chmod '/mypath/critical-working/node_modules/critical/bin/critical'
npm ERR! If you need help, you may report this log at:
npm ERR!     <http://github.com/isaacs/npm/issues>
npm ERR! or email it to:
npm ERR!     <[email protected]>

npm ERR! System Linux 3.17.3-200.fc20.x86_64
npm ERR! command "node" "/bin/npm" "install" "http://github.com/addyosmani/critical/tarball/master"
npm ERR! cwd /mypath/critical-working
npm ERR! node -v v0.10.32
npm ERR! npm -v 1.3.6
npm ERR! path /mypath/critical-working/node_modules/critical/bin/critical
npm ERR! code ENOENT
npm ERR! errno 34
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /mypath/critical-working/npm-debug.log
npm ERR! not ok code 0

i looked into the debug log that is mentioned and did not see any info in there that was helpful to me in diagnosing the cause fo the errors.

Images and Fonts url() path

Hi, my request is about the invalid url path that gets printed out after initialising the critical task. Here is an example of what I am referring to: Lets say I have a "background-image" with destination such as url('../img/someImage.jpg'). In the critical path this will look like url("/components/minified/img/someImage.jpg") which creates invalid request for the browser. The right output for the url should be url("../../public/components/minified/img/someImage.jpg"). My question is how can I get the right url, after starting the critical task ?

Any background images already inlined cause problems with imageinliner

This seems to be an issue with the imageinliner module (I posted note there about this) - in my case, it looks like this that seems to cause the problem - "background-image: url("data:image/svg+xml;base64,PD94bW...")

for the moment, may be that you need to add an option to avoid the imageinliner (line 74 of index.js)

test => fixture

The test folder only contains fixtures, so should probably be named fixture.

CLI

Could be useful.

Getting errors when declaring multiple instances of the critical task

Maybe I'm going about this incorrectly. I have the need to run critical against multiple files. I am using:

// Generate & Inline Critical-path CSS
gulp.task('critical', function () {

    critical.generateInline({
        base: 'dist/',
        src: 'index.html',
        cssPath: 'stylesheets/',
        styleTarget: 'stylesheets/critical.css',
        htmlTarget: 'index.html',
        width: 320,
        height: 480,
        minify: true,
        maxInlineImageSize: 10240
    });
    critical.generateInline({
        base: 'dist/',
        src: 'about.html',
        cssPath: 'stylesheets/',
        styleTarget: 'stylesheets/critical.css',
        htmlTarget: 'about.html',
        width: 320,
        height: 480,
        minify: true,
        maxInlineImageSize: 10240
    });
});

From this I receive:

/Library/WebServer/Documents/WireCash-website/node_modules/critical/node_modules/bluebird/js/main/async.js:93
                throw res.e;
                         ^
TypeError: Cannot call method 'toString' of undefined
    at /Library/WebServer/Documents/WireCash-website/node_modules/critical/index.js:134:30
    at tryCatch1 (/Library/WebServer/Documents/WireCash-website/node_modules/critical/node_modules/bluebird/js/main/util.js:43:21)
    at Promise$_callHandler [as _callHandler] (/Library/WebServer/Documents/WireCash-website/node_modules/critical/node_modules/bluebird/js/main/promise.js:649:13)
    at Promise$_settlePromiseFromHandler [as _settlePromiseFromHandler] (/Library/WebServer/Documents/WireCash-website/node_modules/critical/node_modules/bluebird/js/main/promise.js:663:18)
    at Promise$_settlePromiseAt [as _settlePromiseAt] (/Library/WebServer/Documents/WireCash-website/node_modules/critical/node_modules/bluebird/js/main/promise.js:826:14)
    at Promise$_settlePromises [as _settlePromises] (/Library/WebServer/Documents/WireCash-website/node_modules/critical/node_modules/bluebird/js/main/promise.js:969:14)
    at Async$_consumeFunctionBuffer [as _consumeFunctionBuffer] (/Library/WebServer/Documents/WireCash-website/node_modules/critical/node_modules/bluebird/js/main/async.js:75:12)
    at Async$consumeFunctionBuffer (/Library/WebServer/Documents/WireCash-website/node_modules/critical/node_modules/bluebird/js/main/async.js:38:14)
    at process._tickCallback (node.js:419:13)

Apparently callback methods being passed the String variable criticalCSS are undefined for all subsequent tasks after the first one which is a string as it should be.. Oddly enough all subsequent critical tasks appear to still work, they're just throwing those errors which I circumvented by removing the toString() from the critcialCSS string object which itself is already a string so I'm not sure why those methods were in place.

Is there a standard approach to running the critical task on multiple files? I think it'd be great to be able to run a pattern match like *.html with the htmlTarget by default assuming the same name for each file matched.

toString() errors and more.

Getting toString() errors on two lines, 138 and 219 in index.js

/Library/WebServer/Documents/WireCash-website/node_modules/critical/node_modules/bluebird/js/main/async.js:95
                throw res.e;
                         ^
TypeError: Cannot call method 'toString' of undefined
    at /Library/WebServer/Documents/WireCash-website/node_modules/critical/index.js:138:30

and once I removed the method on 138 I got the same for 219:

/Library/WebServer/Documents/WireCash-website/node_modules/critical/node_modules/bluebird/js/main/async.js:95
                throw res.e;
                         ^
TypeError: Cannot call method 'toString' of undefined
    at /Library/WebServer/Documents/WireCash-website/node_modules/critical/index.js:219:28

Removing toString() from 219, got rid of the error messages, however I'm not getting inlined critical css at all?

My Gulp configuration is below and this is with the latest 0.4.0 release of critical. I'll do some investigating on my end, but wanted to bring attention to the issue.

var gulp = require('gulp'),
    critical = require('critical'),
    fs = require('fs');


// Generate & Inline Critical-path CSS
gulp.task('critical', function () {

    critical.generateInline({
        base: 'dist/',
        src: 'index.html',
        cssPath: 'stylesheets/',
        styleTarget: 'stylesheets/critical.css',
        htmlTarget: 'index.html',
        width: 320,
        height: 480,
        minify: true,
        maxInlineImageSize: 10240
    });
    critical.generateInline({
        base: 'dist/',
        src: 'about.html',
        cssPath: 'stylesheets/',
        styleTarget: 'stylesheets/critical.css',
        htmlTarget: 'about.html',
        width: 320,
        height: 480,
        minify: true,
        maxInlineImageSize: 10240
    });
});

Sample configuration seemingly not working

I'm unable to get htmlTarget to output to a file at all? Seemingly only dest: will do so, though is sans the inline styles. Below is my very simple gulpfile.js. I realize there is a reference to a working sample project, however the gulpfile has a lot going especially for someone brand new to gulp, moving over from grunt and just trying to get a very simple working gulp task going. Thanks for your help

var gulp = require('gulp');
var critical = require('critical');

gulp.task('critical', function() {

    critical.inline({
        base: 'dist',
        src: 'index.html',
        //dest: 'dist/index.html',
        styleTarget: 'stylesheets/styles.css',
        htmlTarget: 'index-inlined.html',
        width: 320,
        height: 480

    }, function (err, output){
        // You now have HTML with inlined critical-path CSS
        // Works with and without dest specified

           // !! This output does not have inlined css? and err is null?
        console.log(err);
        console.log(output);
    });
});

css cache in /tmp folder

Hello,
I have some css files in my /tmp folder

root@mail:~# ls /tmp/
01080730-bf29-482c-81e7-9df3642dffb0.css  33cdb8d7-060e-4f40-b133-61efaad69ad5.css  64664c26-8a37-41c4-b6ff-20331d5a4fea.css  96de35c2-3695-413a-bab2-1b1599161223.css  d69647eb-83e6-41d1-845b-ea677008936d.css
01551406-a16c-4ee7-ae22-a11427a14dca.css  340654fc-2b29-41a0-ac6d-60a104c43145.css  64f3bb03-0114-42d1-a1e7-6190f37fec60.css  971fec66-98c5-419e-919c-4b2b30679c35.css  d7034edd-a330-42cc-8231-3ed8d8560989.css
01c30a3f-befb-4ee3-be6e-6e45c5b2f894.css  34f5ebb6-be29-4af7-a86c-1be8d2a83cba.css  664cc58c-3f1d-4236-a1ad-eb4c20ac7433.css  97f54cd5-ef68-41df-ad73-e35017b79e9e.css  d84dbd3b-5080-4576-b567-c8d4354fafae.css
036df2b0-426e-4f6f-b88a-90a03b3193f2.css  35b4087d-774d-4ad1-ad95-b6b4a7fc8976.css  68a4125f-787c-4430-a12d-be78d1fe6790.css  99fbb948-982f-4b70-a705-17fc6682adba.css  da28124f-bf98-4852-9eb6-a52ae39c1bfc.css
0681cd05-4311-4569-974d-daf856c3f0f5.css  35bc1b74-9d5e-45c6-8c07-22c11e271b38.css  69ed739b-7914-402f-8351-b85b02f5f7ae.css  9a69c184-13fb-4aa9-b79d-13d03bba37bc.css  daac51a4-0625-4885-ad78-56799841d247.css
07d70728-d26b-4579-befb-a7df2341b1e9.css  3677c1b0-19d6-4e7a-8f38-189258894cbf.css  6a88f85a-99f9-414e-969b-0bf25fd5f0f2.css  9afdaab9-3597-4c81-b192-a871e1cdd544.css  dcee70de-e01c-43e0-8343-68ef1182e16a.css
0801a89c-85be-4e95-915c-6ace54e1ba62.css  377d6606-14d7-466b-ba8c-544cdff45b8d.css  6ab62dfc-c6b8-4c54-97e2-23d65e4025da.css  9b8551cb-9c7f-471b-a2da-76f98aeb67e4.css  df07f38a-8eb4-4d16-b0c9-f208385c406f.css
088d78be-9db8-4505-8cf2-27906c268889.css  380b89f2-efc4-433e-849b-14da1767c184.css  6b07faa2-2152-487e-beed-10ea366e1ca3.css  9c2af0c7-2f0a-454e-9a53-4477aa288907.css  df2f655a-fdb8-4bd2-9a2f-ce608f607b58.css
0ca9fdab-3e2c-4c14-bf5b-67724f330b3f.css  384d1fb3-b77e-4461-8c26-bcd2e052ed70.css  6b09cb4c-97fe-4cf7-8f85-133bc2d6443f.css  9e862b89-0d9e-46d7-962a-2367d918e412.css  dfac82d5-752b-4dc1-baca-131924893e19.css
0d43e47a-305f-472f-9136-353308fd0555.css  393fb1dc-6f85-4e00-b816-dc8858851583.css  6bc4ba1a-9241-4575-88fd-7b9ecd3559c2.css  a3562e0b-b552-49b9-b287-08b5b1a83c15.css  dfb0b9fb-6914-43e4-9ccb-5f82c687b5f5.css
0d6e24bc-7ff5-4240-aa62-f30b64575896.css  3b34a247-933b-40e7-a1ae-700004dd4705.css  6bcbef7b-f201-473f-a06b-2475d3d9901f.css  a376640f-41a7-46c1-a328-e935d79090be.css  dfd62398-8482-4b0a-923d-628c7f9f3b72.css
0ff1f79e-7583-458c-a28b-74ac6ce542c0.css  3b879cdd-0e82-41e5-98a5-b9179350f3a0.css  6c3114a4-7115-4f58-874e-c5c1581eb392.css  a4612a3e-b8d1-432a-a0f9-a5012d542f0f.css  e0343b69-183a-4957-b0cc-802daca6d637.css
1075437e-d9e6-4641-8e27-6165a2831686.css  3c95d250-2a8e-4e2a-a25c-7a5590d4a019.css  6d4f87eb-41c2-49b8-b575-91e3a6b24574.css  a468f4ff-dae8-46b9-a399-1aa380efcfd8.css  e0707d4f-303f-420e-84c9-92d7cbc564e5.css
126a2063-faac-44e7-bd4e-8e206d42ba51.css  3cdd2581-6ff8-48e6-946b-2a1d1b6c9eeb.css  6d77088b-1878-4c7a-b826-3668b30d4705.css  a58720e6-e6ee-4e47-bb29-7b6f24faff5b.css  e2e0cc4b-93a7-4f43-ada5-949ec5d93fa3.css
13438749-317f-4e31-bd93-1176d5f05fd5.css  41330db0-7154-4969-bacc-1b588d2650a7.css  6f4b960f-a0bf-47eb-9afd-ddd6e79d14ca.css  a6a0b07b-d80a-42d6-9e41-9dededcd7467.css  e37a504b-6e35-424d-b192-3067890b5273.css
140eaa10-675b-4d6e-92c6-f04161426733.css  45df6ce7-71a1-4b14-b218-ae9835704349.css  72673975-50aa-4ed3-b7cc-95ee9dbe93ad.css  a9a7254d-6df0-45d3-9afb-710dd8a97374.css  e3e04264-4b7c-4d9b-b513-349cb3559c03.css
14373646-4260-4ad7-adfb-709a56f61e61.css  4778eb13-a5e8-4618-befd-57412702e1d0.css  73bb4ae3-25d3-4799-8e40-d006087e5737.css  ab16b0ea-712d-407e-9e6e-9563873a12c4.css  e4f07d8d-d8e7-4bf2-930b-6730ae5b40b7.css
14c7c7d4-26b9-41d3-bd46-c065277c6795.css  48d8c784-7721-4c9d-bc98-304a2d535ea1.css  754d8c4a-ddf6-41c4-ba50-1080f797a91e.css  b123a410-bb7e-4f75-94ba-5b6206fce609.css  e5384c69-feb6-416e-a26a-5c8ddcc1fa28.css
1a5a3fba-9267-40dd-b3e7-a2a4dcc0eccf.css  4974af60-f2b5-49fa-8f6f-b549232abf66.css  77dd51eb-1a5e-4455-b909-5afe2f8195e5.css  b19560bf-c051-44c4-b58a-831374058682.css  e754e5e0-ce82-451c-b192-6ebeededbe1f.css
1a6278b2-02e7-4e0f-ad5d-019aa5fcea2e.css  4adaacc5-e088-4b3e-9707-6d0faa911329.css  784eeee6-46db-43f3-a8fe-3fdc1a30d5fc.css  b2519450-904d-43ff-a614-6a8c888466ba.css  e7bbfe2d-bc39-4ca2-b0d6-7b3f6fd28608.css
1b21485d-c0a4-4bf2-a8fb-e8dfbd0d5146.css  4b1cd8f7-8037-4429-9bfb-1d9897636800.css  7a2d4ee9-6708-4a32-8ece-31e188845946.css  b30ec9b2-0502-4421-8c6c-20077cf45633.css  e85894cc-e4f5-43c7-ba13-f9b2e8b94b59.css
1c10918b-2089-4d96-8312-406944f6255b.css  4b5b1b5c-e74a-45d0-95c5-fc62644f7723.css  7bfdb4ca-cf2c-4159-8d1a-e4436a718ea3.css  b3612811-9967-4198-9af7-063056e322b5.css  ea45254b-2f35-4d18-9be3-eb07d78123e4.css
1c845e8d-8ed4-4f0b-9814-9ee85519d9c6.css  4cd50be3-ef67-40d0-8d86-d983f9f3667b.css  7cb35d0b-9671-424f-86ad-69349dc0bcb3.css  b4427a2e-c0d9-48f6-920a-98e850781f64.css  eaccae61-e6b3-43ce-845e-edb1478f1c63.css
1f6996a9-b44e-469f-bf18-d52e9a190b15.css  4d4bfc4e-a696-49bb-b976-54319a51fb60.css  7da79dbe-8a91-4367-bb65-1c66cd6181e5.css  b71b2b5b-9071-4d2f-84b9-ec5b25c8ddc3.css  ebc8c9a9-5703-4f87-b02f-c1a42eed392c.css
1fe41ccc-4d18-433e-b900-0a1edbe223f0.css  4d632c10-1d58-43d3-8820-3b75f6422e63.css  7ef027e5-1b88-4d33-8f0b-933c1ea421ac.css  b905dd47-d209-417f-841b-3c2a7f2bc654.css  ec35c6d9-f99b-465e-896e-e462376d6fda.css
20017106-21f9-4740-bebe-2b026a95e797.css  50fb8a1c-3f2e-4316-ae1f-7252cb29c6db.css  80c4d8b1-0f32-4d20-832c-0f0678ed7cca.css  ba55ca0e-5e45-4f09-855b-02638b4f3951.css  ec54012c-74ab-417a-ad23-49333dcbdb30.css
20e51be6-0240-4fa5-b30f-78f935a0732d.css  51750742-efd7-4d90-8a2b-382593e941ca.css  82e8ab48-835e-471c-a095-77ecb44bfae8.css  ba59fce5-9f27-4139-ae90-2f654575c62b.css  edf77080-f12a-4776-b065-e0a39bb8801d.css
24231637-94b4-467c-8f9d-a30bbe6aefee.css  53f7a7e1-0125-439f-af56-13b8a9657fc8.css  8490021c-f428-48b4-bef6-512a7f306327.css  bad6928a-4538-467d-82a1-9e656156505d.css  f0db0c9e-3545-4032-a8a5-2bfd409c7c2c.css
24a9ffd2-5aa4-45ef-98fe-754633fbd85b.css  54f629cb-c9e1-45cd-8787-4942590d44c1.css  8532f5e7-1b36-4e7b-8431-14a0a3a84122.css  bbee8599-9b9b-4a5a-af18-4d48bb87e7a8.css  f2df054d-dc76-4596-89f4-be56a3475c9b.css
257c820b-d0a3-4987-a801-3cea8badccd4.css  56b08d82-0932-4c13-8736-98f3362121a9.css  879a2563-9100-4106-a531-d355d5dbe4e0.css  beb6398b-7383-4840-8255-49260b13d0de.css  f397a0b8-2b0a-4543-be5c-c8ee8f011d81.css
27b4079d-d00c-4244-bc8b-ada48b93470b.css  56bb04c3-9994-42c9-985f-f594f377999b.css  8a1dc50a-00e9-4a94-8bbb-6e694f38f44d.css  bfff8fa6-7cc2-4293-8e70-a37cf56cc17b.css  f3af17d7-ca6c-463f-91d4-bade84a3ec1d.css
27c3ca62-c209-44b1-bcc5-0d7d7584b5ec.css  57ec21ba-d135-4fc7-9a92-be97714e4c18.css  8a7581b0-d3a5-4a9e-bc6e-9660ec41a22a.css  c257c97a-6a5e-4e9d-aa9c-07b0a6421f25.css  f4053034-6e46-45af-95a8-e9ca4543424c.css
28d04c61-623d-46a1-aa99-aeec8e3e6c12.css  58473dd7-898c-4572-9e34-28f890893f85.css  8aa78833-337a-4b05-aa21-85ae6042df61.css  c5856c22-0ff4-4cea-8ed8-06fa945ff15c.css  f5b78b0b-1d9f-4c93-90b6-730b7ceb25cc.css
2aa44d03-d44c-491f-a443-cdb7eae252ef.css  58daa896-8675-474b-83b7-1e3ab39dd2b7.css  8b35d01d-30a1-417f-9be7-de7f6f95e191.css  c7439dc4-68aa-4ac3-b45c-5b56494f661d.css  f953f748-6999-4c7f-b0be-d404ef1e688a.css
2ab58b8b-9755-4ccf-9a69-9caa7e17398f.css  5b048158-affc-41b1-95dc-a585acd33f47.css  8b375763-ebce-4a15-b364-db1ac2add5a4.css  c98f6c1e-9828-4106-9efe-50c55387890e.css  fc5cbf38-97d2-4f6d-8f10-a6568e235775.css
2bb31546-1c36-49d0-a93c-660c2a75fda5.css  5b642bd6-4f0f-4da7-9abf-04a4dcc239fb.css  8e347822-a3ee-42e8-9e64-1050627e4418.css  cb730101-320b-4506-9e9e-5a2612366a07.css  fc77811e-4890-4edd-8e61-58ddf8f38193.css
2cd4c771-838c-4611-a0c5-46cf63e51c9b.css  5b9e7b2b-8046-4da2-8acc-a6421d451d57.css  8e38e32c-828e-4925-910e-a8e026ba6ca1.css  cdabb6d1-e8d6-42f4-b728-568ff03ba96d.css  fdfbd6d0-878f-4121-a91e-b3270bd0bf0b.css
..

Move the tmp css file into a .tmp folder?

It appears that critical generates a tmp-.css file in the base directory while it's running. Annoyingly for me, this file is getting picked up on tasks that run after (if chained as a dependency).

It's showing up in my cache manifest file :(

Is there any chance we can get it to generate inside a .tmp folder? At least that way i can set gulp-manifest to ignore that folder.

Default width/height

For the lazy. Find a good default value. Maybe the most popular screen resolution.

Inline: inline the critical-css only

Currently all linked stylesheets are inlined.
This should only be done for the critical-path css.

Maybe the the module could also provide some functionality to diff the critrical-path css and the main css to create a css file with only the remaining css included

load_css script block is output in the HEAD, directly below inlined CSS

Thanks for this project - awesome work.

I'm using gulp to inline the styles

gulp.task('critical', ['styles'], function () {
    critical.generateInline({
        base: 'dist/',
        src: 'index.html',
        styleTarget: 'css/site.css',
        htmlTarget: 'index.html',
        width: 320,
        height: 480,
        minify: true
    }); 
});

but the load_css script block is also output into the head

style:none;margin-left:0;padding-left:0;margin-bottom:20px}.nav-pills>li>a{padding:8px;margin-top:2px;margin-bottom:2px;border-radius:5px;margin-right:2px;line-height:14px}.nav>li>a{display:block}.nav-map a{text-align:center;font-size:.9em}.nav-map a time{display:block;font-size:.8em;font-style:italic}
</style>
<script>
(function(u){function loadCSS(e,t,n){"use strict";function r(){for(var t,i=0;i<d.length;i++)d[i].href&&d[i].href.indexOf(e)>-1&&(t=!0);t?o.media=n||"all":setTimeout(r)}var o=window.document.createElement("link"),i=t||window.document.getElementsByTagName("script")[0],d=window.document.styleSheets;return o.rel="stylesheet",o.href=e,o.media="only x",i.parentNode.insertBefore(o,i),r(),o}for(var i in u){loadCSS(u[i]);}}(['css/style-8994d4f2.css','http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.css']));
</script>
<noscript>
<link rel="stylesheet" href="css/style-8994d4f2.css">
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.css">
</noscript>
</head>

Do I need to do something else to get that script block into the bottom of the body tag?

critical breaks self-closing tags

My use case is an inline svg, where critical removes the closing tag, which causes some problems

eg:
<polygon fill="#DD7B27" points="55.92,7 91.96,61.76 20.24,61.76 "/>

Becomes:
<polygon fill="#DD7B27" points="55.92,7 91.96,61.76 20.24,61.76 ">

Breaks google webfonts when extract: true

For [email protected]

var critical = require('critical');

critical.generateInline({
    // Your base directory
    base: 'dist/',

    // HTML source
    src: 'index.html',

    // Your CSS Files (optional)

    // Viewport width
    width: 320,

    // Viewport height
    height: 480,

    // Target for final HTML output
    htmlTarget: 'index.html',

    // Target for generated critical-path CSS (which we inline)
    //styleTarget: 'app.css',

    // Minify critical-path CSS when inlining
    minify: true,

    // Extract inlined styles from referenced stylesheets
    extract: true
});

The above results in code like:

(function(u){function loadCSS(e,t,n){"use strict";function r(){for(var t,i=0;i<d.length;i++)d[i].href&&d[i].href.indexOf(e)>-1&&(t=!0);t?o.media=n||"all":setTimeout(r)}var o=window.document.createElement("link"),i=t||window.document.getElementsByTagName("script")[0],d=window.document.styleSheets;return o.rel="stylesheet",o.href=e,o.media="only x",i.parentNode.insertBefore(o,i),r(),o}for(var i in u){loadCSS(u[i]);}}(['','','app.686313bf.css']));

When it should really be:

(function(u){function loadCSS(e,t,n){"use strict";function r(){for(var t,i=0;i<d.length;i++)d[i].href&&d[i].href.indexOf(e)>-1&&(t=!0);t?o.media=n||"all":setTimeout(r)}var o=window.document.createElement("link"),i=t||window.document.getElementsByTagName("script")[0],d=window.document.styleSheets;return o.rel="stylesheet",o.href=e,o.media="only x",i.parentNode.insertBefore(o,i),r(),o}for(var i in u){loadCSS(u[i]);}}(['//fonts.googleapis.com/css?family=Questrial','//fonts.googleapis.com/css?family=Sanchez:400italic,400','app.css']));

Turning extract to false solves the problem.

Remove inlined CSS rules from source stylesheets

We could use cave to go through the stylesheets where the critical CSS is pulled from, and "diff" the two, removing critical CSS from the original stylesheets.

e.g:

critical = 'a{color:#f00}'
cave(stylesheet, { css: critical }, saveUpdates)

0.5.7 on npm is missing .stream

I'm not sure what's going on here but the docs and the index.js have .stream, but I just installed the latest from npm and it's not there. The rest of the exported methods are there. 0.5.7 is the version that was installed and that's the version in the package.json on GitHub.

Use larger viewport dimensions in examples

The critical css generated by tools like Penthouse in almost all case works well for all dimensions up to the dimension asked for - but not higher. This means that if you want to cover all grounds, you should ask for the highest possible dimensions you want to include styles for "above the fold" elements for. The downside then is that your critical css will include styles for elements not seen (above the fold) for the majority of your users, which is why Penthouse's default takes the compromise at 1300x900 (yes, quite arbitrary choice).

critical however uses 480x320 in it's examples - which would leave out styles needed for many non mobile viewports. I don't think this a sensible default - we should increase the dimensions specified to 1300x900, or something around there.

Unicode Hex in generated *.html

Generated output for index-critical.html contain Unicode Hex Codes.

gulp critical ->
Instead "Test čeština" it returns "Test &#x10De&#x161tina". Any idea?

Extract:true gives wrong output on absolute paths, and if an external stylesheet is in the markup

NOTE - This was only tested with the new Stream functionality.

Example - Using the new Stream functionality and Extract:true, Gulp is globbing through several HTML files, and some are in subdirectories. In my HTML, my stylesheet path is "/assets/css/app.min.css" (note the slash at the beginning).

This does not work or result in generating multiple partial CSS files, and it doesn't append the appropriate filename to the LoadCSS snippet functions.

Removing the front slash to just "assets/css/app.min.css" MAKES THE WHOLE THING WORK. However, once the files are outputted, the loadCSS is pointing to a relative asset, and this breaks the pages that are inside a subdirectory, since it can't find the CSS there.

to recap - It does work with both absolute and relative paths, as long as you don't use the extract function (which creates its own unique stylesheet per page). If you use extract: true, then it only works with a relative path.

Also, with extract: true, the loadCSS function appends no path for the stylesheet.

Lastly, extract:true also gets hung up if an external stylesheet is defined in the markup.

Bump clean-css

We got an issue over at grunt-critical with conflicting versions of clean-css. See bezoerb/grunt-critical#11

I think bumping clean-css in critical would be the most simple fix for this

Async loaded CSS stylesheets and embedded CSS

So I'm using critical to generate critical path CSS for my website, which I embed into web pages as embedded stylesheets. Then I load the full CSS later on via loadCSS(); All is great so far.

However, I'm using Bootstrap; so let's say there is a Bootstrap declaration such as:

.alert { border-radius: 5px; }

...which gets embedded into my webpage because it's used in the above the fold content.

Further down the page, in below the fold content, I have HTML that looks like this:

 <div class="alert my_alert"></div>

...which the CSS style my_alert being:

 .my_alert { border-radius: 15px; }

So the problem here is that the embedded CSS for "alert" is overriding the "my_alert" style that's applied via my async loaded CSS, so border-radius ends up staying set to 5px;

Is there a way to handle this reasonably?

Tests fail on Windows


> [email protected] test C:\Users\xmr\Desktop\critical
> mocha test.js --timeout 15000

\
....|

  2 passing (2s)
  6 failing

  1)  generates critical-path CSS successfully:
     Uncaught AssertionError: false == true
      at C:\Users\xmr\Desktop\critical\test.js:33:9
      at C:\Users\xmr\Desktop\critical\index.js:60:15
      at C:\Users\xmr\Desktop\critical\node_modules\mocha\node_modules\glob\node_modules\graceful-fs\graceful-fs.js:104:5
      at Object.oncomplete (fs.js:107:15)

  2)  generates minified critical-path CSS successfully:
     Uncaught AssertionError: false == true
      at C:\Users\xmr\Desktop\critical\test.js:47:9
      at C:\Users\xmr\Desktop\critical\index.js:63:13
      at ChildProcess.<anonymous> (C:\Users\xmr\Desktop\critical\node_modules\penthouse\lib\index.js:43:13)
      at ChildProcess.emit (events.js:98:17)
      at Process.ChildProcess._handle.onexit (child_process.js:809:12)

  3)  generates critical-path CSS without writing to disk:
     Uncaught AssertionError: false == true
      at C:\Users\xmr\Desktop\critical\test.js:60:9
      at C:\Users\xmr\Desktop\critical\index.js:63:13
      at ChildProcess.<anonymous> (C:\Users\xmr\Desktop\critical\node_modules\penthouse\lib\index.js:43:13)
      at ChildProcess.emit (events.js:98:17)
      at Process.ChildProcess._handle.onexit (child_process.js:809:12)

  4)  inlines critical-path CSS successfully:
     Uncaught AssertionError: false == true
      at C:\Users\xmr\Desktop\critical\test.js:72:9
      at C:\Users\xmr\Desktop\critical\index.js:92:9
      at C:\Users\xmr\Desktop\critical\node_modules\mocha\node_modules\glob\node_modules\graceful-fs\graceful-fs.js:104:5
      at Object.oncomplete (fs.js:107:15)

  5)  inlines critical-path CSS without writing to disk:
     Uncaught AssertionError: false == true
      at C:\Users\xmr\Desktop\critical\test.js:83:9
      at C:\Users\xmr\Desktop\critical\index.js:95:9
      at fs.js:271:14
      at C:\Users\xmr\Desktop\critical\node_modules\mocha\node_modules\glob\node_modules\graceful-fs\graceful-fs.js:104:5
      at Object.oncomplete (fs.js:107:15)

  6)  inlines and minified critical-path CSS:
     Uncaught AssertionError: false == true
      at C:\Users\xmr\Desktop\critical\test.js:96:9
      at C:\Users\xmr\Desktop\critical\index.js:92:9
      at C:\Users\xmr\Desktop\critical\node_modules\mocha\node_modules\glob\node_modules\graceful-fs\graceful-fs.js:104:5
      at Object.oncomplete (fs.js:107:15)



npm ERR! Test failed.  See above for more details.
npm ERR! not ok code 0

I managed to fix one of the tests by forcing LF. 5 still fail though.

Issues with relative image paths

Relative image paths seem to also be an issue via declared CSS background and background-image properties which unchanged become invalid resources. I was able to get around this via a quick regex replace which, got rid of relative path references ../. Not sure though if this works for all use cases and haven't thoroughly tested it.

Use async fs

Since everything else is async it would be too bad to destroy the async with a sync call. Use fs.writeFile/fs.readFile instead.

CLI: Error path must be a string

Using this example from the README:

critical test/fixture/index.html --base test/fixture > critical.css
  Error: path must be a string

Critical fails if you include Google Webfonts in the header

I'm currently playing around with Critical and I ran into this problem, whenever I have a Google Webfonts in the header Critical crashes. I just straight copied from the first Gulp example and this is what I have in the header:

<link rel="stylesheet" href="/assets/stylesheets/screen.css">
<link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Merriweather:300,700,700italic,300italic|Open+Sans:700,400" />

And when I then run the gulp critical task I get this error:

 gulp critical                                                                                                                                                                                              site/git/master !
[23:20:42] Using gulpfile ~/path/to/site/gulpfile.js
[23:20:42] Starting 'copy:css'...
[23:20:42] Finished 'copy:css' after 19 ms
[23:20:42] Starting 'critical'...
[23:20:42] 'critical' errored after 209 ms
[23:20:42] Error: ENOENT, open 'site/fonts.googleapis.com/css?family=Merriweather:300,700,700italic,300italic|Open+Sans:700,400'

/path/to/site/node_modules/critical/node_modules/bluebird/js/main/async.js:93
                throw res.e;
                         ^
TypeError: Cannot call method 'toString' of undefined

Any kind of solution for this? Thanks!

simplify usage of critical

@addyosmani
While implementing some tests for the CLI i've stumbled across parameter inconsistence between generate and generateInline. For generateInlinewe use styleTarget and htmlTarget and for generatewe only use dest. This could be a bit confusing.
Maybe we should consider deprecating the options styleTarget and htmlTarget in favor of just using dest and and select the right task based upon the filetype

  • html: generateInline
  • css: generate

With this is mind we could also strip down generateand generateInline because then only one public method is needed for either generate and inline to produce html or for just generating the critical css. What do you think?

SVG Images in the HTML Broken After Critical

Hello all,

I am having an interesting issue in my latest project. When I trigger Critical to inject the critical styles in my html (dest: '_site/index.html') it breaks my SVG logo image.
Here is the image before:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 563 87.9" enable-background="new 0 0 563 87.9" xml:space="preserve" width="167px" height="26px" fill="#fff">
    <g>
        <g>
            <path d="M137.6,23.6h-15.7v-3.1h34.8v3.1H141v42h-3.3V23.6z"/>
            <path d="M173.3,20.5h18.9c5.5,0,10,1.7,12.7,4.4c2.1,2.1,3.4,5.1,3.4,8.4v0.1c0,7.5-5.6,11.8-13.2,12.9L210,65.6h-4.2l-14.4-18.7h-0.1h-14.6v18.7h-3.3V20.5z M191.8,43.9c7.5,0,13.1-3.8,13.1-10.3v-0.1c0-6-4.8-9.8-12.9-9.8h-15.4v20.3H191.8z"/>
            <path d="M225.6,46.9V20.5h3.3v26c0,10.6,5.7,16.7,15.3,16.7c9.1,0,15-5.5,15-16.4V20.5h3.3v25.9c0,12.9-7.5,19.8-18.5,19.8C233.2,66.3,225.6,59.5,225.6,46.9z"/>
            <path d="M281.6,20.5h32.1v3.1H285v17.7h25.8v3.1H285v18.1h29v3.1h-32.4V20.5z"/>
            <path d="M326.1,20.5H337l11.8,31.7l11.8-31.7h10.7L353,65.9h-8.8L326.1,20.5z"/>
            <path d="M393.6,20.2h9.1l19.3,45.4h-10.4l-4.1-10.1h-19.1l-4.1,10.1h-10.1L393.6,20.2z M404.1,46.7l-6-14.6l-6,14.6H404.1z"/>
            <path d="M433.2,46.3V20.5h9.9V46c0,7.3,3.7,11.1,9.7,11.1c6.1,0,9.7-3.7,9.7-10.8V20.5h9.9V46c0,13.6-7.7,20.3-19.8,20.3C440.6,66.3,433.2,59.5,433.2,46.3z"/>
            <path d="M489,20.5h9.9v36h22.5v9H489V20.5z"/>
            <path d="M539.3,29.7h-13.7v-9.1H563v9.1h-13.7v35.9h-9.9V29.7z"/>
        </g>
        <g>
            <path d="M63.9,17.6H35.5L22.8,36.5l26.8,26.5l26.8-26.6L63.9,17.6z M60.1,41.1l-0.5,1l-0.4,0.6l-0.7-0.4l-6.7-3.7c-0.6,0.6-1.4,0.9-2.3,0.9c-0.9,0-1.7-0.3-2.3-0.9l-6.7,3.7L40,42.7l-0.4-0.6l-0.5-1l-0.4-0.7l0.7-0.4l6.9-3.8c0,0,0,0,0,0c0-1.3,0.8-2.5,2-3v-7v-0.7H49h1.1h0.7v0.7v7c1.2,0.5,2.1,1.7,2.1,3.1c0,0,0,0,0,0l6.9,3.8l0.7,0.4L60.1,41.1z"/>
            <path d="M73.3,0H26.1L0,38.8l49.6,49.1L99,38.8L73.3,0zM49.6,67.8L18.5,37l15.3-22.7h31.9l15,22.6L49.6,67.8z"/>
        </g>
    </g>
</svg>

And here is the image after:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewbox="0 0 563 87.9" enable-background="new 0 0 563 87.9" xml:space="preserve" width="167px" height="26px" fill="#fff">
    <g>
        <g>
            <path d="M137.6,23.6h-15.7v-3.1h34.8v3.1H141v42h-3.3V23.6z">
            <path d="M173.3,20.5h18.9c5.5,0,10,1.7,12.7,4.4c2.1,2.1,3.4,5.1,3.4,8.4v0.1c0,7.5-5.6,11.8-13.2,12.9L210,65.6h-4.2l-14.4-18.7h-0.1h-14.6v18.7h-3.3V20.5z M191.8,43.9c7.5,0,13.1-3.8,13.1-10.3v-0.1c0-6-4.8-9.8-12.9-9.8h-15.4v20.3H191.8z">
            <path d="M225.6,46.9V20.5h3.3v26c0,10.6,5.7,16.7,15.3,16.7c9.1,0,15-5.5,15-16.4V20.5h3.3v25.9c0,12.9-7.5,19.8-18.5,19.8C233.2,66.3,225.6,59.5,225.6,46.9z">
            <path d="M281.6,20.5h32.1v3.1H285v17.7h25.8v3.1H285v18.1h29v3.1h-32.4V20.5z">
            <path d="M326.1,20.5H337l11.8,31.7l11.8-31.7h10.7L353,65.9h-8.8L326.1,20.5z">
            <path d="M393.6,20.2h9.1l19.3,45.4h-10.4l-4.1-10.1h-19.1l-4.1,10.1h-10.1L393.6,20.2z M404.1,46.7l-6-14.6l-6,14.6H404.1z">
            <path d="M433.2,46.3V20.5h9.9V46c0,7.3,3.7,11.1,9.7,11.1c6.1,0,9.7-3.7,9.7-10.8V20.5h9.9V46c0,13.6-7.7,20.3-19.8,20.3C440.6,66.3,433.2,59.5,433.2,46.3z">
            <path d="M489,20.5h9.9v36h22.5v9H489V20.5z">
            <path d="M539.3,29.7h-13.7v-9.1H563v9.1h-13.7v35.9h-9.9V29.7z">
        </g>
        <g>
            <path d="M63.9,17.6H35.5L22.8,36.5l26.8,26.5l26.8-26.6L63.9,17.6z M60.1,41.1l-0.5,1l-0.4,0.6l-0.7-0.4l-6.7-3.7c-0.6,0.6-1.4,0.9-2.3,0.9c-0.9,0-1.7-0.3-2.3-0.9l-6.7,3.7L40,42.7l-0.4-0.6l-0.5-1l-0.4-0.7l0.7-0.4l6.9-3.8c0,0,0,0,0,0c0-1.3,0.8-2.5,2-3v-7v-0.7H49h1.1h0.7v0.7v7c1.2,0.5,2.1,1.7,2.1,3.1c0,0,0,0,0,0l6.9,3.8l0.7,0.4L60.1,41.1z">
            <path d="M73.3,0H26.1L0,38.8l49.6,49.1L99,38.8L73.3,0zM49.6,67.8L18.5,37l15.3-22.7h31.9l15,22.6L49.6,67.8z">
        </g>
    </g>
</svg>

Notice how by the end of each path element in the input we have a self closing tag "/>". However in the output the self closing tag is transformed to just ">", without the "/" and unfortunately the SVG is messed up :(

Can somebody help me?

Thanks in advance,
Kalo.

no output / errors / processing occurs when running a simple critical task

i have created a gulpfile.js within my working folder here, which contains:

// Include gulp
var gulp = require('gulp'); 
var critical = require('critical');

// Generate Critical-path CSS
gulp.task('critical', function (cb) {
    critical.generate({
        base: '/',
        src: 'mypage.html',
        dest: 'styles/main.css',
        width: 320,
        height: 480
    });
});

and i have (as far as i am aware) correctly installed the github master project for critical, as well as gulp, node and npm.
i have just tested by adding the optional 'css' config variable into the critical task function too - though this didn't make any difference either.

i'm out of ideas here, does anyone know what i might be missing?
the output of the terminal is:

$ gulp critical
[11:04:36] Using gulpfile /mypath/critical-working/gulpfile.js
[11:04:36] Starting 'critical'...

*Ignore

Is there any way to ignore specific css or images/fonts in the inlined css.

For example, I have a font that gets inserted into the inlined critial css due to it being part of an icon in the header. I don't want the font to load at all, until the page has loaded.

Is there anyway to make criticalcss ignore specific files for include?

Getting errors when declaring multiple instances of the critical task

Maybe I'm going about this incorrectly. I have the need to run critical against multiple files. I am using:

// Generate & Inline Critical-path CSS
gulp.task('critical', function () {

    critical.generateInline({
        base: 'dist/',
        src: 'index.html',
        cssPath: 'stylesheets/',
        styleTarget: 'stylesheets/critical.css',
        htmlTarget: 'index.html',
        width: 320,
        height: 480,
        minify: true,
        maxInlineImageSize: 10240
    });
    critical.generateInline({
        base: 'dist/',
        src: 'about.html',
        cssPath: 'stylesheets/',
        styleTarget: 'stylesheets/critical.css',
        htmlTarget: 'about.html',
        width: 320,
        height: 480,
        minify: true,
        maxInlineImageSize: 10240
    });
});

From this I receive:

/Library/WebServer/Documents/WireCash-website/node_modules/critical/node_modules/bluebird/js/main/async.js:93
                throw res.e;
                         ^
TypeError: Cannot call method 'toString' of undefined
    at /Library/WebServer/Documents/WireCash-website/node_modules/critical/index.js:134:30
    at tryCatch1 (/Library/WebServer/Documents/WireCash-website/node_modules/critical/node_modules/bluebird/js/main/util.js:43:21)
    at Promise$_callHandler [as _callHandler] (/Library/WebServer/Documents/WireCash-website/node_modules/critical/node_modules/bluebird/js/main/promise.js:649:13)
    at Promise$_settlePromiseFromHandler [as _settlePromiseFromHandler] (/Library/WebServer/Documents/WireCash-website/node_modules/critical/node_modules/bluebird/js/main/promise.js:663:18)
    at Promise$_settlePromiseAt [as _settlePromiseAt] (/Library/WebServer/Documents/WireCash-website/node_modules/critical/node_modules/bluebird/js/main/promise.js:826:14)
    at Promise$_settlePromises [as _settlePromises] (/Library/WebServer/Documents/WireCash-website/node_modules/critical/node_modules/bluebird/js/main/promise.js:969:14)
    at Async$_consumeFunctionBuffer [as _consumeFunctionBuffer] (/Library/WebServer/Documents/WireCash-website/node_modules/critical/node_modules/bluebird/js/main/async.js:75:12)
    at Async$consumeFunctionBuffer (/Library/WebServer/Documents/WireCash-website/node_modules/critical/node_modules/bluebird/js/main/async.js:38:14)
    at process._tickCallback (node.js:419:13)

Apparently callback methods being passed the String variable criticalCSS are undefined for all subsequent tasks after the first one which is a string as it should be.. Oddly enough all subsequent critical tasks appear to still work, they're just throwing those errors which I circumvented by removing the toString() from the critcialCSS string object which itself is already a string so I'm not sure why those methods were in place.

Is there a standard approach to running the critical task on multiple files? I think it'd be great to be able to run a pattern match like *.html with the htmlTarget by default assuming the same name for each file matched.

Access html via http?

Love this module, however a lot of sites are sourced from templates. This means an additional step of curl-ing the rendered html to disk and then using that as the source for the module. This creates some added complexity that would prevent a lot of folks from using it. Since fs.readFile is async anyhow, would you be open to allowing sourcing the html from the network as opposed to the disk? I can send in a PR if so.

Consider all CSS files

At this time only the first stylesheet gets processed. The critical CSS should be fetched from all linked stylesheets

Backslashes in output url()s on Windows

When rebasing urls starting with ../, backslash is used as a path separator.

For example background-image:url(../img/sprite.png); in my original stylesheet is translated to background-image:url(\img\sprite.png);, which results in an incorrect request for /imgsprite.png, instead of /img/sprite.png.

Base url

Hello. my site is available at this URL - somedomain.com/sometext/my-site/, so when after work critical"
path to the picture is not correct. Tell me what can I do?

Option for specific CSS files?

Since it grabs all link elements and inlines them, what if there was an option to include only specified css files you want inlined?

I use a noscript async fallback for css and critical inlines that :(

Critical CSS and CSS animations / Bootstrap Carousel

I've been using and loving grunt-critical, thank you!

I do have one issue that I can't quite figure out. I have a site that has critical CSS for all of the pages, and it works great... but for pages that have CSS animations on them in form of Twitter Bootstrap carousel animations it's not quite doing the trick.

Here's an example URL:

http://www.onlinelandusa.com/listings/colorado-land-6.458-acres-with-a-driveay-and-cleared-level-area

There some CSS in there that critical isn't picking up on, because PageSpeed Insights says:

"Approximately 19% of the above-the-fold content on your page could be rendered without waiting for the following resources to load. Try to defer or asynchronously load blocking resources, or inline the critical portions of those resources directly in the HTML.

http://cssjs.onlinelandusa.net/site_assets/css/site.combined.min.css"

Somehow critical isn't picking up on all of the CSS that needs to be rendered, so it has to wait to load the full CSS file before it can render the above-the-fold content. There is a similar result on an even simpler page:

http://www.onlinelandusa.com/site/about-us

...that just has one carousel animation on it, so I'm assuming that's what is doing it. You can see the extracted critical CSS here:

http://www.onlinelandusa.com/site/css/about_us_critical.min.css

Multiple src files

Hello guys, awesome work and great plugin.
Is there any way for specifying multiple source files ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.