Skip to content

Instantly share code, notes, and snippets.

@PaulKinlan
Last active March 15, 2023 02:13
Show Gist options
  • Save PaulKinlan/6283739 to your computer and use it in GitHub Desktop.
Save PaulKinlan/6283739 to your computer and use it in GitHub Desktop.
Detect Critical CSS
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<h2>Original CSS</h2>
<style style="display: block; white-space: pre; font-family: monospace">
h2 { margin:0; }
ol { color:red; }
li { color:blue; background-color: red; }
li:hover { color:purple; background-color: red; }
li:first-child { color:green; background-color: yellow; }
@media (max-width:512px) {
li:first-child { color: cyan; background-color: lime; }
}
li:last-child { color:pink; background-color: blue; }
</style>
<h2>Critical CSS</h2>
<pre id=output></pre>
<p>Note the last-child is not in the output because it is not visible (unless you have a huge monitor, in which case, shame on you, shrink your window).</p>
<ol>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
<li>TEST</li>
</ol>
</body>
</html>
// noprotect
var CSSCriticalPath = function(w, d) {
var css = {};
var pushCSS = function(r) {
// The last selector wins, so over-write
// merging existing css will happen here...
css[r.selectorText] = r.cssText;
};
var parseTree = function() {
// Get a list of all the elements in the view.
var height = w.innerHeight;
var walker = d.createTreeWalker(d.body, 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) {
// element is in the first scroll of the screen
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 += css[k] + "\n";
}
return finalCSS;
};
parseTree();
};
window.onload = function() {
var cp = new CSSCriticalPath(window, document);
var css = cp.generateCSS();
output.innerText = css;
};
@jakobjh
Copy link

jakobjh commented Oct 6, 2016

Hi Paul.
The function getMatchedCSSRules is deprecated. Do you have a solution for that?

BR Jakob

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