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>
will look like this in the DevTools network tab:
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);
Attention: please replace all
___data___
withdata
. The markdown parser will throw an error when I just usedata
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:
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
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 😉
Top comments (0)