Category Archives: Web development

Blogposts on blog.futtta.be about “web development”; looking into frameworks, security, best practices, the use of Flash, usability and accessibility, …

Autoptimize 2.8.2 update “mishap” postmortem

This morning I finally pushed Autoptimize 2.8.2 out of the gates which was a relatively minor release with misc. small improvements/ bugfixes. Only it proved not that minor as it broke some sites after the update, so here’s a quick postmortem.

Timeline

  • 7h33 CEST: I pushed out 2.8.2
  • 7h56 CEST: first forum post about a Fatal PHP error due to wp-content/plugins/autoptimize/classes/external/php/ao-minify-html.php missing
  • 7h58 CEST: second forum post confirming issue
  • 8h01 CEST: responded to both forum posts asking if file was indeed missing on filesystem
  • 8h04 CEST: I changed the “stable version” back to 2.8.1 to stop 2.8.2 from being pushed out.
  • 8h07 CEST: forum post replies confirming the file was indeed missing from the filesystem
  • 8h15 CEST: I pushed out 2.8.3 with the fix
  • 8h22 CEST: confirmed fixed by first user
  • 8h26 CEST: confirmed fixed by second user

Root cause analysis

One of the improvements was changing the classname of the HTML minifier to avoid W3 Total Cache’s HTML minifier being used. For this purpose not only small changes were made to the HTML minifier code, but the file was also renamed from minify-html.php into ao-minify-html.php. The file itself was present on my local filesystem, but I did *not* svn add it, so it was never propagated to the wordpress.org SVN server, resulting in it not being in the 2.8.2 zip-file causing the PHP Fatal “require(): Failed opening required” errors.

Conclusions

Every svn ci has be proceeded by an svn stat, always. I’ve updated my “go live” procedure to reflect that.

Additionally; I strongly advise against automatic updates for Autoptimize (and I don’t auto-update any plugin myself), not only for major f-ups like mine today, but also because any change to how (auto-)optimization works needs to be tested for regressions. And if you have a site that generates money somehow, you really should have a staging site (which can auto-update) to test updates on before applying on production.

Redirecting to AMP (reader mode) for mobile

I’m not a big fan of AMP but I do have it active here on this blog using the official AMP plugin for WordPress, using it in “Reader” (aka “classic”) mode. That’s as far as I want to take it, but suppose (as was the case for an Autoptimize/ Critical CSS user I was helping out) you want to redirect all mobile traffic to AMP, then you could use below code snippet to do just that.

add_action('init','amp_if_mobile');
function amp_if_mobile() {
  $_request = $_SERVER['REQUEST_URI'];
	if ( strpos( $_request, '?amp' ) === false && strpos( $_request, '&amp' ) === false && ! is_admin() && wp_is_mobile() ) {
    if ( strpos( $_request, '?' ) === false ) {
      $_amp = '?amp';
    } else {
      $_amp = '&amp';
    }
    $amp_url = home_url() . $_request . $_amp;
    wp_redirect( $amp_url );
    exit;
  }
}

It might be a little rough around the edges, but it (mostly) gets the job done ;-)

How to (not) correctly load Gutenberg JS

On Facebook someone asked me how to do Gutenberg the right way to avoid loading too much JS on the frontend, this is a somewhat better organized version of my answer;

I’m not a Gutenberg specialist (for from it, really) but:

  • the wrong way is adding JS with wp-block/ wp-element and other gutenberg dependencies on init calling wp_enqueue_script,
  • the right way is either hooking into enqueue_block_editor_assets (see https://jasonyingling.me/enqueueing-scripts-and-styles-for-gutenberg-blocks/)
  • or when using init doing wp_register_script and then register_block_type referring to the correct editor_script previously registered (see https://wordpress.org/gutenberg/handbook/designers-developers/developers/tutorials/block-tutorial/writing-your-first-block-type/).

I’ve tried both of these on a “bad” plugin and can confirm both solutions do prevent those needless wp-includes/js/dist/* JS-files from being added on the front-end.

Developers: don’t make Gutenberg go Badass-enberg on my frontend!

Over the past couple of months, since the release of WordPress 5.0 which includes Gutenberg, the new JavaScript-based block editor, I have seen many sites loading a significant amount of extra JavaScript from wp-includes/js/dist on the frontend due to plugins doing it wrong.

So dear plugin-developer-friends; when adding Gutenberg blocks please differentiate between editor access and visitor access, only enqueue JS/ CSS if needed to display your blocks and when registering for front-end please please frigging please don’t declare wp-blocks, wp-element, … and all of those other editor goodies as dependencies unless your 100% sure this is needed (which will almost never be the case).

The performance optimization crowd will thank you for being considerate and -more likely- will curse you if you are not!

Hide-my-WordPress & Autoptimize compatibility glue

An “Autoptimize Critical CSS“-user saw some weirdness in how the site looked when optimized. The reason for this turned out to be not the critical CSS, but the fact that he used “Hide My WordPress Pro”, a plugin that changes well-known paths in WordPress URL’s to other paths (e.g. /wp-content/plugins -> /modules/ and /wp-content/themes -> /templates) and uses rewrite rules .htaccess to map requests to the filesystem. This resulted in Autoptimize not finding the files on the filesystem (as AO does not “see” the mapping in .htaccess), leaving them un-aggregated.

To fix something like that, a small code snippet that hooks into Autoptimize’s API can do the trick;

add_filter('autoptimize_filter_cssjs_alter_url', 'rewrite_hidemywp');
function rewrite_hidemywp($url) {
    if ( strpos( $url, 'modules/' ) !== false && strpos( $url, 'wp-content' ) === false ) {
        $url = str_replace('modules/','wp-content/plugins/', $url);
    } elseif ( strpos( $url, 'templates/' ) !== false && strpos( $url, 'wp-content' ) === false ) {
	$url = str_replace('templates/','wp-content/themes/', $url);
    }
    return $url;
}

The above is just an example (as in the Pro version of hide-my-wp you can set paths of your own liking and you can even replace theme names by random-ish strings), but with a small amount of PHP-skills you should be able to work out the solution for your own site. Happy optimized hiding!