Defer non-crititcal CSS
edpittol opened this issue · 4 comments
CSS files are render-blocking resource. They impact the page load. So, if the CSS resources is delayed, the page is loaded faster.
The challenge on this technique is to load the critical path CSS (above the fold) style preloaded. If it isn't done, we have a big trouble with Cumulative Layout Shift because the first load will be done without any style.
penthouse is a tool that allow you generate critical path CSS. Supplying the URL and the CSS content of the file, it is possible to get the critical path CSS. If shipped on the environment, it is possible generate the critical path for tests purpose.
Oportunity/Diagnotiscs:
Reference
I created a POC to run the penthouse basic example inner a Docker container.
Start a node container
$ docker run --name poc_puppeteer -it node:lts bash
Install Chrome
Based on https://github.com/buildkite/docker-puppeteer/blob/master/Dockerfile
# apt-get update
# apt-get install -y wget gnupg ca-certificates
# wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
# sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
# apt-get update
# apt-get install -y google-chrome-stable
# rm -rf /var/lib/apt/lists/*
Add penthouse and puppeteer
# yarn init --yes
# yarn add --dev penthouse puppeteer
Commit the image to checkpoint and use on the future
# exit
$ docker commit poc_puppeteer poc_puppeteer
Run the POC
$ docker run -it poc_puppeteer node
> .editor
Paste this script:
const puppeteer = require('puppeteer')
const penthouse = require('penthouse')
// Based on https://github.com/pocketjoso/penthouse/issues/311
browser = puppeteer.launch({
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
'--window-size=1920,1200',
],
defaultViewport: {
width: 1920,
height: 1200,
},
})
// Based on https://github.com/pocketjoso/penthouse#basic-example
penthouse({
url: 'http://google.com',
cssString: 'body { color: red }',
puppeteer: {
getBrowser: () => browser,
}
}).then(criticalCss => {
console.log(criticalCss)
})
Press ctrl + D
to run the script. The output should be:
body{color:red}
How to take a sceenshot using Puppeteer
$ docker run -it -v $(pwd)/puppeteer:/puppeteer --network=wordpress-core-web-vitals-lab_default poc_puppeteer node
> .editor
(async () => {
const puppeteer = require('puppeteer')
const browser = await puppeteer.launch({
ignoreHTTPSErrors: true,
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
'--window-size=1920,1200',
],
defaultViewport: {
width: 1920,
height: 1200,
},
});
const page = await browser.newPage();
await page.goto('https://server');
await page.screenshot({path: '/puppeteer/example.png'});
htlm
await browser.close();
})();
Press ctrl + D to run the script. The screenshot will be on project root puppeteer
directory.
It was created the branch penthouse-poc to facilitate run the POC.
The commands to build and run are:
$ cd penthouse-poc/
$ docker-compose build --pull
$ docker-compose run --rm penthouse index.js
Expected result:
*{box-sizing:border-box}body,html{margin:0}h1{border:10px solid blue;height:100vh;text-align:center;color:blue;margin-top:0;padding-top:40px}
Added server to return the critical CSS and to be processed by WordPress (0aa0f94, db32882).
$ cd penthouse-poc/
$ docker-compose run --rm penthouse yarn install
$ docker-compose up -d penthouse-service
$ curl http://localhost:8080/
*{box-sizing:border-box}body,html{margin:0}h1{border:10px solid blue;height:100vh;text-align:center;color:blue;margin-top:0;padding-top:40px}