Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
CriticalCSS Bookmarklet and Devtool Snippet.js
(function() {
var CSSCriticalPath = function(w, d, opts) {
var opt = opts || {};
var css = {};
var pushCSS = function(r) {
if(!!css[r.selectorText] === false) css[r.selectorText] = {};
var styles = r.style.cssText.split(/;(?![A-Za-z0-9])/);
for(var i = 0; i < styles.length; i++) {
if(!!styles[i] === false) continue;
var pair = styles[i].split(": ");
pair[0] = pair[0].trim();
pair[1] = pair[1].trim();
css[r.selectorText][pair[0]] = pair[1];
}
};
var parseTree = function() {
// Get a list of all the elements in the view.
var height = w.innerHeight;
var walker = d.createTreeWalker(d, NodeFilter.SHOW_ELEMENT, function(node) { return NodeFilter.FILTER_ACCEPT; }, true);
while(walker.nextNode()) {
var node = walker.currentNode;
var rect = node.getBoundingClientRect();
if(rect.top < height || opt.scanFullPage) {
var rules = w.getMatchedCSSRules(node);
if(!!rules) {
for(var r = 0; r < rules.length; r++) {
pushCSS(rules[r]);
}
}
}
}
};
this.generateCSS = function() {
var finalCSS = "";
for(var k in css) {
finalCSS += k + " { ";
for(var j in css[k]) {
finalCSS += j + ": " + css[k][j] + "; ";
}
finalCSS += "}\n";
}
return finalCSS;
};
parseTree();
};
var cp = new CSSCriticalPath(window, document);
var css = cp.generateCSS();
console.log(css);
})();
@pocketjoso
Copy link

pocketjoso commented Jun 5, 2014

I built my own CriticalCSS Generator to solve these issues, something I can use for production. You can check it out here if you're interested:

https://github.com/pocketjoso/penthouse

Thanks for the inspiration!

@shidhincr
Copy link

shidhincr commented Sep 30, 2014

Hey @PaulKinlan @pocketjoso

Is there any solution available for CDN served css files ?

@cleberdantas
Copy link

cleberdantas commented Jan 19, 2015

I put this script inside a CLI tool (Node) running on top of PhantomJS.

https://github.com/cleberdantas/atf

It's good for some automations.

Thanks for de original idea @PaulKinlan

@amityweb
Copy link

amityweb commented May 7, 2015

Doesn't work for me in Chrome. I made it into a Bookmarklet using http://chriszarate.github.io/bookmarkleter/

Edit: Ok this gives it away console.log(css); - i can see it now :)

@amityweb
Copy link

amityweb commented May 7, 2015

Doesn't grab ALL the critical CSS for us... leaves out our header menu, so we get a flash of unstyled content, mainly the header menu

@mihawk90
Copy link

mihawk90 commented May 13, 2015

Just found this gem, works really well :)

When executing, I get this warning however:

'getMatchedCSSRules()' is deprecated. For more help, check https://code.google.com/p/chromium/issues/detail?id=437569#c2

@amityweb I suspect it has it has something to do with the positioning of the elements, as it works fine for me on my current project (with a fixed header nav)

@mpiontek
Copy link

mpiontek commented Aug 14, 2015

Not working for me :( http://neu.contur-online.de/de/index.php . After fill in only the 'critical path css', your tool gives me, the page is showing up wrong

@ctorx
Copy link

ctorx commented Aug 20, 2015

It seems the getMatchCSSRules function is expecting 2 arguments. Calling it with an empty string kills the deprecated message and still works as expected.

var rules = w.getMatchedCSSRules(node, '');

@vuquangchien
Copy link

vuquangchien commented Sep 12, 2015

It doesn't work for media query and responsive websites. I tried with Bootstrap (http://getbootstrap.com/examples/theme/). Is there any way to make it work with Bootstrap?

@james-Ballyhoo
Copy link

james-Ballyhoo commented Sep 18, 2015

@vuquangchien, this might be of use (I based it off Paul's code when we also hit the media queries issue) https://gist.github.com/james-Ballyhoo/04761ed2a5778c505527

@alirabet
Copy link

alirabet commented Mar 10, 2016

@james-Ballyhoo I tested it, It didn't work well on default brower on Android. It works well on chrome 👍 Can you fix it for all browers?

@verkaro
Copy link

verkaro commented Sep 9, 2016

non-techie reporting: this doesn't work with chromium-browser in Ubuntu 16.10 -- but running under google's chrome download worked. thanks for the work you've done.

@MiFreSu
Copy link

MiFreSu commented Jun 2, 2017

The function getMatchedCSSRules does not work anymore. Long time it was deprecated and now it is removed. Does someone knows a replacement?

@alexlii1971
Copy link

alexlii1971 commented Jan 22, 2018

Hello,

Someone wrote a plugin as per your code:
Generate Critical CSS at https://wordpress.org/plugins/generate-critical-css/

but that plugin is out to update, would like to update it?

As per suggestion from google page speed insight, we need generate critical css, some plugins (https://wordpress.org/plugins/above-the-fold-optimization/) only handle optimize, but not handle generate those css.

Anyone would like to update those wordpress' plugin?

Alex

@optimalisatie
Copy link

optimalisatie commented Jan 24, 2018

Hi!

Thanks a lot for this snippet!

getMatchedCSSRules will be removed in Chrome 63.

We have created an improved snippet based on this concept that includes a polyfill for getMatchedCSSRules to support more browsers, including Firefox.

https://docs.style.tools/critical-css-generator

@DirkPersky
Copy link

DirkPersky commented Oct 9, 2018

Hi!

i modidyed the snippet for the latest Chrome, and testet it a lot of Times!
If you need the Bookmarklet version you can copy it

https://github.com/DirkPersky/criticalcss

@CameronKnowlton
Copy link

CameronKnowlton commented Mar 12, 2019

hi DirkPersky , I wasn't able to get your https://github.com/DirkPersky/criticalcss bookmarklet working in Chrome 72 Mac... should it be working? I tried it on several URLs, nothing happens (e.g. https://www.nytimes.com/ ). Thanks for your work on this.

@wuworkshop
Copy link

wuworkshop commented Mar 22, 2019

@CameronKnowlton I just tried https://github.com/DirkPersky/criticalcss on the NY Times site and it worked for me in Chrome Canary Version 75.0.3740.0 macOS 10.13.6. The generated critical CSS is displayed in the console in DevTools.

@oopix-jane
Copy link

oopix-jane commented Oct 25, 2019

Just tried DirkPersky's bookmarklet. It works. Thanks!

@fisiculturista
Copy link

fisiculturista commented Jun 24, 2020

Hello, Paul Kilan's code pops an error and DirkPerky's code does nothing. Anyone knows a working script to run on Chrome console to extract the critical css?

@fisiculturista
Copy link

fisiculturista commented Jun 24, 2020

hi DirkPersky , I wasn't able to get your https://github.com/DirkPersky/criticalcss bookmarklet working in Chrome 72 Mac... should it be working? I tried it on several URLs, nothing happens (e.g. https://www.nytimes.com/ ). Thanks for your work on this.

Same issue here. Nothing happens.

@DirkPersky
Copy link

DirkPersky commented Jun 26, 2020

On Windows 10 with Crome 83.0.... the Bookmarklet works.
Maybe update your Chrome.

@fisiculturista

@gatehealing
Copy link

gatehealing commented Jul 6, 2020

Hi, I was sent here via the Autoptimize plugin FAQ. I have no clue how to use this to generate critical/above the fold CSS for the inline and defer css field of AO. Using another critical css generator I am getting the flash of unoptimized code (something like that). Could somebody please point me in the right direction of how to use this tool to extract (*the FAQ link points to this page)
Thanks!
Jon

@DirkPersky
Copy link

DirkPersky commented Jul 6, 2020

@gatehealing you create a new bookmark, and copy all javascript code from my https://github.com/DirkPersky/criticalcss/blob/master/bookmark.js into that field like the screenshot =)
image

using it:
open the developer console, on you site and press the bookmark button in yout browser an wait for it ;)
image

@gatehealing
Copy link

gatehealing commented Jul 6, 2020

Thanks DirkPersky! Please forgive my ignorance . . . what page am I bookmarking? This one (the one I am commenting on?)

@DirkPersky
Copy link

DirkPersky commented Jul 6, 2020

@gatehealing Non of both! Only create a new bookmark, but instead of adding a url to it, copy the content of my javascript and paste it to the url =)

image

@gatehealing
Copy link

gatehealing commented Jul 6, 2020

got it! Now what I see is not wrapped in <style></style> tags, and I believe I am supposed to put what is wrapped in those style tags in the AO inline and defer css box. I don't want to crash my site (which I have managed to do before on things like this), so I want to be sure I have extracted the correct code to put in that AO field....

@lewisje
Copy link

lewisje commented Aug 6, 2020

FWIW I also made a version of the bookmarklet, and I even accounted for some cases where the cssRules or rules property threw an error on access.

@gillespieza
Copy link

gillespieza commented Sep 23, 2021

I get Uncaught TypeError: w.getMatchedCSSRules is not a function , using Chrome

@lewisje
Copy link

lewisje commented Sep 23, 2021

I get Uncaught TypeError: w.getMatchedCSSRules is not a function , using Chrome

My re-fashioning used a polyfill for that; getMatchedCSSRules was never standardized, and it was removed from Chrome starting with version 63.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment