Inlining Critical CSS with Symfony and Twig

Inlining critical CSS can provide performance improvements and will achieve better results for Core Web Vital scores.

Issue at Hand

Google will ding you on your performance score if you are not inlining your critical, above-the-fold CSS.

The SASS Dilemma

In most instances we are utilizing SASS/SCSS to compose stylesheets and tool such as WebPack or Gulp to compile CSS. This is great, and we don’t want to eliminate the benefits of using SASS from our workflow, but also, you cannot just stick compiled CSS from sass files into a view. These files are meant to be served as standalone CSS files.

The Workaround

Since we’re using PHP we do have the benefit to include files into views utilizing file_get_contents, so in our view we can add a style tag in the head, and within that, include just the contents of a particular CSS file. In Twig, the source method is equivalent of PHP’s file_get_contents. So for example:

<style>
  {{ source( path to your critical css file ) }}
<style>

Twig Template Directories

By default Twig will only look into the templates directory of your project when including, embedding, or sourcing other ‘templates’. In my case, I’m using WebPack to compile stylesheets and have configured my CSS to build as such:

// webpack.config.js
...
.addStyleEntry('css/critical', './assets/css/critical.scss')
...
// compiles the file to public/build/css/critical.CSS

In order for Twig to source the file from the public directory, we can add a new Twig Namespace as such:

// config/packages/twig.yaml
twig:
    paths:
      '%kernel.project_dir%/public' : 'PUBLIC'

Now we can source the compiled CSS file as such:

<style>
  {{ source('@PUBLIC' ~ '/build/css/critical.css') }}
<style>

Regarding Asset Versioning

If you are using Symfony’s asset component to version/cache your static assets, you’ll need to take this one step further so that the properly versioned file will be grabbed from the manifest:

<style>
  {{ source('@PUBLIC' ~ asset('build/css/critical.css')) }}
<style>

Determining What's Critical CSS

Obviously you can manually pick apart your css to determine what's a critical, however I recommend using a tool such as Penthouse CLI for this.

That’s it!

So in short, you’ll need to:

  1. Determine what is critical.css and create the appropriate SCSS file and import any necessary partials, mixins and variables into that file.
  2. Configure your SASS compiler (WebPack, Gulp, etc.) to compile your critical.css file into the appropriate public directory where you keep stylesheets.
  3. Configure a public namespace in your Twig configuration.
  4. Add the <style> tag to the<head> of all your applicable templates or your base template, using the Twig source method.
  5. If using asset versioning make sure to use the asset method in your path to the critical.css file.