Oftentimes, after building a web page, we check our Loading Speed metrics for SEO and mobile user experience only to find out that the FCP (First Contentful Paint) or other parts take longer than they’re supposed to, which means we need to improve load speed.
Reasons for that might vary – Popups, Videos, etc., only to name a few. However, this is where a JavaScript XMLHttpRequest comes into play, to prevent non-critical elements from render blocking your page, and improve loading speeds or in other words – your SEO score.
AJAX video loading
Say we want to display videos on our page’s hero banner. Whilst our DOM content is loading, with an additional video loading time after that, we might want a temporary background. Let’s set that up, and by all means, don’t lazy load your first content (e.g. images).
<div class="video-wrapper">
<img id="noscript-img" src="my-awesome-image.webp" width="100%" />
<video id="my-video" src="" width="100%" type="video/webm" style="display:none"></video>
</div>
-Now that that’s setup, let’s get to the JavaScript part. Don’t forget to Defer your non-critical (like this one) JavaScript!
<script defer>
window.addEventListener('load', (event) =>{
var videoObject; //this will be needed later
let vid = document.getElementById('my-video');
let request = new XMLHttpRequest(); //prepare a new request
request.open("GET", "https://awesomesite.me/files/my-awesome-video.webp", true);
//we need to GET our video file from this certain URL
//so we define this in our 'request'
request.responseType = "blob";
//here we also define what type
//of response do we want to get in return
//in this case it is straight forward
//our file's binary data
request.onload = function() {
if(request.status != 200){
console.log("Request failed. Status: " + request.status);
return;
}
//it's best to avoid running any unnesessary job
//in our script so we check if we got our video
//successfully or not
videoObject = URL.createObjectURL(this.response);
//we turn our binary data into an URL object for html
vid.src = videoObject;
vid.load(); //don't forget to load your newly assigned link
}
request.send();
//your request is setup so now we can send it
vid.addEventListener('loadeddata', (event) => {
document.getElementById('noscript-img').remove();
//our image takes up space, so let's remove it
//for the video to take it's place
vid.style.display = "block";
vid.play();
});
});
</script>
Though you may ask, what if the user has JavaScript disabled? The solution would be to write a replacing HTML code in between the noscript tags. Or following our simple example above, have a temporary image setup, which will be removed and replaced by your video element with JavaScript.
HTML content
The same principle will apply for our HTML content, but with a few different lines of code. Say we’re looking to add a popup message after the page loads. We prepare our HTML in a .txt
file, upload it to our server, and our JavaScript should look like this:
var request = new XMLHttpRequest();
request.open("GET", "my-awesome-html-modal.txt");
request.onload = function () {
if (request.status != 200) {
return;
}
document.body.insertAdjacentHTML("beforeend", this.responseText);
//response type is XML so to append it
//to our HTML properly we need
//.insertAdjacentHTML
document
.querySelector(".pop-modal-close")
.addEventListener("click", (event) => {
document.querySelector(".pop-modal").style.display = "none";
//this event is to close our modal
});
};
request.send();
You’ll notice that we didn’t specify a responseType
. That’s because by default it’s text/xml
, which is what we need, and we’d prefer not to waste our precious bytes.
And that’s it! With XMLHttpRequest
you basically update anything on your page without refreshing, which can also be used in many scenarios like the ones we’ve described above.