Scotts Web Dev Banner
Did you notice... every article on this site has an associated video? Consider subscribing to Scotts Web Dev on YouTube! :)

How to embed YouTube videos on WordPress without affecting PageSpeed

Youtube Videos: They are great, but they slow your page down greatly.

In this video, I show you how to load a youtube video/embed in your wordpress page or post, without negatively affecting your PageSpeed score.

Just one youtube video, loaded the normal way in gutenberg editor can drop your pagespeed score by 60 points or more. Multiple youtube videos will be worse.

Using this method, we only load the video when a user scrolls or moves their mouse. There will be a placeholder that you can style in the case a user does not move their mouse.

We do this by creating a shortcode called load_youtube and setting the data-src of the youtube iframe instead of src. Then, we have javascript switch out the data-src for src.

Part 1: Edit functions.php (or another globally included file) and add the load_youtube shortcode:

Add this shortcode function to functions.php of your theme or another globally included file. It’s fine to load this at the bottom of functions.php, before any closing php tag (?>) if there is one.

/**
 * Scottsweb.dev function to lazy load youtube videos to not load until user interaction.
 * This is helpful when youtube videos are above the fold.  You could modify this to 
 * include an image or placeholder as well.
 * 
 * @param string $shortcode - attributes of the shortcode
 * 
 * @package https://scottsweb.dev
 */
function scottswebdev_load_youtube($shortcode) {

	// Set default attributes for src.
	$shortcode = shortcode_atts(
		array('src' => ''),
		$shortcode,
		'load_youtube'
	);

	// Replace the watch string with embed string.
	$url = str_replace('watch?v=', 'embed/', $shortcode['src']);

	// Create a string to return.
	$out = '<div class="scottswebdev-youtube">
		<iframe class="scottswebdev-youtube-iframe" width="560" height="315" 
			data-src="' . $url . '" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen style="background-color: #aeaeae;">
		</iframe>
	</div>';

	// Return it.
    return $out;
}

// Add the shortcode for load_youtube
add_shortcode('load_youtube', 'scottswebdev_load_youtube');

Part 2: The javascript

Include this javascript snippet in a place where it will get executed on the pages containing your videos. This can be in footer.php or header.php or using a code snippets plugin like I did in the video:

<script>
/**
 * Scottsweb.dev
 * Load youtube videos on user interaction (scroll, mousemove).  This is helpful when 
 * youtube videos are above the fold and you can't load them using intersection observer
 */
let youtubes_loaded = false;
function swd_load_youtubes() {
	if (!youtubes_loaded) {
		let swd_youtubes = document.querySelectorAll('iframe.scottswebdev-youtube-iframe');
		if (swd_youtubes.length) {
			swd_youtubes.forEach(swd_yt => {
				swd_yt.setAttribute('src', swd_yt.getAttribute('data-src'));
			});
		}
		youtubes_loaded = true;
	}
}
	
document.addEventListener('DOMContentLoaded', function() {
	window.addEventListener('scroll', swd_load_youtubes);
	window.addEventListener('mousemove', swd_load_youtubes);
});
</script>

Part 3: Edit your post/page and use the new shortcode

Type /shortcode and get a shortcode block going in Gutenberg editor. Once you do that, simply type your new shortcode, replacing YOURURLHERE with your video url from youtube.

[load_youtube src="YOURURLHERE"]

Extra note: Use the “watch” version of your video and not the embed url. Your url should include /watch?v= in it.