Generating Critical CSS
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:
-
DDEV
1.19
-
Vite
2.9.5
-
Craft Vite
1.0.24
-
rollup-plugin-critical
1.0.8
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...
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
Next, install the rollup-plugin-critical package:
npm i -D rollup-plugin-critical
Add this to your config/vite.php
file:
'criticalPath' => '@webroot/dist/criticalcss',
'criticalSuffix' =>'_critical.min.css',
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.
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. 🎉