I found myself creating critical CSS client libraries for an Adobe Experience Manager project as part of a series of performance improvements recently.
What is Critical CSS?
Historically, web site performance has been mainly focussed on server rendering and database query optimisation; but in 2020, front end performance is critical to the success of any website. SEO optimisation is no longer simply focussed on getting the right content and links in place — speed of rendering is a key metric to track and improve.
Some of these KPIs are met by prioritising the rendering of aspects of a page that the user will see first. This typically is the top part of the page, also known as “above the fold”. Since the whole stylesheet isn’t needed to display this part of the page, it is wasteful to synchronously load the whole set of rules. This is especially key, since loading CSS is a render block action, and prevents anything else happening.
Identifying the specific rules that are necessary to render the above the fold content is not a trivial task. These specific rules are known as critical CSS, and best practice is to load this small subset of rules synchronously and then load the remaining rules (non-critical) asynchronously.
Auto Generating the Critical CSS
Fortunately, browsers are pretty good at working out which rules are critical, and the Penthouse npm module can be incorporated into build processes.
The problem is that the underlying technology, Puppeteer uses headless Chromium to generate the critical CSS, which was running just fine locally as part of the Maven project build, and on the self managed Jenkins instance, but was failing inside the Adobe Cloud Manager build environment:
[emitted] (node:2509) UnhandledPromiseRejectionWarning: Error: Failed to launch the browser process!
10:36:24,006 [Exec Stream Pumper] [INFO] /build_root/build/project/ui.frontend/src/main/frontend/node_modules/puppeteer/.local-chromium/linux-722234/chrome-linux/chrome: error while loading shared libraries: libX11-xcb.so.1: cannot open shared object file: No such file or directory