-
-
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); | |
})(); |
@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
@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?
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.
The function getMatchedCSSRules does not work anymore. Long time it was deprecated and now it is removed. Does someone knows a replacement?
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
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.
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
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.
@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.
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.
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?