Autoptimize - Version 2.9.4

Version Description

  • Fix for 2 AMP compatibility issues (toolbar JS & lazyload JS).
  • Fix for PHP notice in autoptimizeImages.php.
  • Change default for "lazyload from nth image" from 0 to 2 (only applies to new installations).
  • Improvements to the exit survey.
  • Enjoy the end-of-year celebrations, there are great Autoptimize things to come in 2022! ;-)
Download this release

Release Info

Developer futtta
Plugin Icon 128x128 Autoptimize
Version 2.9.4
Comparing to
See all releases

Code changes from version 2.9.3 to 2.9.4

autoptimize.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Autoptimize
4
  * Plugin URI: https://autoptimize.com/
5
  * Description: Makes your site faster by optimizing CSS, JS, Images, Google fonts and more.
6
- * Version: 2.9.3
7
  * Author: Frank Goossens (futtta)
8
  * Author URI: https://autoptimize.com/
9
  * Text Domain: autoptimize
@@ -21,7 +21,7 @@ if ( ! defined( 'ABSPATH' ) ) {
21
  exit;
22
  }
23
 
24
- define( 'AUTOPTIMIZE_PLUGIN_VERSION', '2.9.3' );
25
 
26
  // plugin_dir_path() returns the trailing slash!
27
  define( 'AUTOPTIMIZE_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
3
  * Plugin Name: Autoptimize
4
  * Plugin URI: https://autoptimize.com/
5
  * Description: Makes your site faster by optimizing CSS, JS, Images, Google fonts and more.
6
+ * Version: 2.9.4
7
  * Author: Frank Goossens (futtta)
8
  * Author URI: https://autoptimize.com/
9
  * Text Domain: autoptimize
21
  exit;
22
  }
23
 
24
+ define( 'AUTOPTIMIZE_PLUGIN_VERSION', '2.9.4' );
25
 
26
  // plugin_dir_path() returns the trailing slash!
27
  define( 'AUTOPTIMIZE_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
classes/autoptimizeBase.php CHANGED
@@ -167,6 +167,10 @@ abstract class autoptimizeBase
167
 
168
  // Prepend with WP_ROOT_DIR to have full path to file.
169
  $path = str_replace( '//', '/', trailingslashit( WP_ROOT_DIR ) . $path );
 
 
 
 
170
 
171
  // Final check: does file exist and is it readable?
172
  if ( file_exists( $path ) && is_file( $path ) && is_readable( $path ) ) {
167
 
168
  // Prepend with WP_ROOT_DIR to have full path to file.
169
  $path = str_replace( '//', '/', trailingslashit( WP_ROOT_DIR ) . $path );
170
+
171
+ // Allow path to be altered, e.g. in the case of bedrock-like setups where
172
+ // core, theme & plugins might be in different locations on the filesystem.
173
+ $path = apply_filters( 'autoptimize_filter_base_getpath_path', $path, $url );
174
 
175
  // Final check: does file exist and is it readable?
176
  if ( file_exists( $path ) && is_file( $path ) && is_readable( $path ) ) {
classes/autoptimizeConfig.php CHANGED
@@ -831,7 +831,7 @@ if ( true === autoptimizeImages::imgopt_active() && true === apply_filters( 'aut
831
  'autoptimize_imgopt_checkbox_field_4' => '0', // webp off (might be removed).
832
  'autoptimize_imgopt_text_field_5' => '', // lazy load exclusions empty.
833
  'autoptimize_imgopt_text_field_6' => '', // optimization exclusions empty.
834
- 'autoptimize_imgopt_number_field_7' => '0', // lazy load from nth image (0 = lazyload all).
835
  );
836
  return $defaults;
837
  }
@@ -989,8 +989,9 @@ if ( true === autoptimizeImages::imgopt_active() && true === apply_filters( 'aut
989
  $_meta_value = false;
990
  }
991
  }
992
-
993
- if ( ! empty( $_meta_value ) && is_array( $_meta_value ) && array_key_exists( $optim, $_meta_value ) && $_meta_value[$optim] !== 'on' ) {
 
994
  return false;
995
  } else {
996
  return true;
831
  'autoptimize_imgopt_checkbox_field_4' => '0', // webp off (might be removed).
832
  'autoptimize_imgopt_text_field_5' => '', // lazy load exclusions empty.
833
  'autoptimize_imgopt_text_field_6' => '', // optimization exclusions empty.
834
+ 'autoptimize_imgopt_number_field_7' => '2', // lazy load from nth image (0 = lazyload all).
835
  );
836
  return $defaults;
837
  }
989
  $_meta_value = false;
990
  }
991
  }
992
+
993
+ // If autoptimize_post_optimize !== 'on' then always return false as all is off.
994
+ if ( ! empty( $_meta_value ) && is_array( $_meta_value ) && ( ( array_key_exists( 'autoptimize_post_optimize', $_meta_value ) && 'on' !== $_meta_value['autoptimize_post_optimize'] ) || ( array_key_exists( $optim, $_meta_value ) && 'on' !== $_meta_value[$optim] ) ) ) {
995
  return false;
996
  } else {
997
  return true;
classes/autoptimizeExitSurvey.php CHANGED
@@ -46,12 +46,14 @@ class autoptimizeExitSurvey
46
  <label for="ao_feedback5">
47
  I don't see a performance improvement.
48
  </label>
 
49
  </li>
50
  <li ao-option-id="6">
51
  <input type="radio" name="ao-deactivate-option" id="ao_feedback6">
52
  <label for="ao_feedback6">
53
  It broke my site.
54
  </label>
 
55
  <li ao-option-id="4">
56
  <input type="radio" name="ao-deactivate-option" id="ao_feedback4">
57
  <label for="ao_feedback4">
@@ -67,13 +69,20 @@ class autoptimizeExitSurvey
67
  <label for="ao_feedback999">
68
  Other (please specify below) </label>
69
  <textarea width="100%" rows="2" name="comments" placeholder="What can we do better?"></textarea></li>
 
 
 
 
 
 
 
70
  </ul>
71
  </div><!--/.popup--body-->
72
  <div class="popup--footer">
73
  <div class="actions">
74
  <a href="#" class="info-disclosure-link">What info do we collect?</a>
75
  <div class="info-disclosure-content"><p>Below is a detailed view of all data that Optimizing Matters will receive if
76
- you fill in this survey. Email address or IP addresses will not be sent.</p>
77
  <ul>
78
  <li><strong>Plugin version </strong> <code id="ao_plugin_version"> <?php echo AUTOPTIMIZE_PLUGIN_VERSION ?> </code></li>
79
  <li><strong>Current website:</strong> <code> <?php echo trailingslashit(get_site_url()) ?> </code></li>
@@ -85,7 +94,12 @@ class autoptimizeExitSurvey
85
  name="ao-deactivate-no"
86
  id="ao-deactivate-no"
87
  class="button"
88
- value="Skip &amp; Deactivate">
 
 
 
 
 
89
  <input type="submit"
90
  name="ao-deactivate-yes"
91
  id="ao-deactivate-yes"
46
  <label for="ao_feedback5">
47
  I don't see a performance improvement.
48
  </label>
49
+ <p class="last-attempt">Autoptimize does not do page caching, so you might have to install e.g. KeyCDN Cache Enabler or WP Super Cache. Feel free to create a topic on <a href="https://wordpress.org/support/plugin/autoptimize/#new-topic-0" target="_blank">the support forum here</a> to get pointers on how get the most out of Autoptimize!</p>
50
  </li>
51
  <li ao-option-id="6">
52
  <input type="radio" name="ao-deactivate-option" id="ao_feedback6">
53
  <label for="ao_feedback6">
54
  It broke my site.
55
  </label>
56
+ <p class="last-attempt">Almost all problems can be fixed with the right configuration, have a look at <a href="https://wordpress.org/plugins/autoptimize/#faq" target="_blank">the FAQ</a> or create a topic on <a href="https://wordpress.org/support/plugin/autoptimize/#new-topic-0" target="_blank">the support forum here</a>!</p>
57
  <li ao-option-id="4">
58
  <input type="radio" name="ao-deactivate-option" id="ao_feedback4">
59
  <label for="ao_feedback4">
69
  <label for="ao_feedback999">
70
  Other (please specify below) </label>
71
  <textarea width="100%" rows="2" name="comments" placeholder="What can we do better?"></textarea></li>
72
+ <hr />
73
+ <li ao-option-id="998">
74
+ <label for="ao_feedback998">
75
+ If you want to be contacted about your experience with Autoptimize, leave your email here (we won't spam).
76
+ </label>
77
+ <input type="email" name="ao-deactivate-option" id="ao_feedback998" placeholder="mymail@domain.xyz">
78
+ </li>
79
  </ul>
80
  </div><!--/.popup--body-->
81
  <div class="popup--footer">
82
  <div class="actions">
83
  <a href="#" class="info-disclosure-link">What info do we collect?</a>
84
  <div class="info-disclosure-content"><p>Below is a detailed view of all data that Optimizing Matters will receive if
85
+ you fill in this survey. Your email address is only shared if you explicitly fill it in, your IP addres is never sent.</p>
86
  <ul>
87
  <li><strong>Plugin version </strong> <code id="ao_plugin_version"> <?php echo AUTOPTIMIZE_PLUGIN_VERSION ?> </code></li>
88
  <li><strong>Current website:</strong> <code> <?php echo trailingslashit(get_site_url()) ?> </code></li>
94
  name="ao-deactivate-no"
95
  id="ao-deactivate-no"
96
  class="button"
97
+ value="Just Deactivate">
98
+ <input type="submit"
99
+ name="ao-deactivate-cancel"
100
+ id="ao-deactivate-cancel"
101
+ class="button"
102
+ value="Cancel">
103
  <input type="submit"
104
  name="ao-deactivate-yes"
105
  id="ao-deactivate-yes"
classes/autoptimizeImages.php CHANGED
@@ -869,7 +869,7 @@ class autoptimizeImages
869
  }
870
 
871
  public function add_lazyload_js_footer() {
872
- if ( false === autoptimizeMain::should_buffer() ) {
873
  return;
874
  }
875
 
@@ -1149,7 +1149,7 @@ class autoptimizeImages
1149
  echo apply_filters( 'autoptimize_filter_imgopt_settings_status', '<p><strong><span style="color:' . $_notice_color . ';">' . __( 'Shortpixel status: ', 'autoptimize' ) . '</span></strong>' . $_notice['notice'] . '</p>' );
1150
  } else {
1151
  // translators: link points to shortpixel.
1152
- $upsell_msg_1 = '<p>' . sprintf( __( 'Get more Google love by speeding up your website. Start serving on-the-fly optimized images (also in the "next-gen" <strong>WebP</strong> and <strong>AVIF</strong> image formats) by %1$sShortPixel%2$s. The optimized images are cached and served from %3$sShortPixel\'s global CDN%2$s.', 'autoptimize' ), '<a href="https://shortpixel.com/aospai' . $sp_url_suffix . '" target="_blank">', '</a>', '<a href="https://help.shortpixel.com/article/62-where-does-the-cdn-has-pops" target="_blank">' );
1153
  if ( 'launch' === $options['availabilities']['extra_imgopt']['status'] ) {
1154
  $upsell_msg_2 = __( 'For a limited time only, this service is offered free for all Autoptimize users, <b>don\'t miss the chance to test it</b> and see how much it could improve your site\'s speed.', 'autoptimize' );
1155
  } else {
@@ -1222,7 +1222,7 @@ class autoptimizeImages
1222
  <tr id='autoptimize_imgopt_lazyload_from_nth_image' <?php if ( ! array_key_exists( 'autoptimize_imgopt_checkbox_field_3', $options ) || ( isset( $options['autoptimize_imgopt_checkbox_field_3'] ) && '1' !== $options['autoptimize_imgopt_checkbox_field_3'] ) ) { echo 'class="autoptimize_lazyload_child hidden"'; } else { echo 'class="autoptimize_lazyload_child"'; } ?>>
1223
  <th scope="row"><?php _e( 'Lazy-load from nth image', 'autoptimize' ); ?></th>
1224
  <td>
1225
- <label><input type='number' min='0' max='50' style='width:80%' id='autoptimize_imgopt_lazyload_from_nth_image_number' name='autoptimize_imgopt_settings[autoptimize_imgopt_number_field_7]' value='<?php if ( ! empty( $options['autoptimize_imgopt_number_field_7'] ) ) { echo esc_attr( $options['autoptimize_imgopt_number_field_7'] ); } else { echo '0'; } ?>'><br /><?php _e( 'Don\'t lazyload the first X images, \'0\' lazyloads all.', 'autoptimize' ); ?></label>
1226
  </td>
1227
  </tr>
1228
  </table>
@@ -1371,7 +1371,11 @@ class autoptimizeImages
1371
  static $launch_status = null;
1372
 
1373
  if ( null === $launch_status ) {
1374
- $avail_imgopt = $this->options['availabilities']['extra_imgopt'];
 
 
 
 
1375
  $magic_number = intval( substr( md5( parse_url( AUTOPTIMIZE_WP_SITE_URL, PHP_URL_HOST ) ), 0, 3 ), 16 );
1376
  $has_launched = autoptimizeOptionWrapper::get_option( 'autoptimize_imgopt_launched', '' );
1377
  $launch_status = false;
869
  }
870
 
871
  public function add_lazyload_js_footer() {
872
+ if ( false === autoptimizeMain::should_buffer() || autoptimizeMain::is_amp_markup('') ) {
873
  return;
874
  }
875
 
1149
  echo apply_filters( 'autoptimize_filter_imgopt_settings_status', '<p><strong><span style="color:' . $_notice_color . ';">' . __( 'Shortpixel status: ', 'autoptimize' ) . '</span></strong>' . $_notice['notice'] . '</p>' );
1150
  } else {
1151
  // translators: link points to shortpixel.
1152
+ $upsell_msg_1 = '<p>' . sprintf( __( 'Get more Google love by speeding up your website. Start serving on-the-fly optimized images (also in the "next-gen" <strong>WebP</strong> and <strong>AVIF</strong> image formats) by %1$sShortPixel%2$s. No additional image optimization plugins are needed: your images are optimized, cached and served from %3$sShortPixel\'s global CDN%2$s.', 'autoptimize' ), '<a href="https://shortpixel.com/aospai' . $sp_url_suffix . '" target="_blank">', '</a>', '<a href="https://help.shortpixel.com/article/62-where-does-the-cdn-has-pops" target="_blank">' );
1153
  if ( 'launch' === $options['availabilities']['extra_imgopt']['status'] ) {
1154
  $upsell_msg_2 = __( 'For a limited time only, this service is offered free for all Autoptimize users, <b>don\'t miss the chance to test it</b> and see how much it could improve your site\'s speed.', 'autoptimize' );
1155
  } else {
1222
  <tr id='autoptimize_imgopt_lazyload_from_nth_image' <?php if ( ! array_key_exists( 'autoptimize_imgopt_checkbox_field_3', $options ) || ( isset( $options['autoptimize_imgopt_checkbox_field_3'] ) && '1' !== $options['autoptimize_imgopt_checkbox_field_3'] ) ) { echo 'class="autoptimize_lazyload_child hidden"'; } else { echo 'class="autoptimize_lazyload_child"'; } ?>>
1223
  <th scope="row"><?php _e( 'Lazy-load from nth image', 'autoptimize' ); ?></th>
1224
  <td>
1225
+ <label><input type='number' min='0' max='50' style='width:80%' id='autoptimize_imgopt_lazyload_from_nth_image_number' name='autoptimize_imgopt_settings[autoptimize_imgopt_number_field_7]' value='<?php if ( ! empty( $options['autoptimize_imgopt_number_field_7'] ) ) { echo esc_attr( $options['autoptimize_imgopt_number_field_7'] ); } else { echo '1'; } ?>'><br /><?php _e( 'Don\'t lazyload the first X images, \'1\' lazyloads all.', 'autoptimize' ); ?></label>
1226
  </td>
1227
  </tr>
1228
  </table>
1371
  static $launch_status = null;
1372
 
1373
  if ( null === $launch_status ) {
1374
+ $avail_imgopt = '';
1375
+ if ( is_array( $this->options ) && array_key_exists( 'availabilities', $this->options ) && is_array( $this->options['availabilities'] ) && array_key_exists( 'extra_imgopt', $this->options['availabilities'] ) ) {
1376
+ $avail_imgopt = $this->options['availabilities']['extra_imgopt'];
1377
+ }
1378
+
1379
  $magic_number = intval( substr( md5( parse_url( AUTOPTIMIZE_WP_SITE_URL, PHP_URL_HOST ) ), 0, 3 ), 16 );
1380
  $has_launched = autoptimizeOptionWrapper::get_option( 'autoptimize_imgopt_launched', '' );
1381
  $launch_status = false;
classes/autoptimizeMain.php CHANGED
@@ -689,7 +689,7 @@ class autoptimizeMain
689
  public static function notice_installed()
690
  {
691
  echo '<div class="updated"><p>';
692
- _e( 'Thank you for installing and activating Autoptimize. Please configure it under "Settings" -> "Autoptimize" to start improving your site\'s performance.', 'autoptimize' );
693
  echo '</p></div>';
694
  }
695
 
689
  public static function notice_installed()
690
  {
691
  echo '<div class="updated"><p>';
692
+ printf( __( 'Thank you for installing and activating Autoptimize. Please configure it under %sSettings -> Autoptimize%s to start improving your site\'s performance.', 'autoptimize' ), '<a href="options-general.php?page=autoptimize">', '</a>' );
693
  echo '</p></div>';
694
  }
695
 
classes/autoptimizeToolbar.php CHANGED
@@ -17,7 +17,12 @@ class autoptimizeToolbar
17
  }
18
 
19
  // Load admin toolbar feature once WordPress, all plugins, and the theme are fully loaded and instantiated.
20
- add_action( 'wp_loaded', array( $this, 'load_toolbar' ) );
 
 
 
 
 
21
  }
22
 
23
  public function load_toolbar()
17
  }
18
 
19
  // Load admin toolbar feature once WordPress, all plugins, and the theme are fully loaded and instantiated.
20
+ if ( is_admin() ) {
21
+ add_action( 'wp_loaded', array( $this, 'load_toolbar' ) );
22
+ } else {
23
+ // to avoid AMP complaining about the AMP conditional being checked too early.
24
+ add_action( 'wp', array( $this, 'load_toolbar' ) );
25
+ }
26
  }
27
 
28
  public function load_toolbar()
classes/static/exit-survey/exit-survey.css CHANGED
@@ -50,6 +50,20 @@ tr[data-slug="autoptimize"] span.deactivate{
50
  max-height: 150px;
51
  }
52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  .ao-feedback li {
54
  display: flex;
55
  align-items: center;
@@ -113,6 +127,10 @@ tr[data-slug="autoptimize"] span.deactivate{
113
  width: 100%;
114
  }
115
 
 
 
 
 
116
  .ao-feedback .buttons input:last-child {
117
  margin-left: auto;
118
  }
50
  max-height: 150px;
51
  }
52
 
53
+ .ao-feedback .popup--form input[type='email'] {
54
+ width: 100%;
55
+ margin: 10px 0 0;
56
+ }
57
+
58
+ .ao-feedback .popup--form input[type='email']:invalid {
59
+ color:red;
60
+ border-color:red;
61
+ }
62
+
63
+ .ao-feedback .popup--form p.last-attempt {
64
+ display: none;
65
+ }
66
+
67
  .ao-feedback li {
68
  display: flex;
69
  align-items: center;
127
  width: 100%;
128
  }
129
 
130
+ .ao-feedback .buttons input:nth-child(2) {
131
+ margin: auto;
132
+ }
133
+
134
  .ao-feedback .buttons input:last-child {
135
  margin-left: auto;
136
  }
classes/static/exit-survey/exit-survey.js CHANGED
@@ -8,7 +8,9 @@
8
  $('#ao_uninstall_feedback_popup').appendTo($(targetElement).parent());
9
 
10
  $(targetElement).on('click', function (e) {
11
- e.preventDefault();
 
 
12
  $('#ao_uninstall_feedback_popup ').addClass('active');
13
  $('body').addClass('ao-feedback-open');
14
  $('.ao-feedback-overlay').on('click', function () {
@@ -24,6 +26,7 @@
24
 
25
  $('#ao_uninstall_feedback_popup input[type="radio"]').on('change', function () {
26
  var radio = $(this);
 
27
  if (radio.parent().find('textarea').length > 0 &&
28
  radio.parent().find('textarea').val().length === 0) {
29
  $('#ao_uninstall_feedback_popup #ao-deactivate-yes').attr('disabled', 'disabled');
@@ -36,6 +39,7 @@
36
  });
37
  } else {
38
  $('#ao_uninstall_feedback_popup #ao-deactivate-yes').removeAttr('disabled');
 
39
  }
40
  });
41
 
@@ -50,6 +54,13 @@
50
  }
51
  });
52
 
 
 
 
 
 
 
 
53
  $('#ao_uninstall_feedback_popup #ao-deactivate-yes').on('click', function (e) {
54
  e.preventDefault();
55
  e.stopPropagation();
@@ -72,6 +83,7 @@
72
  'reason': reason,
73
  'type': 'wordpress',
74
  'version' : $('#ao_plugin_version').text().trim(),
 
75
  };
76
  $.ajax({
77
  type: 'POST',
8
  $('#ao_uninstall_feedback_popup').appendTo($(targetElement).parent());
9
 
10
  $(targetElement).on('click', function (e) {
11
+ if ( false == e.target.href.includes('https://wordpress.org/') ) {
12
+ e.preventDefault();
13
+ }
14
  $('#ao_uninstall_feedback_popup ').addClass('active');
15
  $('body').addClass('ao-feedback-open');
16
  $('.ao-feedback-overlay').on('click', function () {
26
 
27
  $('#ao_uninstall_feedback_popup input[type="radio"]').on('change', function () {
28
  var radio = $(this);
29
+ $('p.last-attempt').hide();
30
  if (radio.parent().find('textarea').length > 0 &&
31
  radio.parent().find('textarea').val().length === 0) {
32
  $('#ao_uninstall_feedback_popup #ao-deactivate-yes').attr('disabled', 'disabled');
39
  });
40
  } else {
41
  $('#ao_uninstall_feedback_popup #ao-deactivate-yes').removeAttr('disabled');
42
+ $(this).siblings('p.last-attempt').show();
43
  }
44
  });
45
 
54
  }
55
  });
56
 
57
+ $('#ao_uninstall_feedback_popup #ao-deactivate-cancel').on('click', function (e) {
58
+ e.preventDefault();
59
+ e.stopPropagation();
60
+ $('#ao_uninstall_feedback_popup ').removeClass('active');
61
+ $('body').removeClass('ao-feedback-open');
62
+ });
63
+
64
  $('#ao_uninstall_feedback_popup #ao-deactivate-yes').on('click', function (e) {
65
  e.preventDefault();
66
  e.stopPropagation();
83
  'reason': reason,
84
  'type': 'wordpress',
85
  'version' : $('#ao_plugin_version').text().trim(),
86
+ 'email': $('#ao_feedback998').val().trim(),
87
  };
88
  $.ajax({
89
  type: 'POST',
readme.txt CHANGED
@@ -5,7 +5,7 @@ Donate link: http://blog.futtta.be/2013/10/21/do-not-donate-to-me/
5
  Requires at least: 4.9
6
  Tested up to: 5.8
7
  Requires PHP: 5.6
8
- Stable tag: 2.9.3
9
 
10
  Autoptimize speeds up your website by optimizing JS, CSS, images (incl. lazy-load), HTML and Google Fonts, asyncing JS, removing emoji cruft and more.
11
 
@@ -325,6 +325,13 @@ Just [fork Autoptimize on Github](https://github.com/futtta/autoptimize) and cod
325
 
326
  == Changelog ==
327
 
 
 
 
 
 
 
 
328
  = 2.9.3 =
329
  * Improvement: add logic to autoptimize_404_handler.php to differentiate between different multisite sites.
330
  * Improvement: remove the different feeds (and all JS to switch between them) on the settings-page, keeping only the "Autoptimize news".
5
  Requires at least: 4.9
6
  Tested up to: 5.8
7
  Requires PHP: 5.6
8
+ Stable tag: 2.9.4
9
 
10
  Autoptimize speeds up your website by optimizing JS, CSS, images (incl. lazy-load), HTML and Google Fonts, asyncing JS, removing emoji cruft and more.
11
 
325
 
326
  == Changelog ==
327
 
328
+ = 2.9.4 =
329
+ * Fix for 2 AMP compatibility issues (toolbar JS & lazyload JS).
330
+ * Fix for PHP notice in autoptimizeImages.php.
331
+ * Change default for "lazyload from nth image" from 0 to 2 (only applies to new installations).
332
+ * Improvements to the exit survey.
333
+ * Enjoy the end-of-year celebrations, there are great Autoptimize things to come in 2022! ;-)
334
+
335
  = 2.9.3 =
336
  * Improvement: add logic to autoptimize_404_handler.php to differentiate between different multisite sites.
337
  * Improvement: remove the different feeds (and all JS to switch between them) on the settings-page, keeping only the "Autoptimize news".