Skip to content

Instantly share code, notes, and snippets.

@erikyo
Created March 25, 2024 06:34
Show Gist options
  • Save erikyo/8e38a9bdeddfc3fea315399c0107ff09 to your computer and use it in GitHub Desktop.
Save erikyo/8e38a9bdeddfc3fea315399c0107ff09 to your computer and use it in GitHub Desktop.
Wordpress background and video lazy load
<?php
/**
* Lazy load background images and videos in Gutenberg blocks
* @param $block - the block
* @param $parsed - the parsed block data
* @return array|mixed|string|string[]|null
*/
function vsge_lazy_cover( $block, $parsed ) {
// Check if the 'url' attribute is set
if ( isset( $parsed['attrs']['url'] ) ) {
$has_parallax = isset( $parsed['attrs']['hasParallax'] ) && (int) $parsed['attrs']['hasParallax'] == 1;
$has_video = isset($parsed['attrs']['backgroundType']) && $parsed['attrs']['backgroundType'] == 'video';
if ( $has_parallax || $has_video ) {
// Get the URL of the background image
$url = $parsed['attrs']['url'];
// Placeholder image URL
$placeholder = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';
// Add the 'data-background' attribute with the original URL to the same div containing the background image URL
$block = str_replace( $url, $placeholder, $block );
// Replace the background image URL with the placeholder
if ($has_parallax) {
$block = preg_replace('/<div\s*class="(.+?)"\s*style="(.+?)background-image\s*:\s*url\((.*?)\)(.*?)>/', '<div class="$1 lazy-background" style="$2background-image:url($3);$4" data-background="' . $url . '">', $block);
} else if ($has_video) {
$block = preg_replace('/<video\s*class="(.+?)"\s*(.*?)src="(.*?)"(.*?)>/', '<video class="$1 lazy-background lazy-video" $2data-background="'.$url.'"$4>', $block);
}
}
}
return $block;
}
add_filter( 'render_block_core/cover', 'vsge_lazy_cover', 16, 3 );
/**
* Lazy load js stuff
*/
add_action( "wp_footer", function () {
?>
<script>
const lazyBackgrounds = document.querySelectorAll('[data-background]');
if ('IntersectionObserver' in window) {
const lazyBackgroundObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(entry => {
if (entry.isIntersecting) {
const lazyBackground = entry.target;
if (lazyBackground.classList.contains('lazy-video')) {
console.log('lazy-background');
lazyBackground.src = lazyBackground.dataset.background;
} else {
lazyBackground.style.backgroundImage = `url(${lazyBackground.dataset.background})`;
}
lazyBackground.classList.add('lazy-background-on');
observer.unobserve(lazyBackground);
}
});
});
lazyBackgrounds.forEach(lazyBackground => {
lazyBackgroundObserver.observe(lazyBackground);
});
} else {
// Fallback for browsers that don't support Intersection Observer
lazyBackgrounds.forEach(lazyBackground => {
lazyBackground.style.backgroundImage = `url(${lazyBackground.dataset.background})`;
lazyBackground.classList.remove('lazy-background');
lazyBackground.classList.add('lazy-background-failed');
lazyBackground.removeAttribute('data-background');
});
}
</script>
<?php
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment