Skip to content

Generating Critical CSS

John D Wells Jr edited this page Apr 20, 2022 · 1 revision

YES, it is possible to generate Critical CSS using DDEV + Vite.

Note that at the time of writing this guide (version 2.3.0 of this starter project), the relevant package versions are as follows:

Credit to Puppeteer Headless Chrome Support and a related PR which attempts to restore Critical CSS functionality for DDEV 1.16+ as well as for Apple's new M1 chips...


Step 1: Configure DDEV

Under the hood (and down the dependency tree!), the Critical plugin relies on Puppeteer, which will not be able to launch the bundled chromium binary from within the web container because of some missing Linux libraries.

Furthermore, for now, the bundled chromium version will not run on Apple Silicon M1 architecture. This recipe provides a workaround to use a native chromium package instead of the one provided by Puppeteer.

You can add chromium support to your ddev project by adding the following extra Debian packages to your config.yaml file:

webimage_extra_packages: [gconf-service, libasound2, libatk1.0-0, libcairo2, libgconf-2-4,
  libgdk-pixbuf2.0-0, libgtk-3-0, libnspr4, libpango-1.0-0, libpangocairo-1.0-0, libx11-xcb1,
  libxcomposite1, libxcursor1, libxdamage1, libxfixes3, libxi6, libxrandr2, libxrender1,
  libxss1, libxtst6, fonts-liberation, libnss3, xdg-utils]

For Apple Silicon M1 support, you will have to override that configuration by adding a config.m1.yaml file in your ddev folder along with the config.yaml one with the following content:

webimage_extra_packages : [chromium]
web_environment:
- CPPFLAGS=-DPNG_ARM_NEON_OPT=0
- PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
- PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true

Step 2: Install Packages

Next, install the rollup-plugin-critical package:

npm i -D rollup-plugin-critical

Step 3: Configure Craft Vite

Add this to your config/vite.php file:

'criticalPath' => '@webroot/dist/criticalcss',
'criticalSuffix' =>'_critical.min.css',

Step 4: Configure Vite

Amend your vite.config.js file to incorporate the following code:

import { defineConfig } from 'vite'
import critical from 'rollup-plugin-critical'

export default defineConfig({
  plugins: [
    critical({
      criticalUrl: 'http://localhost/',
      criticalBase: './web/dist/criticalcss/',
      criticalPages: [
        { uri: '', template: 'index' },
        { uri: 'about', template: 'about/index' },
      ],
      criticalConfig: {},
  }),
  ],
})

Note that we set criticalUrl to http://localhost. This means that your critical CSS will be generated based on your local development environment. You can instead include a fully-qualified URL if you want to generate based on a production URL.

Step 5: Inline Critical CSS in the <head>

Add this somewhere in the <head>:

{{ craft.vite.includeCriticalCssTags() }}

And be sure to call craft.vite.script() with an empty (or true) 2nd parameter, so that any CSS files are loaded async:

{{ craft.vite.script('src/js/app.js') }}

Further instructions are in the Craft Vite docs: https://nystudio107.com/docs/vite/#the-includecriticalcsstags-function


That should be it! Run npm run build from within your container, or make build from outside, to make a production build including critical CSS. 🎉