DEV Community

Cover image for Prevent Youtube iframes to improve Page Speed
Michael Gangolf
Michael Gangolf

Posted on

2 2

Prevent Youtube iframes to improve Page Speed

Improving your Core Web Vitals page speed with a simple JavaScript! No HTML changes required.

After Google introduced the Core Web Vitals to measure your web sites speed you have to make some changes to get a good score.

A big problem are YouTube iframes! They will make an external request as soon as you load your page. On the one hand it will load some kb/mb depending on your player settings but on the other hand it is an external request you might have to prevent because of the GDPR/DSGVO!

The problem

So a simple page like this:



<!DOCTYPE html>
<html lang="de">

<head>
    <meta charset="utf-8">
    <script src="main.js"></script>
</head>

<body>
    <main>
        <iframe id="ytplayer" type="text/html" width="640" height="360" src="http://www.youtube.com/embed/RNuUgbUzM8U?autoplay=1&origin=http://example.com" frameborder="0" />
    </main>
</body>

</html>


Enter fullscreen mode Exit fullscreen mode

will look like this in the DevTools network tab:
youtube1 32 requests / 2.92MB (3.47MB)

Lot's of external requests and it is preloading the video already.

How to fix it

Without changing the HTML code you can use this simple JavaScript file to prevent them from auto-loading:



function updateElements(elements) {
    // loop through all elements
    for (var i = 0; i < elements.length; i++) {
        const currentNode = elements[i].addedNodes;

        for (var j = 0; j < currentNode.length; j++) {
            if (currentNode[j].nodeName.toLowerCase() == "iframe") {
                const myLink = currentNode[j].src;

                // create local HTML code with Youtube link - replace ___data___ with data - dev.to's markdown parser won't let me use it :)
                const localHtml = '<html><body style="background:rgb(200,200,200)"><a href="' + myLink + '" style="font-size:14px;text-align:center;position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);"><img src="___data___:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzMuOTJtbSIgaGVpZ2h0PSIyMy42Mm1tIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAzMy45MiAyMy42MiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC04OC4wNCAtMTM2LjcpIj4KICA8cGF0aCB0cmFuc2Zvcm09InNjYWxlKC4yNjQ2KSIgZD0ibTM0MS43IDUxNi42Yy00Ljk0NiAwLTguOTI4IDMuOTgxLTguOTI4IDguOTI4djcxLjQzYzAgNC45NDYgMy45ODEgOC45MjggOC45MjggOC45MjhoMTEwLjRjNC45NDYgMCA4LjkyOC0zLjk4MSA4LjkyOC04LjkyOHYtNzEuNDNjMC00Ljk0Ni0zLjk4MS04LjkyOC04LjkyOC04LjkyOHptNDcuMzIgMjkuNTYgMjYuNTIgMTUuMDktMjYuNTIgMTUuMDl6IiBmaWxsPSIjZjAwIiBzdG9wLWNvbG9yPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjMuMDM0cHgiIHN0eWxlPSJwYWludC1vcmRlcjpzdHJva2UgZmlsbCBtYXJrZXJzIi8+CiA8L2c+Cjwvc3ZnPgo=" width="80" height="55"/><br/>play video</a></body></html>';

                currentNode[j].setAttribute("data-src", myLink);

                // set local HTML
                // replace ___data___ with data - dev.to's markdown parser won't let me use it :)
                currentNode[j].src = "___data___:text/html;charset=utf-8," + localHtml;
            }
        }
    }
    // remove listeners at the end
    removeEventListener(document, updateElements);
}

function removeEvents(obj, callback) {
    if (window.__obs) {
        window.__obs.disconnect();
    }
}

function registerEvents(obj, callback) {
    const MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
    if (MutationObserver) {
        const obs = new MutationObserver(function(mutations, observer) {
            callback(mutations)
        });
        obs.observe(obj, {
            childList: true,
            subtree: true
        });
        window.__obs = obs;
    }
}

// register events
registerEvents(document, updateElements);


Enter fullscreen mode Exit fullscreen mode

Attention: please replace all ___data___ with data. The markdown parser will throw an error when I just use data

This will register a MutationObserver and remove the iframe source when it is added to the DOM.

This will stop loading the original iframe source and show a local HTML file instead:
youtube2 no external request!


As soon as you click the link it will go to the original source and - since it is a user interaction - it will play the video
youtube3

Improvements

Of course you can change the localHtml page to look better or display an image and so on. For a proof of concept I've decided to keep it simple 😉

SurveyJS custom survey software

Simplify data collection in your JS app with a fully integrated form management platform. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more. Integrates with any backend system, giving you full control over your data and no user limits.

Learn more

Top comments (0)

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay