Skip to content

Commit

Permalink
Avoid error in deferred scripts.
Browse files Browse the repository at this point in the history
  • Loading branch information
fumikito committed Dec 3, 2020
1 parent a6b7e9a commit 227d2ed
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 48 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
.wp-env.json export-ignore
assets-lazy-loader.php export-ignore
package.json export-ignore
test.js export-ignore
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ Kunoichi\AssetsLazyLoader\ScriptsDefer::enable( [
] );
```

Some JavaScripts have following scripts via `wp_add_inline_script`. This may cause critical erros. `ScriptDefer` skips enqueued scripts with `after` section, but for more safety, consider allow list approach.

```php
Kunoichi\AssetsLazyLoader\ScriptsDefer::enable( [
// Defer scripts only which you know they are safe with defer attribute.
'exclude' => [ 'your-js', 'jquery' ],
] );
```


### CSS Preload

Add `rel="preload"` to `link` tag and fallback scripts.
Expand Down
2 changes: 1 addition & 1 deletion assets-lazy-loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

// Enqueue jQuery
add_action( 'wp_enqueue_scripts', function() {
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'assets-lazy-loader', plugins_url( 'test.js', __FILE__ ), [ 'jquery', 'wp-api-fetch' ], '1.0.0' );
} );

// Defer JS
Expand Down
53 changes: 53 additions & 0 deletions src/Kunoichi/AssetsLazyLoader/Pattern/HandleDetector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace Kunoichi\AssetsLazyLoader\Pattern;

/**
* Handle detector
*
* @package assets-lazy-loader
* @property-read string[] $exclude
* @property-read string[] $include
*/
abstract class HandleDetector extends Singleton {

/**
* Add extra arguments.
*
* @param array $args
* @return array
*/
protected function parse_args( $args ) {
return array_merge( [
'exclude' => [],
'include' => [],
], parent::parse_args( $args ) );
}

/**
* Check if handle is avilable.
*
* @param string $handle
* @return bool
*/
protected function is_valid_handle( $handle ) {
if ( ( ! $this->in_admin ) && is_admin() ) {
// If not in admin, skip.
return false;
}
if ( ( ! $this->in_login ) && $this->is_login() ) {
// If not in login, skip.
return false;
}
if ( $this->include ) {
// Allow list exists, check if it's included.
return in_array( $handle, (array) $this->include, true );
} elseif ( $this->exclude ) {
// Deny list exists, check if it's included.
return ! in_array( $handle, (array) $this->exclude, true );
} else {
return true;
}
}

}
54 changes: 31 additions & 23 deletions src/Kunoichi/AssetsLazyLoader/ScriptsDefer.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,19 @@
namespace Kunoichi\AssetsLazyLoader;


use Kunoichi\AssetsLazyLoader\Pattern\Singleton;
use Kunoichi\AssetsLazyLoader\Pattern\HandleDetector;

/**
* Defer JavaScripts
*
* @package assets-lazy-loader
* @property-read string[] $exclude
*/
class ScriptsDefer extends Singleton {
class ScriptsDefer extends HandleDetector {

/**
* Override parser
*
* @param array $args
*
* @return array
* @var string[] Critical scripts not to be deferred.
*/
protected function parse_args( $args ) {
return array_merge( [
'exclude' => [],
], parent::parse_args( $args ) );
}
protected $critical_scripts = [ 'wp-i18n' ];

/**
* Register filter hooks.
Expand All @@ -36,14 +27,6 @@ protected function init() {
define( 'CONCATENATE_SCRIPTS', false );
}
}
if ( ! $this->in_admin && is_admin() ) {
// This is admin and not in admin.
return;
}
if ( ! $this->in_login && $this->is_login() ) {
// This is login screen and not in login.
return;
}
// Filter script loader.
add_filter( 'script_loader_tag', [ $this, 'script_loader_tag' ], 9999, 2 );
}
Expand All @@ -56,8 +39,7 @@ protected function init() {
* @return string
*/
public function script_loader_tag( $tag, $handle ) {
// If this is excluded tag, skip.
if ( in_array( $handle, (array) $this->exclude, true ) ) {
if ( ! $this->is_valid_handle( $handle ) ) {
return $tag;
}
// Already having "defer" or "async", skip.
Expand All @@ -66,7 +48,33 @@ public function script_loader_tag( $tag, $handle ) {
return $tag;
}
}
// If critical, skip.
if ( in_array( $handle, $this->critical_scripts, true ) ) {
return $tag;
}
// Having after script, skip.
if ( $this->has_after( $handle ) ) {
return $tag;
}
// Add defer.
return str_replace( ' src=', ' defer src=', $tag );
}

/**
* If after script, skip.
*
* @param string $handle
* @return bool
*/
protected function has_after( $handle ) {
global $wp_scripts;
if ( ! isset( $wp_scripts->registered[ $handle ] ) ) {
return false;
}
$script = $wp_scripts->registered[ $handle ];
if ( ! empty( $script->extra['after'] ) ) {
return true;
}
return false;
}
}
27 changes: 3 additions & 24 deletions src/Kunoichi/AssetsLazyLoader/StyleLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
namespace Kunoichi\AssetsLazyLoader;


use Kunoichi\AssetsLazyLoader\Pattern\Singleton;
use Kunoichi\AssetsLazyLoader\Pattern\HandleDetector;

/**
* Style loader.
*
* @package assets-lazy-loader
* @property-read string[] $exclude
*/
class StyleLoader extends Singleton {
class StyleLoader extends HandleDetector {

/**
* @var bool If set preload at least 1, enable.
Expand All @@ -28,18 +27,6 @@ public static function admin_critical( $extra = [] ) {
return array_merge( [ 'login', 'common', 'admin-bar', 'admin-menu', 'dashboard' ], $extra );
}

/**
* Add extra arguments.
*
* @param array $args
* @return array
*/
protected function parse_args( $args ) {
return array_merge( [
'exclude' => [],
], parent::parse_args( $args ) );
}

/**
* Constructor.
*/
Expand Down Expand Up @@ -77,15 +64,7 @@ public function preload_helper() {
* @return string
*/
public function style_loader_tag( $tag, $handle, $href, $media ) {
if ( ( ! $this->in_admin ) && is_admin() ) {
// If not in admin, skip.
return $tag;
}
if ( ( ! $this->in_login ) && $this->is_login() ) {
// If not in login, skip.
return $tag;
}
if ( in_array( $handle, (array) $this->exclude, true ) ) {
if ( ! $this->is_valid_handle( $handle ) ) {
return $tag;
}
// If already preload or print, skip.
Expand Down
5 changes: 5 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/*!
* Description
*/

console.log( 'Assets Lazy Loader' );

0 comments on commit 227d2ed

Please sign in to comment.