Non-render-blocking YouTube embeds in WordPress

On this site’s Music Reviews page (itself built on-the-fly by a shortcode that sorts and displays posts from a “Music Review” custom post type), most of the reviews are accompanied by YouTube video embeds from the album in question.

What I didn’t realize in setting that up is that YouTube embeds use <iframe> tags to embed videos, and <iframe> tags block page rendering—the page’s onload property, which signals that the page is fully ready to display to the viewer and to remove the spinning “page loader” image I use on this site as pages load—does not fire until every iframe on the page has fully loaded its contents. This caused that page, which currently only has a handful of videos on it, to load very slowly. What’s worse, this site’s custom menus parse all page contents every time the site is updated to display for word counts, meaning including that page in the menus drastically slowed down the first load of any page of the site after I update anything as the menus are rebuilt.

So I hit upon an elegant solution. I created a shortcode as follows: [[ytembed url="http://youtube.com/embedurlhere?blahblahblah"]] with optional additional parameters "width" and "float" to set the css width and float properties.

This shortcode creates a <div class="mk_YTembedDiv" data-url="http://youtube.com/embedurlhere?blahblahblah"> with the specified CSS properties. Then a script queued up in wordpress’s page footers runs after the javascript event window.onload has fired to indicate the page has fully loaded.  That script checks if the page has any <div class="mk_YTembedDiv"> tag on it. If so, it scans the page to build a list of all of them, and grabbing the data-url attribute from each one, inserts an <iframe> tag into it with the proper attributes to display the video with that embed url.

Therefore, the embedded <iframe> tags to show the videos are only added to the page, and begin loading, after the page has been built and displayed to the user. It does mean there can be a delay after the user starts interacting with the page before the videos appear, but I assume people will read a reviews before wanting to watch the video at the bottom of it, so I don’t think this is a problem. And it’s still much less inconvenient than the page not displaying at all until every video has loaded.

The code that makes the magic happen resides in a custom plugin I wrote to hold all my shortcodes, and here’s the README, code, and license, from my github repo at https://github.com/kupietools/wordpress-non-render-blocking-youtube-embed/:

README.md

ytembed_shortcode.php

License