Autoptimize enhancement: feedback wanted

screenshot of the page/ post autoptimization settingsI’m in the process of adding a per page/ post option to disable Autoptimization.
In the current state of this work in process one can disable Autoptimize entirely on a post/ page or disable just JS optimization as you can see on the screenshot.
Now my question to you, Autoptimize user, is; what other options of below list _have_ to go in that metabox taking into account the list should be between 3 and 5 items long?

  • CSS optimization (which includes Critical CSS)
  • Critical CSS usage/ Inline & defer CSS
  • HTML optimization
  • Image optimization
  • Image Lazyload
  • Google Font optimization
  • Preload (from “extra” tab)
  • Preconnect (from “extra” tab)
  • Async (from “extra” tab)

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.

Contact Form 7 alternatives

Contact Form 7: trouble right here in volcano city!Given the major change in Contact Form 7‘s frontend JavaScript and the problems having to optimize the JS or cache the page after the update, the question I get asked frequently is what alternatives there are to CF7.
So here is a very quick rundown of 3 such alternatives:

  1. Gravity Forms: premium-only, visual form builder, very flexible, big ecosystem (lots of 3rd party plugins & integrations)
  2. Formidable Forms: has a free Light version, drag & drop interface for building forms, very flexible (we currently use this on autoptimize.com), lots of integrations but smaller ecosystem.
  3. HTML Forms: free plugin from the team that also develops “Koko Analytics” (which I now use on all my sites) and “Mailchimp for WordPress” with a premium addon for extra features, similar to Contact Form 7, no frills, very light on JS so great for performance.

My advice; try HTML Forms if you have rather standard contactform-like forms and you’re not looking for something fancy (which CF7 is not either), try Formidable if you need drag & drop form building or if you (will) need more flexibility/ integrations.

Contact Form 7 update breaks Autoptimize JS optimization: workaround

Due to a recent major change in Contact Form 7’s frontend JavaScript Autoptimize users might have to add wp-includes/js/dist the comma-separated JS optimization exclusion list (or in some cases even wp-includes/js).
It is nice CF7 gets rid of the jQuery dependancy, but I’m not sure is replacing that with a significant amount of extra WordPress blocks JS-files was such a good idea?
Update: additionally the change also introduces nonces (random password-like strings as hidden elements in the form) which can spell serious trouble when using page caching plugins.

Autoptimize Image Optimization to be less “lazy” with pictures

Up until now Autoptimize, when performing image optimization, relies on JS-based lazyloading (with the great lazysizes component) to differentiate between browser that support different image formats (AVIF, WebP and JPEG as fallback).
As JS-based Lazyload is going out of fashion though (with native lazyload being supported by more browsers and WordPress having out-of-the-box support for it too), it is time to start working on <picture> output in Autoptimize to serve “nextgen image formats” where different <source> tags offer the AVIF and WebP files and the <img> tag (which includes the  loading=”lazy” attribute) with JPEG as fallback.
For now that functionality is in a separate “power-up”, available on Github. If you have Image Optimization active in Autoptimize (and you are on the Beta version, Autoptimize 2.8.1 is missing a filter which the power-up needs so download & install the Beta if not done yet), you can download the plugin Github and give it a go. All feedback is welcome!

Fix for Elementor 3.1 YouTube not LYTE anymore

Elementor 3.1 came with “refactored YouTube source to use YouTube API in Video widget” which resulted in WP YouTube Lyte not being able to lyten up the YouTubes any more. Below code snippet (consider it beta) hooks into Elementor to fix this regression;

add_filter( 'elementor/frontend/widget/should_render', function( $should_render, $elementor_element ) {
	if ( function_exists( 'lyte_preparse' ) && 'Elementor\Widget_Video' === get_class( $elementor_element ) ) {
		$pas = get_private_property( $elementor_element , 'parsed_active_settings');
		if ( ! empty( $pas['youtube_url'] ) ) {
			echo lyte_preparse( $pas['youtube_url'] );
			return false;
		}
	}
	return $should_render;
}, 10, 2 );
// from https://www.lambda-out-loud.com/posts/accessing-private-properties-php/
function get_private_property( object $object, string $property ) {
    $array = (array) $object;
    $propertyLength = strlen( $property );
    foreach ( $array as $key => $value ) {
        if ( substr( $key, -$propertyLength ) === $property ) {
            return $value;
        }
    }
}

Hat tip to Koen for his assistance in digging into Elementor, much appreciated!

AO image optimization: transparent .png to avif issue

if “Load WebP or AVIF in supported browsers?” is on, .png files with transparency will loose that transparency in browsers that support AVIF due to a recent technical change in Shortpixel’s AVIF toolchain.
Shortpixel is looking at alternative solutions, but until then as a workaround you can either:

  • add .png to Autoptimize’s lazyload exclusion field
  • or to use below code snippet to disable AVIF images;

add_filter( 'autoptimize_filter_imgopt_do_avif', '__return_false');

About that new autoptimize_filter_imgopt_lazyload_from_nth filter

Some people asked for documentation/ information on that new autoptimize_filter_imgopt_lazyload_from_nth filter which allows one to tell AO not to optimize the first X images found in the HTML, so here is an example code snippet that sees AO not lazyload the first 5 images:
add_filter( 'autoptimize_filter_imgopt_lazyload_from_nth', function(){ return 5; } );
Update: as from AO 2.8.2 this will also be an option on the settings page, see screenshot 🙂
 

Fixed: WordPress 5.6 required Autoptimize settings change

PSA: WordPress 5.6 changes the filename of jQuery core. If you’re using Autoptimize and you have jQuery excluded (which is default) you will want to update your JS optimization exclusion list from js/jquery/jquery.js to js/jquery/jquery.min.js.
Update: Autoptimize 2.8 will automagically fix this, urgently looking for some testers to download https://github.com/futtta/autoptimize/archive/beta.zip (make sure 2.7.8 is disabled when enabling the beta). If all goes well and I get some confirmation the update (which has a lot more then just the fix) will go out today!
Update2: AO28 was released, all is (or should be) OK now 🙂