-
-
Save PaulKinlan/6284142 to your computer and use it in GitHub Desktop.
(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); | |
})(); |
Just tried DirkPersky's bookmarklet. It works. Thanks!
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?
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.
On Windows 10 with Crome 83.0.... the Bookmarklet works.
Maybe update your Chrome.
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
@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 =)
using it:
open the developer console, on you site and press the bookmark button in yout browser an wait for it ;)
Thanks DirkPersky! Please forgive my ignorance . . . what page am I bookmarking? This one (the one I am commenting on?)
@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 =)
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....
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.
I get Uncaught TypeError: w.getMatchedCSSRules is not a function
, using Chrome
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.
I was able to get it working by replacing getMatchedCSSRules
with the script below. However doesn't work if css is from a different domain.
var getCSS = function(el) {
var sheets = document.styleSheets, ret = [];
el.matches = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector
|| el.msMatchesSelector || el.oMatchesSelector;
for (var i in sheets) {
var rules;
try {
rules = sheets[i].rules;
} catch {
console.log("Error reading rules: ");
try{
rules = sheets[i].cssRules;
} catch {
console.log("Error reading cssRules: ");
}
}
```
this library is probably the way to go: https://www.brothercake.com/site/resources/scripts/cssutilities/
Your example script was not complete, but I imagine the rest of the way you'd do it is to test the element against each rule to see whether it matches.
@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.