Roots Discourse

Asynchronous CSS Loading in Sage


Originally published at:

Why load CSS asynchronously? All stylesheets are render-blocking by nature. Meaning that referencing CSS stylesheets with <link rel="stylesheet"> causes the browser to stop parsing the HTML and wait while a stylesheet loads. This is bad for performance and will trigger warnings on all page speed tests. Asynchronous CSS automation The new <link rel="preload"> attribute allows…



Great guide, just what I was looking for! thank you @jasonbaciulis.

However, I’m getting a FatalThrowableError: Call to a member function setAttribute() on null on the $tag->setAttribute('rel', 'preload') line for the Async load CSS filter.

$dom and $tag vars look like this on that line. Am I missing something? Sorry if it’s a dumb question, but I’m kinda new to this:

Thanks for your help and this awesome guide!



Try debugging a $handle and $html values. It looks like $handle is missing on some tag and maybe you can pinpoint which <link> tag is loaded at that time.



Found it! The clean_style_tag function on Soil removes ids from style tags, so getElementById($handle . '-css') returns null.

Solved it by disabling add_theme_support('soil-clean-up'), though I’m loosing all the other goodies from Soil’s clean up :stuck_out_tongue:



Good catch. So it’s something to be aware with other optimization plugins as well that might remove ids.

You could try calling async CSS earlier before Soil. Just need to find out what priority Soil is using and reduce the number from 999.



When i test this local it works fine but after deploying it to staging I got a http server 500 error. any idea? Still got the error “FatalThrowableError: Call to a member function setAttribute() on null” even if I disable soil-clean-up or decrease the priority of the filter to , for example , 10

hmmm getElementByID seems to bee ‘null’??



You mentioned it works in your local env, so try to pinpoint the differences between environments. Maybe there are additional plugins running on staging that could be removing ids?



Unfortunately, no result looks like the setups are similar. Only difference was W3 Total cache, which was disabled on local env . but disabling this on staging did not solve the issue.



What might be the modifications necessary – made to the filter and polyfill scripts – to only enable async CSS for specific stylesheets.

The reason I ask is because I have a specific project with javascript firing that will conflict with inline styling. I need certain stylesheets to load on page-load (without being inlined), and others to load in the background.



I’m having an issue when using your tutorial. Everything appears to work correctly except, I get the following error on the console.

Uncaught (in promise) TypeError: Failed to resolve module specifier ‘fg-loadcss/dist/cssrelpreload.min’

When following this the templates are outputting this.

	<style type="text/css">.recentcomments a{display:inline !important;padding:0 !important;margin:0 !important;}</style>

I also noticed I get an error from yarn linting

yarn run v1.12.3

$ npm run -s lint:scripts && npm run -s lint:styles


1:7 error Parsing error: Unexpected token (

:heavy_multiplication_x: 1 problem (1 error, 0 warnings)

error Command failed with exit code 1.

info Visit for documentation about this command.

Here is the content of the file cssrelpreload.js


Did I do something wrong?



I made a syntax error in the guide. Remove parentheses from import path. It should be:

import "fg-loadcss/dist/cssrelpreload.min";