Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add oEmbed optimizer module #886

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
2fc3745
Missing file doc comment (Squiz.Commenting.FileComment.Missing)
adamsilverstein Nov 22, 2023
557933b
Add oEmbed Optimize module
adamsilverstein Nov 22, 2023
13308cd
resore composer.lock
adamsilverstein Nov 22, 2023
d65e170
cleanup
adamsilverstein Nov 22, 2023
aaeb1be
improve docblocks
adamsilverstein Nov 22, 2023
4001a0a
improve docblocks 2
adamsilverstein Nov 22, 2023
21f2908
Process oEmbeds with WP_HTML_Tag_Processor
adamsilverstein Nov 24, 2023
1ed01e0
Correct namespace prefix
adamsilverstein Nov 24, 2023
4ce1610
remove unused observer parameter
adamsilverstein Nov 24, 2023
9eab381
single WP_HTML_Tag_Processor loop
adamsilverstein Nov 27, 2023
3701f2d
remove extraneous is_string check
adamsilverstein Nov 28, 2023
b96f6f6
add translations
adamsilverstein Nov 29, 2023
3fdfdc2
Update modules/js-and-css/optimize-oembeds/hooks.php
adamsilverstein Dec 15, 2023
0405547
Update modules/js-and-css/optimize-oembeds/hooks.php
adamsilverstein Dec 15, 2023
333179f
Merge branch 'trunk' into add/optimize-oembeds
adamsilverstein Dec 20, 2023
8f64e33
Update modules/js-and-css/optimize-oembeds/hooks.php
adamsilverstein Jan 23, 2024
3c03658
refine logic for iframe and script lazy loading
adamsilverstein Jan 23, 2024
d5532cd
Merge branch 'trunk' into add/optimize-oembeds
adamsilverstein Jan 23, 2024
c3f54a7
remove duplicate line
adamsilverstein Jan 23, 2024
5995820
Update modules/js-and-css/optimize-oembeds/hooks.php
adamsilverstein Jan 24, 2024
1408cce
Update modules/js-and-css/optimize-oembeds/hooks.php
adamsilverstein Jan 24, 2024
8a935a2
Update modules/js-and-css/optimize-oembeds/hooks.php
adamsilverstein Jan 24, 2024
3b76392
Update modules/js-and-css/optimize-oembeds/hooks.php
adamsilverstein Jan 24, 2024
bbc8c4a
Update modules/js-and-css/optimize-oembeds/hooks.php
adamsilverstein Jan 24, 2024
c5489be
Update modules/js-and-css/optimize-oembeds/hooks.php
adamsilverstein Jan 24, 2024
db2fa87
Update modules/js-and-css/optimize-oembeds/hooks.php
adamsilverstein Jan 24, 2024
c9ad936
Update modules/js-and-css/optimize-oembeds/hooks.php
adamsilverstein Jan 24, 2024
d28a02e
Update modules/js-and-css/optimize-oembeds/hooks.php
adamsilverstein Jan 25, 2024
3ed4911
Update modules/js-and-css/optimize-oembeds/hooks.php
adamsilverstein Jan 26, 2024
3dc5ef5
Merge branch 'trunk' into add/optimize-oembeds
adamsilverstein Jan 26, 2024
dd54710
Merge branch 'trunk' into add/optimize-oembeds
adamsilverstein Jan 30, 2024
7920a20
Update modules/js-and-css/optimize-oembeds/hooks.php
adamsilverstein Feb 7, 2024
8dd0382
Merge branch 'trunk' into add/optimize-oembeds
adamsilverstein Feb 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions module-i18n.php
Expand Up @@ -9,6 +9,8 @@
_x( 'Creates WebP versions for new JPEG image uploads if supported by the server.', 'module description', 'performance-lab' ),
_x( 'Enqueued Assets Health Check', 'module name', 'performance-lab' ),
_x( 'Adds a CSS and JS resource check in Site Health status.', 'module description', 'performance-lab' ),
_x( 'oEmbed Optimizer', 'module name', 'performance-lab' ),
_x( 'Optimize oEmbed loading with improved lazy loading.', 'module description', 'performance-lab' ),
_x( 'Autoloaded Options Health Check', 'module name', 'performance-lab' ),
_x( 'Adds a check for autoloaded options in Site Health status.', 'module description', 'performance-lab' ),
);
Expand Down
115 changes: 115 additions & 0 deletions modules/js-and-css/optimize-oembeds/hooks.php
@@ -0,0 +1,115 @@
<?php
/**
* Hook callbacks used for oEmbed Optimizer.
*
* @since n.e.x.t
* @package performance-lab
*/

if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}

/**
* Filter the oEmbed HTML.
*
* Add loading="lazy" to any iframe tags.
* Lazy load any script tags.
*
* @since n.e.x.t
*
* @param string $html The oEmbed HTML.
* @return string
*/
function perflab_optimize_oembed_html( string $html ): string {
$p = new WP_HTML_Tag_Processor( $html );

/**
* Determine how to lazy load the embed.
*
* - If there is only one iframe, set loading="lazy".
* - Prevent making scripts lazy if there is an inline script.
* - Only make script lazy if there is a single external script (since if there are
* multiple they may not get loaded in the right order).
* - Ensure that both the iframe and the script are made lazy if both occur in the same embed.
*/
$iframe_count = 0;
$script_count = 0;
$has_inline_script = false;
// Locate the iframes and scripts.
while ( $p->next_tag() ) {
if ( 'IFRAME' === $p->get_tag() ) {
$loading_value = $p->get_attribute( 'loading' );
if ( empty( $loading_value ) ) {
++$iframe_count;
$p->set_bookmark( 'iframe' );
}
} elseif ( 'SCRIPT' === $p->get_tag() ) {
adamsilverstein marked this conversation as resolved.
Show resolved Hide resolved
if ( ! $p->get_attribute( 'src' ) ) {
$has_inline_script = true;
} else {
++$script_count;
$p->set_bookmark( 'script' );
}
}
}
// If there was only one non-inline script, make it lazy.
if ( 1 === $script_count && ! $has_inline_script ) {
add_action( 'wp_footer', 'perflab_optimize_oembed_lazy_load_scripts' );
$p->seek( 'script' );
$p->set_attribute( 'data-lazy-embed-src', $p->get_attribute( 'src' ) );
$p->remove_attribute( 'src' );
}
adamsilverstein marked this conversation as resolved.
Show resolved Hide resolved
// If there was only one iframe, make it lazy.
if ( 1 === $iframe_count ) {
$p->seek( 'iframe' );
$p->set_attribute( 'loading', 'lazy' );
}
return $p->get_updated_html();
}
add_filter( 'embed_oembed_html', 'perflab_optimize_oembed_html' );

/**
* Add a script to the footer if there are lazy loaded embeds.
* Load the embed's scripts when they approach the viewport using an IntersectionObserver.
*
* @since n.e.x.t
*/
function perflab_optimize_oembed_lazy_load_scripts() {
?>
<script type="module">
const lazyEmbedsScripts = document.querySelectorAll( 'script[data-lazy-embed-src]' );
const lazyEmbedScriptsByParents = new Map();

const lazyEmbedObserver = new IntersectionObserver(
( entries ) => {
for ( const entry of entries ) {
if ( entry.isIntersecting ) {
const lazyEmbedParent = entry.target;
const lazyEmbedScript = lazyEmbedScriptsByParents.get( lazyEmbedParent );
const embedScript = document.createElement( 'script' );
for ( const attr of lazyEmbedScript.attributes ) {
embedScript.setAttribute(
attr.nodeName === 'data-lazy-embed-src' ? 'src' : attr.nodeName,
attr.nodeValue
);
}
lazyEmbedScript.replaceWith( embedScript );
lazyEmbedObserver.unobserve( lazyEmbedParent );
}
}
},
{
rootMargin: '100% 0% 100% 0%',
threshold: 0
}
);

for ( const lazyEmbedScript of lazyEmbedsScripts ) {
const lazyEmbedParent = lazyEmbedScript.parentNode;
lazyEmbedScriptsByParents.set( lazyEmbedParent, lazyEmbedScript );
lazyEmbedObserver.observe( lazyEmbedParent );
}
</script>
<?php
}
12 changes: 12 additions & 0 deletions modules/js-and-css/optimize-oembeds/load.php
@@ -0,0 +1,12 @@
<?php
/**
* Module Name: oEmbed Optimizer
* Description: Optimize oEmbed loading with improved lazy loading.
* Experimental: Yes
*
* @since n.e.x.t
* @package performance-lab
*/

// Load in the oEmbed Optimizer module hooks.
require_once __DIR__ . '/hooks.php';