You care about web performance and so you dutifully aggregate and minify your CSS. But then a couple of months ago Google PageSpeed Insights (for mobile) started identifying CSS as a render blocking resource and so you wonder if you should you inline your CSS, or even defer loading it. Based on tests executed on a multi-site WordPress installation, deferring CSS is not the best idea just yet, but inlining might be worthwhile! Read on for the hard numbers and other details.
- 4 test-blogs on a multi-site WordPress instance
- using the Expound theme (which is interesting because its main stylesheet imports 2 other CSS-files)
- using Lite Cache for page caching (new WordPress page caching plugin by the Hyper Cache author)
- the same content was imported on all 4 blogs
- all 4 had Autoptimize HTML & JS optimization active
- the difference was in the Autoptimize CSS settings, where:
- blog 1 had no CSS optimization at all (baseline )
- blog 2 had standard CSS aggregation and minification, linked in head
- blog 3 inlined the optimized CSS
- blog 4 deferred the optimized CSS
- each blog was tested on webpagetest.org‘s Amsterdam node on a DSL-profile using IE9 and doing 9 test-runs on one specific blogpost with contained a 16KBimage (I excluded favicon.ico as it seemed to pollute results)
- each blog was analyzed by Google PageSpeed Insights for both mobile & desktop
Based on these tests (your mileage may vary, always test your results):
- deferring all CSS is useless, performance is worse, desktop PageSpeed score is (slightly) lower and there is a “flash of unstyled content” between the rendering of the page and the application of the CSS.
- Inlining CSS yields the best results both from a page speed and PageSpeed perspective. Although the base HTML is larger as it has the CSS payload, this has almost no impact in this specific context and rendering is almost instantaneous. Off course in a context where multiple other pages from the same site, with the exact same CSS would be loaded, the impact would be significant. Hence inlining CSS is especially interesting for sites with a low pageviews/ visitor ratio.
The future; inline + defer
Deferring CSS may seem pretty useless, but the sweet spot may just be inlining base CSS (everything needed for initial rendering above the fold) and deferring everything else. This is what CSS optimizing tools should focus on in 2014 and you can certainly expect something along these lines in one of the next major Autoptimize releases (although diehards can already test this approach).
A new version of WP YouTube Lyte was released over the weekend. Benetech, a U.S. nonprofit that develops and uses technology to create positive social change, offered a patch that adds the accessibilityFeature property to videos that have captions. If you have microdata enabled, WP YouTube Lyte now will automatically check if captions are available and if so, adds the accessibilityFeature property with value “captions” to the HTML-embedded microdata.
As YouTube only offers information on captions in their API v3, which requires authentication, the check is done in a separate, asynchronous call via a proxy-webservice on api.a11ymetadata.org. You can see an example of what the response looks like here and look at the source code on Github. This webservice-request for captions can be disabled by simply switching off microdata. Alternatively, if you want microdata but not the accessibilityFeature-property, you can use the “lyte_docaptions”-filter to set captions to false (you can find an example in lyte_helper.php_example).
This was the first time someone actively submitted code changes to add functionality to a project of mine, actually. Working with Benetech was a breeze and GitHub is a great platform to share, review and comment code. I for one am looking forward to more high-quality contributions like this one!
I love me some regular expressions (problems), but have you ever seen one crash Apache? Well I have! This regex is part of YUI-CSS-compressor-PHP-port, the external CSS minification component in Autoptimize, my WordPress JS/CSS optimization plugin:
Executing that on a large chunk of CSS (lots of selectors for one declaration block, which cannot be ripped apart) triggers a stack overflow in PCRE, which crashes Apache and shows up as a “connection reset”-error in the browser.
Regular expression triggered segfaults are no exception in the PHP bugtracker and each and every of those tickets gets labeled “Not a bug” while pointing the finger at PCRE, which in their man-pages and in their bug tracker indeed confirm that stack overflows can occur. This quote from that PCRE bug report says it all, really;
If you are running into a problem of stack overflow, you have the
(a) Work on your regular expression pattern so that it uses less
memory. Sometimes using atomic groups can help with this.
(b) Increase the size of your process stack.
(c) Compile PCRE to use the heap instead of the stack.
(d) Set PCRE's recursion limit small enough so that it gives an error
before the stack overflows.
Are you scared yet? I know I am. But this might be a consolation; if you test your code on xampp (or another Apache on Windows version), you’re bound to detect the problem early on, as the default threadstacksize there is a mere 1MB instead of the whopping 8MB on Linux.
As for the problem in YUI-CSS-compressor-PHP-port; I logged it on their Github issue-list and I think I might just have a working alternative which will be in Autoptimize 1.8.
Another year behind us, another overview in numbers (as done previously for 2011 and 2012).
- My blog:
- My WordPress plugins:
On a personal note, 2013 has not been the easiest of years, but our lovely daughter’s “lentefeest” (a non-religious rite of passage for 6-year olds) and our holiday in Italy were great highlights though.
It’s been just under a year since I took over development & support of Autoptimize. And just now it reached 99.999 downloads:
For those of you who use it; thanks for the confidence. For those who haven’t given it a shot yet; watch us, there’s some great features coming up!
I’ve been working on a new Autoptimize version over the last couple of weeks and consider it largely finished now. The following features are in:
- Optionally inline all CSS as suggested by Hamed (warning: can result in improved pagespeed-score but lower page speed! I’ll write a blogpost about when to use and not to use this one shortly)
- Simple API Set of filters to provide a simple API (including example code) to change Autoptimize behavior to
- conditionally disable Autoptimize on a per request-basis
- change the CSS- and JS-excludes
- change the limit for CSS background-images to be inlined in the CSS
- define what JS-files are moved behind the aggregated one
- change the defer-attribute on the aggregated JS script-tag
- Improvement: updated upstream CSS minifier
- Improvement: switch default delivery of optimized CSS/JS-files from dynamic PHP to static files
- Improvement (force gzip of static files) and bugfix (force expiry for dynamic files, thanks to Willem Razenberg) in .htaccess
- Bugfix: fail gracefully when things go wrong (e.g. the CSS import aggregation gone haywire resulting in empty aggregated CSS-files that was reported by Danka)
- Bugfix: stop import-statements in CSS comments to be taken into acccount as seen by Joseph from blog-it-solutions.de
- Bugfix: fix for blur in CSS breaking as reported by Chris of clickpanic.com
- Updated translations
Some more testing and a couple of translations are still to be updated and we’re good to go for a release early January. You’re welcome to join in on the fun off course; download the test-version here and let me know what works and -more importantly- what is broken!
If you’re using both Autoptimize and WordPress SEO by Yoast, you might have noticed blank sitemaps in your browser. With the help of Vance Hallman and Armand Hadife, I have been able to isolate and fix this rather interesting bug.
I pretty soon saw that It actually wasn’t the sitemap XML, but the XSL (XML stylesheets, browsers use those to make XML readable) that was wrecking havoc. This means that although you couldn’t see them in your browser, the sitemaps themselves were not broken and could still be used by search engines.
Although fiddling with the defer-attribute could solve the issue, I think it’s not a good idea for Autoptimize to try to optimize non-HTML resources as it isn’t WordPress’ core functionality either, so I changed Autoptimize to not act on non-HTML content (i.e. without an HTML-tag or with an xsl:stylesheet-tag). This change is in the upcoming 1.7.3 release, it will be pushed live tomorrow.