Skip to content

JavaScript module code inlined in PHP should be loaded from external JS files #1600

@westonruter

Description

@westonruter

Initially discussed in #1596 (comment).

There are a couple places where JS code is being inlined in PHP:

function image_prioritizer_get_lazy_load_script(): string {
return <<<JS
const lazyVideoObserver = new IntersectionObserver(
( entries ) => {
for ( const entry of entries ) {
if ( entry.isIntersecting ) {
/** @type {HTMLVideoElement} */
const video = entry.target;
if ( video.hasAttribute( 'data-original-poster' ) ) {
video.setAttribute( 'poster', video.getAttribute( 'data-original-poster' ) );
}
if ( video.hasAttribute( 'data-original-autoplay' ) ) {
video.setAttribute( 'autoplay', 'autoplay' );
}
if ( video.hasAttribute( 'data-original-preload' ) ) {
const preload = video.getAttribute( 'data-original-poster' );
if ( 'default' === preload ) {
video.removeAttribute( 'preload' );
} else {
video.setAttribute( 'preload', preload );
}
}
lazyVideoObserver.unobserve( video );
}
}
},
{
rootMargin: '100% 0% 100% 0%',
threshold: 0
}
);
const videos = document.querySelectorAll( 'video' );
for ( const video of videos ) {
lazyVideoObserver.observe( video );
}
JS;
}

function embed_optimizer_get_lazy_load_script(): string {
return <<<JS
const lazyEmbedsScripts = document.querySelectorAll( 'script[type="application/vnd.embed-optimizer.javascript"]' );
const lazyEmbedScriptsByParents = new Map();
const lazyEmbedObserver = new IntersectionObserver(
( entries ) => {
for ( const entry of entries ) {
if ( entry.isIntersecting ) {
const lazyEmbedParent = entry.target;
const lazyEmbedScript = /** @type {HTMLScriptElement} */ lazyEmbedScriptsByParents.get( lazyEmbedParent );
const embedScript = document.createElement( 'script' );
for ( const attr of lazyEmbedScript.attributes ) {
if ( attr.nodeName === 'type' ) {
// Omit type=application/vnd.embed-optimizer.javascript type.
continue;
}
embedScript.setAttribute(
attr.nodeName === 'data-original-type' ? 'type' : attr.nodeName,
attr.nodeValue
);
}
lazyEmbedScript.replaceWith( embedScript );
lazyEmbedObserver.unobserve( lazyEmbedParent );
}
}
},
{
rootMargin: '100% 0% 100% 0%',
threshold: 0
}
);
for ( const lazyEmbedScript of lazyEmbedsScripts ) {
const lazyEmbedParent = /** @type {HTMLElement} */ lazyEmbedScript.parentNode;
lazyEmbedScriptsByParents.set( lazyEmbedParent, lazyEmbedScript );
lazyEmbedObserver.observe( lazyEmbedParent );
}
JS;
}

This is not ideal because the JS code does not get the benefit of linting or TypeScript checks (#1589). Instead, the JS should be moved to external JS files and then loaded via file_get_contents(). This is what core does in _print_emoji_detection_script() and print_embed_scripts().

This will also allow for the scripts to be minified once #1493 lands.

Metadata

Metadata

Assignees

No one assigned

    Labels

    [Plugin] Embed OptimizerIssues for the Embed Optimizer plugin (formerly Auto Sizes)[Plugin] Image PrioritizerIssues for the Image Prioritizer plugin (dependent on Optimization Detective)[Plugin] Optimization DetectiveIssues for the Optimization Detective plugin[Type] EnhancementA suggestion for improvement of an existing feature
    No fields configured for Enhancement.

    Projects

    Status

    Done 😃

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions