Why Autoptimize doesn’t touch non-local CSS/JS

Earlier today I got this question on the wordpress.org support forum for Autoptimize;

Will there be Google fonts support in the future? I now include the google font’s like this:
wp_enqueue_style( 'google-fonts', '//fonts.googleapis.com/css?family=Open+Sans:400italic,600italic,400,700,600|Varela+Round' );
Is it possible to add this css to the combined and minified by this plugin file?

The basic question if Autoptimize can aggregate external resources has been asked before and I felt it was time to dig in.
I did a little test, requesting the same Google Font CSS, changing browser user agents. For my good ole Firefox on Ubuntu Linux I got (snippet);

@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
src: local('Open Sans'), local('OpenSans'), url(http://fonts.gstatic.com/s/opensans/v13/cJZKeOuBrn4kERxqtaUH3VtXRa8TVwTICgirnJhmVJw.woff2) format('woff2'), url(http://fonts.gstatic.com/s/opensans/v13/cJZKeOuBrn4kERxqtaUH3T8E0i7KZn-EPnyo3HZu7kw.woff) format('woff');

Whereas the exact same request with an MSIE7 useragent gives (again, extract);

@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
src: url(http://fonts.gstatic.com/s/opensans/v13/cJZKeOuBrn4kERxqtaUH3fY6323mHUZFJMgTvxaG2iE.eot);

It’s not surprising Google has specific CSS based on browser useragent (probably browser-version), but this is a simple example of how dynamic remote CSS or JS can be (the scala of variables that could lead to 3rd parties serving up different CSS/JS is huge, really).
So although theoretically it would be possible to have AO cache remote JS/CSS (such as Google Font’s) and include it in the aggregated CSS- or JS-file (and that way removing render blocking resources), the problem is that AO will never be able to apply whatever logic the 3rd party applies when getting requests. Hence the design decision (made by the original developer, Turl, a long long time ago) not to aggregate & minify external resources. This is how it should be.

Want to beta-test Autoptimize power-ups?

So I’m currently working on “power-ups” for Autoptimize, which I might commercialize later this year. Some examples of functionality I’m developing;

  • Excluding specific parts of your site from optimization (JS+CSS+HTML, JS-only or CSS-only), all from a simple configuration-screen
  • A settings-page to configure “above-the-fold”-CSS for specific pages
  • A power-up to speed up optimization itself (especially interesting if you don’t have a page caching plugin)

Drop me a line If you’re interested in beta-testing these power-ups, with a small description of where you would run this beta.

Autoptimize: video tutorial en Espanõl!

The webempresa.com team contacted me a couple of days ago to let me know they created a small tutorial on the installation & basic configuration of Autoptimize, including this video of the process;

The slowdown noticed when activating JS optimization is due to the relative cost of aggregating & minifying the JS. To avoid this overhead for each request, implementing a page caching solution (e.g. HyperCache plugin or a Varnish-based solution) is warmly recommended.
Muchas gracias Webempresa!

Is your string zipped?

While looking into a strange issue on a multisite WordPress installation which optimized the pages of the main but not of the sub-blogs, I needed code to check whether a string was gzipped or not. I found this like-a-boss code-snippet on StackOverflow which worked for gzencoded strings:

$is_gzip = 0 === mb_strpos($mystery_string , "\x1f" . "\x8b" . "\x08");

But this does not work for strings compressed with gzcompress or gzdeflate, which don’t have the GZIP header data, so in the end I came up with this less funky function which somewhat brutally simply tries to gzuncompress and gzinflate the string:

function isGzipped($in) {
  if (mb_strpos($in , "\x1f" . "\x8b" . "\x08")===0) {
    return true;
  } else if (@gzuncompress($in)!==false) {
    return true;
  } else if (@gzinflate($in)!==false) {
    return true;
  } else {
    return false;

Klunky, but it works. Now if only this would confirm my “educated guess” that the original problem was due to a compressed string.

Celebrating 300000 Autoptimize downloads with new release

300k-1, that isSo just now Autoptimize passed the 300000 downloads mark (6 months after reaching 200k), which feels huge to me. To celebrate I just pushed out version 1.9.3, which features -as becomes a minor release- small improvements and bugfixes. From the changelog;

  • improvement: more intelligent CDN-replacement logic, thanks Squazz for reporting and testing
  • improvement: allow strings (comments) to be excluded from HTML-optimization when comment removal is active (via API)
  • improvement: changed priority with which AO gets triggered by WordPress, solving JS not being aggregated when NextGen Galleries is active, with great help from msebald
  • improvement: extra JS exclude-strings: gist.github.com, text/html, text/template, wp-slimstat.min.js, _stq, nonce, post_id (the latter two were removed from the default “manual” exclude list on the settings-page and can be removed there if you want)
  • new in API: autoptimize_filter_html_exclude, autoptimize_filter_css_defer, autoptimize_filter_css_inline, autoptimize_filter_base_replace_cdn, autoptimize_filter_js_noptimize, autoptimize_filter_css_noptimize, autoptimize_filter_html_noptimize
  • bugfix: remove some PHP notices, as reported by dimitrov.adrian
  • bugfix: make sure HTML-optimalization does not gobble a space before a cite as proposed by ecdltf
  • bugfix: cleaning the cache did not work on non-default directories as encountered by NoahJ Champion
  • upgraded to yui compressor php port 2.4.8-4
  • added arabic translation, thanks to the ekleel team
  • tested with WordPress 4.2 beta 3 (yep, it works)

So there you have your present, no go unwrap it! Have fun! 🙂

wordpress.org plugin repo: ratings changed

autoptimize ratings on feb 26th 2015Yesterday the average rating of all plugins on the wordpress.org repository changed; ratings that were not linked to a review, were removed. That means that ratings dating from before approximately November 2012, when reviews were introduced, are not being taken into account any more.
This had a positive impact on the average rating of my own plugins, but especially so for Autoptimize. That plugin was largely unsupported before I took over in January 2013 and got some low ratings as a consequence (the average was 4.2 at the time, if I’m not mistaking). With those old numbers now out of the way, the average went from 4.6 to 4.8 overnight. Yay!
[Update: a couple of days later there were even more changes on the WordPress Plugin pages.]

Bye 2014, it was nice knowing ya!

this used to be an animated gif, click to see itWith 2014 finally behind us, we can start dwelling on that past as of yesterday. These are some of my 2014 facts & figures:
About my blog:

My WordPress plugins:

  • Autoptimize
    • 2 major and 7 minor releases
    • 141324 downloads, bringing the total to 241650
    • answered lots of questions and feedback on the support-forum, allowing me to improve both the code and the FAQ.
    • 2015 will bring Autoptimize 2.0 (fixing the occasional WSOD & the cache-size problem) and Autoptimize Power-Ups (extensions for professional & power-users)
  • WP YouTube Lyte:
    • 2 major and 2 minor releases
    • 36507 downloads, now totalling 210285
    • 2015 will see continued improvements and WP YouTube Lyte Power-Ups (you guessed it, extensions for professional & power-users)
  • WP DoNotTrack:
    • 2 minor releases
    • 4312 downloads, now 12009 total
    • 2015 really should see a 1.0 release, which will finally include CSP-enforced protection.

Bye 2014, it was nice knowing ya, but I’m off enjoying 2015 now!

Autoptimize minor update and beyond

I just released an update to Autoptimize, bumping the version to 1.9.2. Main new features;

  • New: support for alternative cache-directory and file-prefix as requested by a.o. Jassi Bacha, Cluster666 and Baris Unver.
  • Improvement: hard-exclude all linked-data json objects (script type=application/ld+json)
  • Improvement: several filters added to the API, e.g. to alter optimized HTML, CSS or JS
  • Some bugfixes
  • Swedish translations updated & Ukrainian added, courtesy of Zanatoly of SebWeo.com

I’m already thinking about version 2.0 (which should fix the 2 big issues some people face; exploding cache size due to page-specific inline code & the rare but nasty white screen of death due to CSS minification issues) and about some powerful new features that could extend Autoptimize for professionals and power-users in need of something more. 2015 is going to be great, hope you guys & girls will be part of that!
Anyway, enjoy the end-of-year festivities and above all, have fun & share some of the happiness!

Amazed by Autoptimize take-up

autoptimize at +200K downloads, wow!Less then a year after reaching 100000 downloads, Autoptimize broke the 200000 barrier just last week.
It’s also exiting to see how people are blogging (or tweeting) about it as well;

So yeah, I’m pretty amazed by how well Autoptimize is doing. Thanks for the confidence!