Bringing Autoptimize 2.0 (beta) to a Christmas-tree near you

While over the last couple of months Autoptimize was quietly picking up users to reach 100.000 active installations, work was ongoing on the next version, the magical 2.0 (the PowerUps mentioned here before are still on the roadmap, albeit with some delay as I want AO 2.0 out first). Yesterday I uploaded what I consider to be the first Beta of Autoptimize 2.0 to the wordpress.org plugin repository and before inviting you to download & test this release I think this is the ideal moment to document some of the changes in that new version. Here goes;

  • Option to (de-)activate aggregation of inline JS and CSS which would allow to fix or prevent some of the recurring problems people have with AO (I’ll post a follow-up post on this with more info soon).
  • Option to remove Google Fonts (special request from my favorite user who obviously doesn’t like (Google) Fonts and who is too lazy to just dequeue them).
  • On average 30% faster minification (I’ll spill the beans on how that was done and what this implies in a later blogpost)!
  • Cache-size will be checked daily and a notice will be shown on your wp-admin pages if cache size goes over 512 MB (threshold can be changed using a filter).
  • Small autoptimized CSS (e.g. some print CSS) will be inlined instead of linked (256 characters by default, can be changed using a filter).
  • New in API: filters to declare a JS and CSS whitelist, where only files in that whitelist are autoptimized and all others are left untouched.
  • New in API: filters to declare “removable” CSS and JS, upon which Autoptimize will simply delete that code (emoji’s for example, if you prefer not to dequeue them).
  • lots of small and bigger bugfixes, I won’t bother you with a full list but have a look at the commmit log on GitHub.

I consider the code for this version feature-complete (have to keep some things up my sleeve for later versions), but what is needed now is testing, bug-reporting, bug-fixing and more testing. And translations, if you’re into those (I already contacted some earlier contributors). You can download Autoptimize 2.0 beta here, bug-reports are more then welcome on GitHub as an issue.
I’m pretty excited about this new version, so I’m looking forward to your feedback! Who knows we can push this out before the year is over?

Autoptimize to allow optimizing whitelisted resources only (and more)

Although work is still ongoing on what will become Autoptimize 2.0, I thought I’d share an (API-only) feature that allows developers/ web agencies to only aggregate & minify a fixed set of known-good resources only. This whitelist-based optimization will allow for a more stable situation upon delivery of your project to customers, as the CSS/ JS of plugins that are installed by your customer will not be autoptimized, so the site is less likely to break by accident.
The following example-code shows how to tell Autoptimize to only aggregate & minify jquery.js and jquery-migrate.min.js;

add_filter('autoptimize_filter_js_whitelist','example_js_whitelist');
function example_js_whitelist() {
return "jquery.js,jquery-migrate.min.js";
}

Using autoptimize_filter_css_whitelist allows you to accomplish the exact same things for CSS. The guys over at gigaom.com are already using autoptimize_filter_js_whitelist, so we must at least be doing something right there.
Some other new filters that might prove helpful;

  • autoptimize_filter_css_removables and autoptimize_filter_js_removables will allow you to specify which CSS or JS should actually be removed alltogether (Google Fonts, Emoji’s, … all in case you don’t like dequeuing off course)
  • autoptimize_filter_css_inlinesize allows you to specify up until how many characters of optimized CSS should be inlined instead of linked (can be useful for print CSS). Default value is 128, but I might bump that to 256 actually.
  • passing “true” to autoptimize_filter_css_fonts_cdn will tell AO to try to switch the font URL’s to your CDN
  • autoptimize_filter_cssjs_multidomain takes an array which can be used to tell AO that are also to be considered local domains and resources from those can be optimize (warning; as AO aggregates from the filesystem, this only works if the resources are actually local)
  • autoptimize_filter_cachecheck_do, autoptimize_filter_cachecheck_frequency and autoptimize_filter_cachecheck_maxsize can be used to control the wp-cronned cachechecker that will get triggered daily

Non-API improvements include performance optimizations, out-of-the box support for WPML subdomain-based language-variations and a whole heap of smaller improvements and bugfixes (e.g. the fact that if you have multiple title-tags, the optimized CSS would be injected in front of every one of those).
So yeah, I’d say we almost have ourselves a release. Only major thing still to go in; swapping the “look only in head” for an “include inline code” option. And testing of course, but that’s one area where I am looking at YOU, dear reader! Download the in-development version from GitHub and test away!

Solve WP Super Cache + Autoptimize Internal Server Errors

Yesterday I noticed my autoptimized JS-files were returning an internal server error (CSS worked as that is inlined). My Apache error-log had this entry:

[Tue Oct 13 17:23:42 2015] [alert] [client 178.xx.xx.xx] /var/public_html/blog.futtta.be/wp-content/cache/.htaccess: Option Indexes not allowed here

/var/public_html/blog.futtta.be/wp-content/cache/.htaccess is created by WP Super Cache, which got updated recently, a.o. to disable indexes being created of directories, and the .htaccess indeed read;

# BEGIN INDEX
Options -Indexes
# END INDEX

The solution? I could have edited WPSC’s .htaccess, but my changes could get overwritten there whenever Donncha would feel like it, so in the end I edited my site’s config in Apache;

<directory /var/public_html/blog.futtta.be>
AllowOverride All
</directory>

And all is well now.

3 interesting WordPress plugins

I came across some interesting WordPress plugins and thought I’d document these quickly;

  1. Warm Cache; have your site crawled based on your sitemap.xml to re-generate your cache (applicable to both your page cache and Autoptimize’s cache)
  2. Duplicator: export your entire WordPress installation to an archive and install elsewhere. Haven’t tried this yet, but might come in very handy at some point.
  3. Code Snippets: don’t burden your theme’s functions.php with your own code (risking losing the changes with a theme update), but use Code Snippets instead. Handy if you want to e.g. tell Autoptimize not to be active on specific pages or if you want WP YouTube Lyte to also act on youtube-links in text widgets for example.

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;

Mejora la velocidad y el SEO de tu sitio web comprimiendo ficheros JavaScript, CSS y HTML

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.