With the decline of Flash and the explosive rise of mobile devices, more and more content is being delivered as HTML5 video. You can optimize the speed of your site by replacing animated GIF video clips with HTML5 videos. However, video files themselves have a number of optimizations that you can make to improve their performance.

One of the most important is that video files must be properly optimized for streaming online as HTML5 video. Without this optimization videos can be delayed for hundreds of milliseconds and megabytes of bandwidth can be wasted by visitors just trying to play your videos. In this post I will show you how to optimize your video files for fast streaming.

How MP4 Streaming Works

As discussed in our last post, HTML5 video is a cross-browser way to watch video without needing a plug-in like Flash. As of 2016, H.264 encoded video stored in an MP4 container file (which I’ll just simply call an MP4 video) has emerged as the standard format for all online HTML5 video. So when we talk about optimizing HTML5 video, what we are really talking about is how to optimize an MP4 video for faster playback. And the way we do that has to do with the structure of the MP4 file, and how streaming video works.

MP4 files consist of chunks of data called atoms. There are atoms to store things like subtitles or chapters, as well as obvious things like the video and audio data. Meta data about where the video and audio atoms are, as well as information about how to play the video like the dimensions and frames per second, is all stored in a special atom called the moov atom. You can think of the moov atom as a kind of table of contents for the MP4 file.

When you play a video, the program looks through the MP4 file, locates the moov atom , and then uses that to find the start of the audio and video data and begin playing. Unfortunately, atoms can appear in any order, so the program doesn’t know where the moov atom will be ahead of time. Searching to find the moov works fine if you already have the entire video file. However another option is needed when you don’t have the entire video yet, such as when you are streaming HTML5 video. That’s the whole point of streaming a video! You can start watching it without having to download the entire video first.

When streaming, your browser requests the video and starts receiving the beginning of the file. It looks to see if the moov atom is near the start. If the moov atom is not near the start, it must either download the entire file to try and find the moov, or the browser can download small different pieces of the video file, starting with data from the very end, in an attempt to find the moov atom.

All this seeking around trying to find the moov wastes time and bandwidth. Unfortunately, the video cannot play until the moov is located. We can see in the screen shot below a waterfall chart of a browser trying to stream an unoptimized MP4 file using HTML5 video:


You can see the browser makes 3 requests before it can start playing the video. In the first request, the browser downloads the first 552 KB of the video using an HTTP range request. We can tell this by the 206 Partial Content HTTP response code, and by digging in and looking at the request headers. However the moov atom is not there so the browser cannot start to play the video. Next, the browser requests the final 21 KB of the video file using another range request. This does contain the moov atom, telling the browser where the video and audio streams start. Finally, the browser makes a third and final request to get the audio/video data and can start to play the video. This has wasted over half a megabyte of bandwidth and delayed the start of the video by 210 ms! Simply because the browser couldn’t find the moov atom.

It gets even worse if you haven’t configured your server to support HTTP range requests; the browser can’t skip around to find the moov and must download the entire file. This is yet another reason why your should optimize your site with partial download support.

The ideal way to prepare a MP4 video for HTML5 streaming is to organize the file so that the moov is at the very beginning. This way the browser can avoid downloading the entire movie or waste time making additional requests in an attempt to find the moov. The waterfall of a website with a streaming-optimized video looks like this:


With moov at the start of the file, the video will load and play faster, resulting in a better user experience.

Splunk Observability Cloud is an all-in-one monitoring and optimization solution that delivers actionable insights about 40+ metrics. Reach out for additional information and a free trial.

How to Optimize MP4 for Faster Streaming

We have seen that to optimize a video for HTML5 streaming, you need to reorganize the MP4 atoms so the moov atom is at the start. So how do we do that? Most video encoding software has an “optimize for web” or “optimize for streaming” option which does this very thing. You should look at your video encoding settings when creating video to ensure it is optimized. For example, in the screenshot below, we see the open source video encoder Handbrake which has an option “Web Optimized”, which places the moov atom at the start:


This is a workable solution if you are creating the MP4 file from the original source video, but what if you already have an MP4 file?

You can also reorganize an existing video to optimize it for web streaming. For example, the open source command line video encoder FFMpeg can reorganize the structure of the MP4 file to place the moov atom at the start. Unlike the initial encoding of the video which is very time consuming and CPU intensive, reorganizing the file is an easier operation. And, it will not alter the quality of the original video in any way. Before is an example of using ffmpeg to optimize a video named input.mp4* for streaming. The resulting video is named output.mp4

ffmpeg -i input.mp4 -movflags faststart -acodec copy -vcodec copy output.mp4

The -movflags faststart parameter is what tells ffmpeg to reorder the MP4 video atoms so that moov is at the start. We are also instructing ffmpeg to copy the video and audio data instead of re-encoding them, so nothing gets altered.


Whether you are converting animated GIF video clips to MP4, or have a bunch of existing MP4 videos, you can make those videos load and start playing much faster if you optimize the structure of the file. By reordering the atoms so the moov atom is at the start, the browser avoids sending extra HTTP range requests to skip around and try to locate the moov atom. This allows the browser to instantly start streaming the video. You can usually configure an option when initially creating your video to optimize it for streaming. If you have an existing file, you can use a program like ffmpeg to reorder the file without altering its contents.