Autoptimize - Version 2.8.1

Version Description

  • Images: new option not to lazyload first X images
  • fix for "array to string" conversion errors in image optimization logic of .ico files
  • switch jQuery shorthand .click (in toolbar JS & PaND dismiss notice JS) to please jQuery Migrate helper (and because it's better that way)
Download this release

Release Info

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

Code changes from version 2.8.0 to 2.8.1

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.8.0
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.8.0' );
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.8.1
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.8.1' );
25
 
26
  // plugin_dir_path() returns the trailing slash!
27
  define( 'AUTOPTIMIZE_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
classes/autoptimizeConfig.php CHANGED
@@ -808,6 +808,8 @@ echo __( 'A comma-separated list of CSS you want to exclude from being optimized
808
  'autoptimize_imgopt_checkbox_field_3' => '0', // lazy load off.
809
  'autoptimize_imgopt_checkbox_field_4' => '0', // webp off (might be removed).
810
  'autoptimize_imgopt_text_field_5' => '', // lazy load exclusions empty.
 
 
811
  );
812
  return $defaults;
813
  }
808
  'autoptimize_imgopt_checkbox_field_3' => '0', // lazy load off.
809
  'autoptimize_imgopt_checkbox_field_4' => '0', // webp off (might be removed).
810
  'autoptimize_imgopt_text_field_5' => '', // lazy load exclusions empty.
811
+ 'autoptimize_imgopt_text_field_6' => '', // optimization exclusions empty.
812
+ 'autoptimize_imgopt_number_field_7' => '0', // lazy load from nth image (0 = lazyload all).
813
  );
814
  return $defaults;
815
  }
classes/autoptimizeCriticalCSSSettings.php CHANGED
@@ -160,7 +160,7 @@ class autoptimizeCriticalCSSSettings {
160
  ?>
161
  <div class="notice-warning notice"><p>
162
  <?php
163
- _e( "Oops! Please <strong>activate the \"Inline and Defer CSS\" option</strong> on Autoptimize's main settings page ensure critical CSS is used on the front-end.", 'autoptimize' );
164
  ?>
165
  </p></div>
166
  <?php
160
  ?>
161
  <div class="notice-warning notice"><p>
162
  <?php
163
+ _e( "Oops! Please <strong>activate the \"Inline and Defer CSS\" option</strong> on Autoptimize's main settings page to ensure critical CSS is used on the front-end.", 'autoptimize' );
164
  ?>
165
  </p></div>
166
  <?php
classes/autoptimizeImages.php CHANGED
@@ -399,7 +399,7 @@ class autoptimizeImages
399
  return $imgopt_base_url;
400
  }
401
 
402
- private function can_optimize_image( $url, $tag = '' )
403
  {
404
  static $cdn_url = null;
405
  static $nopti_images = null;
@@ -411,7 +411,7 @@ class autoptimizeImages
411
  );
412
  }
413
 
414
- if ( null === $nopti_images ) {
415
  if ( is_array( $this->options ) && array_key_exists( 'autoptimize_imgopt_text_field_6', $this->options ) ) {
416
  $nopti_images = $this->options['autoptimize_imgopt_text_field_6'];
417
  }
@@ -513,11 +513,11 @@ class autoptimizeImages
513
  if ( strpos( $matches[1], '.ico' ) === false ) {
514
  return $this->replace_img_callback( $matches, $width, $height );
515
  } else {
516
- return $matches;
517
  }
518
  }
519
 
520
- public function filter_optimize_images( $in )
521
  {
522
  /*
523
  * potential future functional improvements:
@@ -554,7 +554,7 @@ class autoptimizeImages
554
  if ( isset( $indiv_srcset_parts[1] ) && rtrim( $indiv_srcset_parts[1], 'w' ) !== $indiv_srcset_parts[1] ) {
555
  $imgopt_w = rtrim( $indiv_srcset_parts[1], 'w' );
556
  }
557
- if ( $this->can_optimize_image( $indiv_srcset_parts[0], $tag ) ) {
558
  $imgopt_url = $this->build_imgopt_url( $indiv_srcset_parts[0], $imgopt_w, '' );
559
  $srcset = str_replace( $indiv_srcset_parts[0], $imgopt_url, $srcset );
560
  }
@@ -574,7 +574,7 @@ class autoptimizeImages
574
  foreach ( $urls as $url ) {
575
  $full_src_orig = $url[0];
576
  $url = $url[1];
577
- if ( $this->can_optimize_image( $url, $full_src_orig ) ) {
578
  $imgopt_url = $this->build_imgopt_url( $url, $imgopt_w, $imgopt_h );
579
  $full_imgopt_src = str_replace( $url, $imgopt_url, $full_src_orig );
580
  $tag = str_replace( $full_src_orig, $full_imgopt_src, $tag );
@@ -596,7 +596,7 @@ class autoptimizeImages
596
  $_url = $this->normalize_img_url( $_url );
597
 
598
  $placeholder = '';
599
- if ( $this->can_optimize_image( $_url, $tag ) && apply_filters( 'autoptimize_filter_imgopt_lazyload_dolqip', true ) ) {
600
  $lqip_w = '';
601
  $lqip_h = '';
602
  if ( isset( $imgopt_w ) && ! empty( $imgopt_w ) ) {
@@ -770,7 +770,8 @@ class autoptimizeImages
770
  public function add_lazyload( $tag, $placeholder = '' ) {
771
  // adds actual lazyload-attributes to an image node.
772
  $this->lazyload_counter++;
773
- if ( str_ireplace( $this->get_lazyload_exclusions(), '', $tag ) === $tag && $this->lazyload_counter >= apply_filters( 'autoptimize_filter_imgopt_lazyload_from_nth', 0 ) ) {
 
774
  $tag = $this->maybe_fix_missing_quotes( $tag );
775
 
776
  // store original tag for use in noscript version.
@@ -1165,10 +1166,16 @@ class autoptimizeImages
1165
  <label><input type='checkbox' id='autoptimize_imgopt_lazyload_checkbox' name='autoptimize_imgopt_settings[autoptimize_imgopt_checkbox_field_3]' <?php if ( ! empty( $options['autoptimize_imgopt_checkbox_field_3'] ) && '1' === $options['autoptimize_imgopt_checkbox_field_3'] ) { echo 'checked="checked"'; } ?> value='1'><?php _e( 'Image lazy-loading will delay the loading of non-visible images to allow the browser to optimally load all resources for the "above the fold"-page first.', 'autoptimize' ); ?></label>
1166
  </td>
1167
  </tr>
1168
- <tr id='autoptimize_imgopt_lazyload_exclusions' <?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="hidden"'; } ?>>
1169
  <th scope="row"><?php _e( 'Lazy-load exclusions', 'autoptimize' ); ?></th>
1170
  <td>
1171
- <label><input type='text' style='width:80%' id='autoptimize_imgopt_lazyload_exclusions' name='autoptimize_imgopt_settings[autoptimize_imgopt_text_field_5]' value='<?php if ( ! empty( $options['autoptimize_imgopt_text_field_5'] ) ) { echo esc_attr( $options['autoptimize_imgopt_text_field_5'] ); } ?>'><br /><?php _e( 'Comma-separated list of to be excluded image classes or filenames.', 'autoptimize' ); ?></label>
 
 
 
 
 
 
1172
  </td>
1173
  </tr>
1174
  </table>
@@ -1190,14 +1197,14 @@ class autoptimizeImages
1190
  jQuery("#autoptimize_imgopt_ngimg_checkbox").change(function() {
1191
  if (this.checked) {
1192
  jQuery("#autoptimize_imgopt_lazyload_checkbox")[0].checked = true;
1193
- jQuery("#autoptimize_imgopt_lazyload_exclusions").show("slow");
1194
  }
1195
  });
1196
  jQuery("#autoptimize_imgopt_lazyload_checkbox").change(function() {
1197
  if (this.checked) {
1198
- jQuery("#autoptimize_imgopt_lazyload_exclusions").show("slow");
1199
  } else {
1200
- jQuery("#autoptimize_imgopt_lazyload_exclusions").hide("slow");
1201
  jQuery("#autoptimize_imgopt_ngimg_checkbox")[0].checked = false;
1202
  }
1203
  });
399
  return $imgopt_base_url;
400
  }
401
 
402
+ private function can_optimize_image( $url, $tag = '', $testing = false )
403
  {
404
  static $cdn_url = null;
405
  static $nopti_images = null;
411
  );
412
  }
413
 
414
+ if ( null === $nopti_images || $testing ) {
415
  if ( is_array( $this->options ) && array_key_exists( 'autoptimize_imgopt_text_field_6', $this->options ) ) {
416
  $nopti_images = $this->options['autoptimize_imgopt_text_field_6'];
417
  }
513
  if ( strpos( $matches[1], '.ico' ) === false ) {
514
  return $this->replace_img_callback( $matches, $width, $height );
515
  } else {
516
+ return $matches[0];
517
  }
518
  }
519
 
520
+ public function filter_optimize_images( $in, $testing = false )
521
  {
522
  /*
523
  * potential future functional improvements:
554
  if ( isset( $indiv_srcset_parts[1] ) && rtrim( $indiv_srcset_parts[1], 'w' ) !== $indiv_srcset_parts[1] ) {
555
  $imgopt_w = rtrim( $indiv_srcset_parts[1], 'w' );
556
  }
557
+ if ( $this->can_optimize_image( $indiv_srcset_parts[0], $tag, $testing ) ) {
558
  $imgopt_url = $this->build_imgopt_url( $indiv_srcset_parts[0], $imgopt_w, '' );
559
  $srcset = str_replace( $indiv_srcset_parts[0], $imgopt_url, $srcset );
560
  }
574
  foreach ( $urls as $url ) {
575
  $full_src_orig = $url[0];
576
  $url = $url[1];
577
+ if ( $this->can_optimize_image( $url, $full_src_orig, $testing ) ) {
578
  $imgopt_url = $this->build_imgopt_url( $url, $imgopt_w, $imgopt_h );
579
  $full_imgopt_src = str_replace( $url, $imgopt_url, $full_src_orig );
580
  $tag = str_replace( $full_src_orig, $full_imgopt_src, $tag );
596
  $_url = $this->normalize_img_url( $_url );
597
 
598
  $placeholder = '';
599
+ if ( $this->can_optimize_image( $_url, $tag ) && apply_filters( 'autoptimize_filter_imgopt_lazyload_dolqip', true, $_url ) ) {
600
  $lqip_w = '';
601
  $lqip_h = '';
602
  if ( isset( $imgopt_w ) && ! empty( $imgopt_w ) ) {
770
  public function add_lazyload( $tag, $placeholder = '' ) {
771
  // adds actual lazyload-attributes to an image node.
772
  $this->lazyload_counter++;
773
+ $_lazyload_from_nth = apply_filters( 'autoptimize_filter_imgopt_lazyload_from_nth', $this->options['autoptimize_imgopt_number_field_7'] );
774
+ if ( str_ireplace( $this->get_lazyload_exclusions(), '', $tag ) === $tag && $this->lazyload_counter >= $_lazyload_from_nth ) {
775
  $tag = $this->maybe_fix_missing_quotes( $tag );
776
 
777
  // store original tag for use in noscript version.
1166
  <label><input type='checkbox' id='autoptimize_imgopt_lazyload_checkbox' name='autoptimize_imgopt_settings[autoptimize_imgopt_checkbox_field_3]' <?php if ( ! empty( $options['autoptimize_imgopt_checkbox_field_3'] ) && '1' === $options['autoptimize_imgopt_checkbox_field_3'] ) { echo 'checked="checked"'; } ?> value='1'><?php _e( 'Image lazy-loading will delay the loading of non-visible images to allow the browser to optimally load all resources for the "above the fold"-page first.', 'autoptimize' ); ?></label>
1167
  </td>
1168
  </tr>
1169
+ <tr id='autoptimize_imgopt_lazyload_exclusions' <?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"'; } ?>>
1170
  <th scope="row"><?php _e( 'Lazy-load exclusions', 'autoptimize' ); ?></th>
1171
  <td>
1172
+ <label><input type='text' style='width:80%' id='autoptimize_imgopt_lazyload_exclusions_text' name='autoptimize_imgopt_settings[autoptimize_imgopt_text_field_5]' value='<?php if ( ! empty( $options['autoptimize_imgopt_text_field_5'] ) ) { echo esc_attr( $options['autoptimize_imgopt_text_field_5'] ); } ?>'><br /><?php _e( 'Comma-separated list of to be excluded image classes or filenames.', 'autoptimize' ); ?></label>
1173
+ </td>
1174
+ </tr>
1175
+ <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"'; } ?>>
1176
+ <th scope="row"><?php _e( 'Lazy-load from nth image', 'autoptimize' ); ?></th>
1177
+ <td>
1178
+ <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>
1179
  </td>
1180
  </tr>
1181
  </table>
1197
  jQuery("#autoptimize_imgopt_ngimg_checkbox").change(function() {
1198
  if (this.checked) {
1199
  jQuery("#autoptimize_imgopt_lazyload_checkbox")[0].checked = true;
1200
+ jQuery(".autoptimize_lazyload_child").show("slow");
1201
  }
1202
  });
1203
  jQuery("#autoptimize_imgopt_lazyload_checkbox").change(function() {
1204
  if (this.checked) {
1205
+ jQuery(".autoptimize_lazyload_child").show("slow");
1206
  } else {
1207
+ jQuery(".autoptimize_lazyload_child").hide("slow");
1208
  jQuery("#autoptimize_imgopt_ngimg_checkbox")[0].checked = false;
1209
  }
1210
  });
classes/external/php/persist-admin-notices-dismissal/dismiss-notice.js CHANGED
@@ -2,7 +2,7 @@
2
  //shorthand for ready event.
3
  $(
4
  function () {
5
- $( 'div[data-dismissible] button.notice-dismiss' ).click(
6
  function (event) {
7
  event.preventDefault();
8
  var $this = $( this );
2
  //shorthand for ready event.
3
  $(
4
  function () {
5
+ $( 'div[data-dismissible] button.notice-dismiss' ).on('click',
6
  function (event) {
7
  event.preventDefault();
8
  var $this = $( this );
classes/static/toolbar.js CHANGED
@@ -13,7 +13,7 @@ jQuery( document ).ready(function()
13
  jQuery( '#wp-admin-bar-autoptimize-cache-info .autoptimize-radial-bar .inset' ).css( 'background-color', jQuery( '#wp-admin-bar-autoptimize .ab-sub-wrapper' ).css( 'background-color') );
14
  jQuery( '#wp-admin-bar-autoptimize-delete-cache .ab-item' ).css( 'background-color', jQuery( '#wpadminbar' ).css( 'background-color') );
15
 
16
- jQuery( '#wp-admin-bar-autoptimize-default li' ).click(function(e)
17
  {
18
  var id = ( typeof e.target.id != 'undefined' && e.target.id ) ? e.target.id : jQuery( e.target ).parent( 'li' ).attr( 'id' );
19
  var action = '';
13
  jQuery( '#wp-admin-bar-autoptimize-cache-info .autoptimize-radial-bar .inset' ).css( 'background-color', jQuery( '#wp-admin-bar-autoptimize .ab-sub-wrapper' ).css( 'background-color') );
14
  jQuery( '#wp-admin-bar-autoptimize-delete-cache .ab-item' ).css( 'background-color', jQuery( '#wpadminbar' ).css( 'background-color') );
15
 
16
+ jQuery( '#wp-admin-bar-autoptimize-default li' ).on('click', function(e)
17
  {
18
  var id = ( typeof e.target.id != 'undefined' && e.target.id ) ? e.target.id : jQuery( e.target ).parent( 'li' ).attr( 'id' );
19
  var action = '';
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: futtta, optimizingmatters, zytzagoo, turl
3
  Tags: optimize, minify, performance, pagespeed, images, lazy-load, google fonts
4
  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.6
7
  Requires PHP: 5.6
8
- Stable tag: 2.8.0
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
 
@@ -45,9 +45,9 @@ HTTP/2 is a great step forward for sure, reducing the impact of multiple request
45
 
46
  Although Autoptimize comes without any warranties, it will in general work flawlessly if you configure it correctly. See "Troubleshooting" below for info on how to configure in case of problems.
47
 
48
- = Why is jquery.js not optimized =
49
 
50
- Starting from AO 2.1 WordPress core's jquery.js is not optimized for the simple reason a lot of popular plugins inject inline JS that is not aggregated either (due to possible cache size issues with unique code in inline JS) which relies on jquery being available, so excluding jquery.js ensures that most sites will work out of the box. If you want optimize jquery as well, you can remove it from the JS optimization exclusion-list (you might have to enable "also aggregate inline JS" as well or switch to "force JS in head").
51
 
52
  = Why is Autoptimized JS render blocking? =
53
 
@@ -140,8 +140,8 @@ If your blog doesn't function normally after having turned on Autoptimize, here
140
 
141
  * If all works but you notice your blog is slower, ensure you have a page caching plugin installed (WP Super Cache or similar) and check the info on cache size (the soution for that problem also impacts performance for uncached pages) in this FAQ as well.
142
  * In case your blog looks weird, i.e. when the layout gets messed up, there is problem with CSS optimization. Try excluding one or more CSS-files from being optimized. You can also force CSS not to be aggregated by wrapping it in noptimize-tags in your theme or widget or by adding filename (for external stylesheets) or string (for inline styles) to the exclude-list.
143
- * In case some functionality on your site stops working (a carroussel, a menu, the search input, ...) you're likely hitting JavaScript optimization trouble. Change the "Aggregate inline JS" and/ or "Force JavaScript in head?" settings and try again. Excluding 'js/jquery/jquery.js' from optimization (see below) and optionally activating "[Add try/catch wrapping](http://blog.futtta.be/2014/08/18/when-should-you-trycatch-javascript/)") can also help. Alternatively -for the technically savvy- you can exclude specific scripts from being treated (moved and/ or aggregated) by Autoptimize by adding a string that will match the offending Javascript or excluding it from within your template files or widgets by wrapping the code between noptimize-tags. Identifying the offending JavaScript and choosing the correct exclusion-string can be trial and error, but in the majority of cases JavaScript optimization issues can be solved this way. When debugging JavaScript issues, your browsers error console is the most important tool to help you understand what is going on.
144
- * If your theme or plugin require jQuery, you can try either forcing all in head and/ or excluding jquery.js (and jQuery-plugins if needed).
145
  * If you can't get either CSS or JS optimization working, you can off course always continue using the other two optimization-techniques.
146
  * If you tried the troubleshooting tips above and you still can't get CSS and JS working at all, you can ask for support on the [WordPress Autoptimize support forum](http://wordpress.org/support/plugin/autoptimize). See below for a description of what information you should provide in your "trouble ticket"
147
 
@@ -187,11 +187,11 @@ Disable the option to optimize cart/ checkout pages (works for WooCommerce, Easy
187
 
188
  = Revolution Slider is broken! =
189
 
190
- Make sure `js/jquery/jquery.js` is in the comma-separated list of JS optimization exclusions (this is excluded in the default configuration).
191
 
192
  = I'm getting "jQuery is not defined" errors =
193
 
194
- In that case you have un-aggregated JavaScript that requires jQuery to be loaded, so you'll have to add `js/jquery/jquery.js` to the comma-separated list of JS optimization exclusions.
195
 
196
  = I use NextGen Galleries and a lot of JS is not aggregated/ minified? =
197
 
@@ -238,7 +238,7 @@ Preconnect is a somewhat advanced feature to instruct browsers ([if they support
238
 
239
  = When can('t) I async JS? =
240
 
241
- JavaScript files that are not autoptimized (because they were excluded or because they are hosted elsewhere) are typically render-blocking. By adding them in the comma-separated "async JS" field, Autoptimize will add the async flag causing the browser to load those files asynchronously (i.e. non-render blocking). This can however break your site (page), e.g. if you async "js/jquery/jquery.js" you will very likely get "jQuery is not defined"-errors. Use with care.
242
 
243
  = How does image optimization work? =
244
 
@@ -319,6 +319,11 @@ Just [fork Autoptimize on Github](https://github.com/futtta/autoptimize) and cod
319
 
320
  == Changelog ==
321
 
 
 
 
 
 
322
  = 2.8.0 =
323
  * JavaScript: new option "defer but don't aggregate"
324
  * JavaScript: ensure Autoptimize also acts on jQuery in WordPress 5.6 which is renamed to jquery.min.js from jquery.js before.
3
  Tags: optimize, minify, performance, pagespeed, images, lazy-load, google fonts
4
  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.7
7
  Requires PHP: 5.6
8
+ Stable tag: 2.8.1
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
 
45
 
46
  Although Autoptimize comes without any warranties, it will in general work flawlessly if you configure it correctly. See "Troubleshooting" below for info on how to configure in case of problems.
47
 
48
+ = Why is jquery.min.js not optimized =
49
 
50
+ Starting from AO 2.1 WordPress core's jquery.min.js is not optimized for the simple reason a lot of popular plugins inject inline JS that is not aggregated either (due to possible cache size issues with unique code in inline JS) which relies on jquery being available, so excluding jquery.min.js ensures that most sites will work out of the box. If you want optimize jquery as well, you can remove it from the JS optimization exclusion-list (you might have to enable "also aggregate inline JS" as well or switch to "force JS in head").
51
 
52
  = Why is Autoptimized JS render blocking? =
53
 
140
 
141
  * If all works but you notice your blog is slower, ensure you have a page caching plugin installed (WP Super Cache or similar) and check the info on cache size (the soution for that problem also impacts performance for uncached pages) in this FAQ as well.
142
  * In case your blog looks weird, i.e. when the layout gets messed up, there is problem with CSS optimization. Try excluding one or more CSS-files from being optimized. You can also force CSS not to be aggregated by wrapping it in noptimize-tags in your theme or widget or by adding filename (for external stylesheets) or string (for inline styles) to the exclude-list.
143
+ * In case some functionality on your site stops working (a carroussel, a menu, the search input, ...) you're likely hitting JavaScript optimization trouble. Change the "Aggregate inline JS" and/ or "Force JavaScript in head?" settings and try again. Excluding 'js/jquery/jquery.min.js' from optimization (see below) and optionally activating "[Add try/catch wrapping](http://blog.futtta.be/2014/08/18/when-should-you-trycatch-javascript/)") can also help. Alternatively -for the technically savvy- you can exclude specific scripts from being treated (moved and/ or aggregated) by Autoptimize by adding a string that will match the offending Javascript or excluding it from within your template files or widgets by wrapping the code between noptimize-tags. Identifying the offending JavaScript and choosing the correct exclusion-string can be trial and error, but in the majority of cases JavaScript optimization issues can be solved this way. When debugging JavaScript issues, your browsers error console is the most important tool to help you understand what is going on.
144
+ * If your theme or plugin require jQuery, you can try either forcing all in head and/ or excluding jquery.min.js (and jQuery-plugins if needed).
145
  * If you can't get either CSS or JS optimization working, you can off course always continue using the other two optimization-techniques.
146
  * If you tried the troubleshooting tips above and you still can't get CSS and JS working at all, you can ask for support on the [WordPress Autoptimize support forum](http://wordpress.org/support/plugin/autoptimize). See below for a description of what information you should provide in your "trouble ticket"
147
 
187
 
188
  = Revolution Slider is broken! =
189
 
190
+ Make sure `js/jquery/jquery.min.js` is in the comma-separated list of JS optimization exclusions (this is excluded in the default configuration).
191
 
192
  = I'm getting "jQuery is not defined" errors =
193
 
194
+ In that case you have un-aggregated JavaScript that requires jQuery to be loaded, so you'll have to add `js/jquery/jquery.min.js` to the comma-separated list of JS optimization exclusions.
195
 
196
  = I use NextGen Galleries and a lot of JS is not aggregated/ minified? =
197
 
238
 
239
  = When can('t) I async JS? =
240
 
241
+ JavaScript files that are not autoptimized (because they were excluded or because they are hosted elsewhere) are typically render-blocking. By adding them in the comma-separated "async JS" field, Autoptimize will add the async flag causing the browser to load those files asynchronously (i.e. non-render blocking). This can however break your site (page), e.g. if you async "js/jquery/jquery.min.js" you will very likely get "jQuery is not defined"-errors. Use with care.
242
 
243
  = How does image optimization work? =
244
 
319
 
320
  == Changelog ==
321
 
322
+ = 2.8.1 =
323
+ * Images: new option not to lazyload first X images
324
+ * fix for "array to string" conversion errors in image optimization logic of .ico files
325
+ * switch jQuery shorthand .click (in toolbar JS & PaND dismiss notice JS) to please jQuery Migrate helper (and because it's better that way)
326
+
327
  = 2.8.0 =
328
  * JavaScript: new option "defer but don't aggregate"
329
  * JavaScript: ensure Autoptimize also acts on jQuery in WordPress 5.6 which is renamed to jquery.min.js from jquery.js before.