PluginProbe
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder / 2.10.0
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder v2.10.0
2.13.0 2.13.1 2.12.0 2.11.1 2.11.0 2.10.0 2.9.0 2.7.4 2.7.5 2.7.6 2.7.7 2.8.0 2.8.1 2.9.1 trunk 1.0 1.0-beta1 1.0-beta2 1.0-beta3 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 All 80 releases
ablocks / includes / performance / delay-js.php

delay-js.php in aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder 2.10.0, at includes/performance/delay-js.php

108 lines 3.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace ABlocks\Performance;
3
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit;
6 }
7
8 use ABlocks\Helper;
9
10 /**
11 * Performance Suite — delay JavaScript until the first user interaction.
12 *
13 * The aBlocks combined frontend script is emitted in a non-executing form and
14 * swapped in on the first interaction (scroll/key/pointer/touch) or after a
15 * fallback timeout, cutting main-thread work during initial load (INP/TBT).
16 *
17 * Opt-in via `perf_delay_js`. The handles affected are filterable so it stays
18 * scoped to aBlocks scripts (third-party JS is never touched).
19 */
20 class DelayJs {
21
22 public static function init() {
23 if ( is_admin() ) {
24 return;
25 }
26 $enabled = (bool) apply_filters(
27 'ablocks/perf/perf_delay_js',
28 (bool) Helper::get_settings( 'perf_delay_js', false )
29 );
30 if ( ! $enabled ) {
31 return;
32 }
33 // Never delay scripts for a logged-in editor viewing the frontend, so
34 // building/previewing the site is unaffected; real visitors still get it.
35 if ( is_user_logged_in() && current_user_can( 'edit_posts' )
36 && (bool) apply_filters( 'ablocks/perf/bypass_optimizations_for_editors', true ) ) {
37 return;
38 }
39 $self = new self();
40 add_filter( 'script_loader_tag', [ $self, 'delay_tag' ], 20, 3 );
41 add_action( 'wp_footer', [ $self, 'print_loader' ], 99 );
42 }
43
44 private function handles() {
45 return (array) apply_filters(
46 'ablocks/perf/delay_js_handles',
47 [ 'ablocks-blocks-combine-script' ]
48 );
49 }
50
51 /**
52 * Rewrite the target script tag so the browser doesn't execute it yet.
53 */
54 public function delay_tag( $tag, $handle, $src ) {
55 if ( ! $this->should_delay( $handle ) ) {
56 return $tag;
57 }
58 // Move src out of the way and mark the tag as delayed.
59 $tag = preg_replace( '/\ssrc=/', ' data-ablocks-src=', $tag, 1 );
60 $tag = preg_replace( '/^<script\s/', '<script type="ablocks/delayed" ', $tag, 1 );
61 return $tag;
62 }
63
64 /**
65 * Whether a script handle should be delayed. Covers the combined per-page
66 * script (assets-generation on) and the per-block frontend scripts
67 * (assets-generation off), so delay works in both modes.
68 */
69 private function should_delay( $handle ) {
70 if ( in_array( $handle, $this->handles(), true ) ) {
71 return true;
72 }
73 return (bool) preg_match( '/^ablocks-.+-block-static-script$/', (string) $handle );
74 }
75
76 /**
77 * Print the tiny vanilla loader that activates delayed scripts on interaction.
78 */
79 public function print_loader() {
80 $timeout = (int) Helper::get_settings( 'perf_delay_js_timeout', 5000 );
81 $timeout = max( 0, $timeout );
82 ?>
83 <script id="ablocks-delay-js-loader">
84 ( function () {
85 var loaded = false;
86 var events = [ 'scroll', 'keydown', 'pointerdown', 'touchstart', 'mousemove' ];
87 function load() {
88 if ( loaded ) { return; }
89 loaded = true;
90 events.forEach( function ( e ) { window.removeEventListener( e, load ); } );
91 document.querySelectorAll( 'script[type="ablocks/delayed"]' ).forEach( function ( s ) {
92 var n = document.createElement( 'script' );
93 var src = s.getAttribute( 'data-ablocks-src' );
94 if ( src ) { n.src = src; }
95 if ( s.id ) { n.id = s.id + '-delayed'; }
96 document.body.appendChild( n );
97 } );
98 }
99 events.forEach( function ( e ) { window.addEventListener( e, load, { passive: true, once: true } ); } );
100 <?php if ( $timeout > 0 ) : ?>
101 setTimeout( load, <?php echo (int) $timeout; ?> );
102 <?php endif; ?>
103 } )();
104 </script>
105 <?php
106 }
107 }
108