1

I got a warning about my page speed performance being suboptimal. Turns out that an iframe of 1 embedded YouTube video is loading one JS file that adds half a second to my page load.

I added loading="lazy" attribute to that iframe and to 2 other media assets that are further down the page. None of it seems to make any difference in PageSpeed Insights tests.

It is very annoying that PageSpeed Insights complains even about JS implementation in Google’s own scripts.

To improve general loading speeds in other geographical regions, what would be a good service to use that won’t require me to get and configure a separate server for every continent? That would help more than any optimization.

1

Rather than use the default embed code from Youtube, you can truly lazy load the video:

  1. Put just a placeholder image in the HTML
  2. Run JavaScript onclick on that image that replaces it with the Youtube iframe and plays the video.

The Youtube JS API fully supports this. Here is the code to make it happen from ak85's answer to this question on StackOverflow: Lazy Load youtube video from iframe API The only thing that you need to change in this code is the video id from Youtube. It is in two places: The placeholder image and the JavaScript.

<div id="placeholder">
<img src="http://img.youtube.com/vi/M7lc1UVf-VE/sddefault.jpg" />
</div>
</div>
<div id="player"></div>

<script>

document.getElementById("placeholder").addEventListener("click", function(){
    this.style.display = 'none';
    loadYT()
});
  // 2. This code loads the IFrame Player API code asynchronously.
  function loadYT() {
    var tag = document.createElement('script');
    tag.src = "https://www.youtube.com/iframe_api";
    var firstScriptTag = document.getElementsByTagName('script')[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
  }

  // 3. This function creates an <iframe> (and YouTube player)
  //    after the API code downloads.
  var player;

  function onYouTubeIframeAPIReady() {
    player = new YT.Player('player', {
      height: '390',
      width: '640',
      videoId: 'M7lc1UVf-VE',
      events: {
        'onReady': onPlayerReady,
        'onStateChange': onPlayerStateChange
      }
    });
  }

  // 4. The API will call this function when the video player is ready.
  function onPlayerReady(event) {
    event.target.playVideo();
  }

  // 5. The API calls this function when the player's state changes.
  //    The function indicates that when playing a video (state=1),
  //    the player should play for six seconds and then stop.
  var done = false;

  function onPlayerStateChange(event) {
    if (event.data == YT.PlayerState.PLAYING && !done) {
      setTimeout(stopVideo, 6000);
      done = true;
    }
  }

  function stopVideo() {
    player.stopVideo();
  }

</script>
2
  • If this script is embedded I'm fairly certain the execution will go last (effectively "deferred"), which contradicts the async, no? However, if this video is not visible above the fold I would probably defer it anyways, especially if the page loads a lot of other 3rd party resources. Aug 13 at 17:27
  • This script could be put in a js file and marked as async. The important thing about it is that the only thing from youtube that gets run onload is the image. Everything else happens onclick. Aug 13 at 19:52
1

Requesting an external resource on a website or application incurs several round-trips before the browser can actually start to download the resource. These round-trips include the DNS lookup, TCP handshake, and TLS negotiation.

Your problem is that video is blocking the browser's main thread. It is "renderblocking".

To add to Stephen's answer, if you're looking to shave your timings down to the milliseconds, let's pre-connect to YouTube.

<link rel="preconnect" href="https://www.youtube.com">

//Other YouTube stuff 
<link rel="preconnect" href="https://i.ytimg.com">
<link rel="preconnect" href="https://i9.ytimg.com">
<link rel="preconnect" href="https://s.ytimg.com">

Unless this has changed recently, Roboto is used as the font in the YouTube player. So let's preconnect it as well.

<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

crossorigin tells the browser that "resources on this connection are downloaded using CORS." Essentially - "CORS without credentials."

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.