As networks speed up and devices become ever more powerful, designers and developers can add new immersive features to websites and applications that were previously ‘too slow.’ One popular feature that most devices and networks can handle is video. Research shows that the addition of video increases customer engagement and retention due to the more immersive experience.
However, delivering video has downsides as well. Video files are by far the largest files delivered on the web. Websites with video utilise 300 to 600 percent more Kilobytes than sites without video:
Data from 15/12/2018 HTTP Archive (httparchive.org)
Customers on limited data plans, or those who are roaming, may face unexpected costs from visiting your website incorporating video. Improperly formatted videos can slow down the delivery of the website (and slow websites lose engagement with consumers). Also, if the video cannot be downloaded on the available network, it can lead to a slow startup, stalls and further push away your customers. So, what can we do to make sure that the video delivered on the web is fast, responsive, and does not destroy the mobile data plans of your users?
Read on to find out!
Note: In this article, I’ll only be addressing discrete video files, and not video streaming. Look for additional posts on how to optimise video streams on the web.
The animated GIF: the first video of the internet
Animated GIFs can be found in most social media conversations — on Twitter, Facebook, Slack, etc — and are ubiquitous across the web. However, let’s step back to 1990 — before the World Wide Web existed — and look into the GIF specification. It turns out (if you get to Appendix D) that…
“The Graphics Interchange Format is not intended as a platform for animation, even though it can be done in a limited way.”
I suppose this is not the first time (nor the last) that a technology was used counter its initial purposes. But why would the GIF developers say such a thing? Well, it turns out that animated GIF files are really large and not the optimal way to serve video on the web. Animated GIFs are really a flipbook of discrete GIF images, being played back at a fast framerate. Video, on the other hand, will compress the file through the dimension of time, which creates much smaller files. Lighthouse performance audits will fail your test if they find an animated GIF on your site and recommends that all animated GIFs are replaced with video files.
But… <insert social platform> uses animated GIFs. Why can’t I?
Of course social media platforms say that they support GIFs. And the screen even shows that the file is a GIF in the bottom left corner:
But… if you open the page in Chrome DevTools, there is no GIF file. Twitter is actually serving the animation as a movie — at just 119 KB!
How big is the original GIF? We can go to Giphy and try to find out. But, low and behold, in Chrome, Giphy takes the GIF URL, but delivers an animated WebP image (857 KB) — since WebP files compress more efficiently than animated GIFs. Opening the Giphy link in Safari (which doesn’t support WebP) delivers a 2.4 MB GIF. So the MP4 is just five percent the size of the animated GIF — it’s no wonder that most platforms are moving away from the GIF and embracing the looping video!
How do you deliver a GIF as a video? In all likelihood, you probably already have the MP4, but you can use FFmpeg to convert the animated GIF to an MP4 file. Or you can use a tool like Giphy to create the MP4 file for you, and then you can just place it in a HTML5 video tag:
<video src="shaq.mp4" autoplay="autoplay" loop="loop" muted="" width="300" height="150">
Now you are using animated GIFs like the pros!
By autoplaying videos, you add new levels of motion and interaction to your site that were previously unavailable to users of the web. Sometimes these appear as a “hero video” — a banner video that plays at the top of the page. Other times, they appear as small video windows embedded into the page. Let’s look at an example of a hero video:
The University of Illinois MBA program has a hero video that shows off the UI campus to prospective students. It’s a really cool video — if you ever manage to see it, that is. On relatively fast home Wi-Fi, I see this for about 40 seconds:
Unless I am very patient, I’ll never actually see the video play in my browser! Let’s look at the HTML here, and parse what we see:
<div class="fullwidth-video"> <video preload="auto" autoplay loop muted> <source src="https://business.illinois.edu/mrefresh/wp-content/uploads/sites/78/2016/08/Campus.mp4" type="video/mp4"> <:/video> </div> <div class="fullwidth-video-image" style="background-image:url(https://mba.illinois.edu/wp-content/uploads/sites/78/2017/12/MBA-Network-e1513363230473-400x274.jpg);"></div>
There are two div tags — one for the video, and one for a background image. Inside the video tag, we have autoplay, loop and muted parameters. Autoplay and loop make sense, but the muted is required in mobile browsers for video to autoplay (we’ll touch more on mobile later). One term not seen in the code is the poster attribute, which will display an image instead of the black screen to improve the appearance of the page while the image loads:
<video src="mybigvideo.mp4" poster="poster.jpg">
The fullwidth-video-image div is only called with a mobile user agent, so desktop users never see the background image.
Add a poster image to fill the place of the video while it loads.
But why does this video take so long to download? A quick look at the response headers in Chrome DevTools gives us some insight:
The cache control headers indicate that the movie will be stored for one year (3.15 million seconds). The content length header shows that this video is 98.6 MB, which explains why it takes so long to download and playback in the browser!
Why is the video so large?
Let’s examine this video to understand why it’s so large. We’ll use
ffprobe (part of the FFmpeg toolset) to examine it:
ffprobe -v error -show_streams -show_format http://mba….campus.mp4
A long output appears in the terminal. Let’s focus on just a few parameters.
From the FORMAT output:
|nb_streams=2||There are two streams of data. We should make sure both are required.|
|duration=50.92266||It’s probably longer than needed, but perhaps that is outside the developer’s control.|
|size=98611339||It’s 98.6 MB. Now we see why this is taking so long… We can work some magic here.|
|bit_rate=15491936||A 15.5 Megabits-per-second video is pretty high quality for the web. Reducing this will certainly reduce the file size.|
Now let’s look at the STREAM outputs.
/ MPEG-4 AVC
/ MPEG-4 part 10
|Pretty standard encoding.|
|width=1920 height=1080||A 1080p video. Pretty large dimensions — perhaps we can encode to smaller dimensions.|
|r_frame_rate=30000/1001||30 frames per second.|
(Advanced Audio Coding)
|An audio stream. For a silent video!|
The second stream is an audio track. For a video that plays in the background and is silent. To be fair, the audio track has no sound but it does have a size volume that is downloaded on each playback. We’ll remove this track in the next section.
How do we make the hero video smaller?
We will use
FFmpeg for the optimisations.
1. Reduce file quality. We’ll first work to lower the quality by adding a constant rate factor (FFmpeg recommends 17 to 28 for the web, and higher numbers are lower quality).
ffmpeg -i Campus.mp4 -c:v libx264 -preset slow -crf 22 -c:a copy campus2.mp4
This gets the file to nearly 35 MB.
2. Reduce the dimensions from 1080p to 720p by adding a scale factor —
“-vf scale=-1:720” — reducing the video size to 17 MB.
3. Finally, we’ll remove the silent audio stream using
-map 0:0 -vcodec copy, which saves an additional 2 MB and results in a 15.7 MB video.
4. Raising the crf to 28 lowers the video size to 6.7 MB, with no substantial loss in video quality (see for yourself!)
Resize video dimensions appropriately.
Test different video encoding qualities. Generally 20 to 28 are safe for the web.
For silent videos remove the audio track, even if there is no audio present to reduce the file size.
Video on mobile
Now, you might imagine, as the title of this post implies, that a 98 MB video would indeed kill many people’s data plans. I recently had the opportunity to visit Russia, and my roaming plan was €10/MB. Visiting this page once would have cost me nearly €1000 for the video alone!
One common data-saving tactic is to replace the video with an image on mobile. In the HTML code above, we see a div with a background image, which is only displayed on mobile. Problem solved, right? It all looks great, until you run the same test on a mobile device with DevTools open. And then the preload=”auto” attribute in the video tag rears its ugly head. When the browser sees that tag, it will download the content — even if it’s never displayed on the page. In this case, Chrome eventually gives up on the download, but in one WebPageTest run, there were 44.5 MB of video downloaded, which was never viewed by the end user!
If the video is not going to be displayed, don’t download it for your customers.
Preload="auto" is great if there is a very high possibility that the video will be viewed. Otherwise you are just wasting bytes.
Background videos and video length
One popular way to utilise autoplaying video on the web is to add a background video that plays behind your content. Assuming that it contrasts well with the foreground text, this can be a great way to add motion and cool effects to your website. For example, this website (with name obfuscated) uses a video of a walking tiger at the top of the page:
Now, if a background video is too large, it may never actually display in the background while the page is open, because it’s still downloading. When delivering a video, the main way to reduce the video size is to change the dimensions: width/height, bitrate and length.
For background videos, when there is a filter obscuring the video slightly, you can serve a lower resolution or lower bitrate video without your customers actually noticing. But the easiest way to ensure a smaller file is to reduce the length of the video. In the case of the pacing tiger above, the video is 55 seconds long. Perhaps just 10 seconds of looping would be sufficient.
Also, the video is delivered as a Quicktime file (.mov). These files tend to be larger in size. Using
FFmpeg to convert this file to an MP4 is easy:
ffmpeg -i Tiger-background.mov tiger.mp4
This creates an MP4 file that is 10 MB (76%) smaller. Now, let’s shorten the file to 10 seconds:
ffmpeg -i Tiger-background.mov -t 10 tiger.mp4
This gets us to 3.2 MB (92% smaller).
By working to reduce the size of the video, your customers are more likely to have the entire file downloaded and see he background video effect play in their browser.
Video can be delivered to the browser in a way that is fast and responsive, if just a little thought is given to the attributes of the video being displayed. Reducing the size of the video file ensures that it can be delivered quickly to customers on all types of connections, giving them the interactive immersive experience you are looking for. So, before you just simply add a video to your page, use the techniques mentioned above to see if you can reduce the size without harming the quality. This will give your customers the best possible immersive experience — which is our end goal anyway.