aztecweb / wordpress-core-web-vitals-lab

Laboratory to test diagnostics and opportunities to improve Core Web Vitals metrics on WordPress ecosystem.
GNU General Public License v2.0
3 stars 1 forks source link

Defer non-crititcal CSS #1

Open edpittol opened 3 years ago

edpittol commented 3 years ago

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

edpittol commented 3 years ago

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}
edpittol commented 3 years ago

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.

edpittol commented 3 years ago

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}
edpittol commented 3 years ago

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}