{"id":21646,"date":"2018-01-03T17:28:31","date_gmt":"2018-01-03T17:28:31","guid":{"rendered":"http:\/\/evolution_of_img_gif_without_the_gif"},"modified":"2025-11-06T16:15:37","modified_gmt":"2025-11-07T00:15:37","slug":"evolution_of_img_gif_without_the_gif","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif","title":{"rendered":"Evolution of &lt;img>: Gif Without the GIF"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p><strong>MP4 vs. GIF the TL;DR<\/strong><\/p>\n<ul>\n<li>Gifs are awesome but <em>terrible<\/em> for quality and <a href=\"https:\/\/cloudinary.com\/blog\/image_optimization_for_websites_beautiful_pages_that_load_quickly\">performance<\/a>.<\/li>\n<li>Replacing Gifs with <code>&lt;video&gt;<\/code> is \/better\/ but has perf. drawbacks: not preloaded, uses range requests.<\/li>\n<li>Now you can <code>&lt;img src=&quot;.mp4&quot;&gt;<\/code>s in Safari Technology Preview.<\/li>\n<li>Early results show mp4s in <code>&lt;img&gt;<\/code> tags display 20x faster and decode 7x faster than the GIF equivalent &#8211; in addition to being 1\/14th the file size!<\/li>\n<li>Background CSS video &amp; Responsive Video can now be a \u201cthing\u201d.<\/li>\n<li>Finally &#8211; cinemagraphs without the downsides of Gifs! Now we wait for the other browsers to catch-up<\/li>\n<\/ul>\n<h2>Intro<\/h2>\n<p>I both <img decoding=\"async\" src=\"https:\/\/colinbendell.cloudinary.com\/video\/upload\/c_scale,w_50,fl_animated,f_auto,e_loop\/fire.gif\" alt=\"Ode to Geocities\" \/> love and <img decoding=\"async\" src=\"https:\/\/colinbendell.cloudinary.com\/video\/upload\/c_scale,fl_animated,f_auto,w_50,e_loop\/colin.gif\" alt=\"Thanks Tim Kadlec\" \/> hate animated Gifs.<\/p>\n<p>Safari Tech Preview has changed all of this. Now I love and love animated \u201cGifs\u201d.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/colinbendell.cloudinary.com\/image\/upload\/c_crop,f_auto,g_auto,h_350,w_400\/v1512090971\/Wizard-Clap-by-Markus-Magnusson.gif\" alt=\"GIF Image of happy man dancing changing costumes\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"400\" height=\"350\"\/><\/p>\n<p>Animated Gifs are a hack. To quote from the <a href=\"https:\/\/www.w3.org\/Graphics\/GIF\/spec-gif89a.txt\">original Gif89a specification<\/a>:<\/p>\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>The Graphics Interchange Format is not intended as a platform for animation, even though it can be done in a limited way.<\/p><\/div>\n<p>But they have become an awesome tool for <a href=\"https:\/\/cinemagraphs.com\">cinemagraphs<\/a>, <a href=\"https:\/\/giphy.com\/search\/memes\/\">memes<\/a>, and creative <a href=\"https:\/\/www.youtube.com\/watch?v=vuxKb5mxM8g\">expression<\/a>. All of this awesomeness, however, comes at a cost. Animated Gifs are terrible for web performance. They are HUGE in size, impact cellular data bills, require more CPU and memory, <a href=\"https:\/\/www.html5rocks.com\/en\/tutorials\/speed\/animated-gifs\/\">cause repaints<\/a>, and are battery killers. Typically Gifs are <a href=\"https:\/\/webkit.org\/blog\/6784\/new-video-policies-for-ios\/\">12x larger files than H.264 videos, and take 2x the energy to load and display in a browser<\/a>. And we\u2019re spending all of those resources on something that doesn\u2019t even look very good \u2013 the GIF 256 color limitation often makes GIF files look terrible (although there are some <a href=\"https:\/\/gif.ski\/\">cool workarounds<\/a>).<\/p>\n<p>My daughter loves them \u2013 but she doesn\u2019t understand why her battery is always dead.<\/p>\n<p>Gifs have many advantages: they are requested immediately by the browser preloader, they play and loop automatically, and they are silent! Implicitly they are also shorter. <a href=\"https:\/\/dmakproductions.com\/blog\/what-is-the-ideal-length-for-web-video-production\/\">Market<\/a> <a href=\"https:\/\/wistia.com\/blog\/does-length-matter-it-does-for-video-2k12-edition\">research<\/a> has shown that users have higher engagement with, and generally prefer both micro-form video (&lt; 1minute) and cinemagraphs (stills with subtle movement), over longer-form videos and still images. Animated Gifs are great for user experience.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/colinbendell.cloudinary.com\/image\/upload\/c_crop,g_north,h_340,w_580\/q_auto\/vista_video_length.gif\" alt=\"Chart of video performance mp4 vs gif\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"580\" height=\"340\"\/><\/p>\n<p>So how did I go from love\/hating Gifs to love\/loving \u201cGifs\u201d?<\/p>\n<p>In the latest Safari Tech Preview, thanks to some hard work by <a href=\"https:\/\/twitter.com\/jernoble\">Jer Noble<\/a>, we can <a href=\"https:\/\/bugs.webkit.org\/show_bug.cgi?id=176825\">now use MP4 files<\/a> in <code>&lt;img&gt;<\/code> tags. The intended use case is not long-form video, but micro-form, muted, looping video \u2013 just like animated Gifs. Take a look for yourself:<\/p>\n<pre class=\"js-syntax-highlighted\"><code>&lt;img src=\u201drocky.mp4\u201d&gt;\n<\/code><\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/colinbendell.cloudinary.com\/video\/upload\/f_auto,q_auto,fl_animated\/rocky.gif\" alt=\"GIF Image of Rocky jumping rope\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"480\" height=\"270\"\/><\/p>\n<p>Cool! This is going to be awesome on so many fronts \u2013 for business, for usability, and particularly for web performance!<\/p>\n<h2>But We Already Have <code>&lt;video&gt;<\/code> Tags?<\/h2>\n<p>As many have already <a href=\"https:\/\/rigor.com\/blog\/2015\/12\/optimizing-animated-gifs-with-html5-video\">pointed<\/a> <a href=\"https:\/\/www.sohamkamani.com\/blog\/2016\/04\/09\/stop-using-gifs\/\">out<\/a>, using the <code>&lt;video&gt;<\/code> tag is much better for performance than using animated Gifs. That\u2019s why in 2014 Twitter <a href=\"https:\/\/mashable.com\/2014\/06\/20\/twitter-gifs-mp4\/\">famously added animated GIF support<\/a> by not adding GIF support. Twitter instead transcodes Gifs to MP4s on-the-fly, and delivers them inside <code>&lt;video&gt;<\/code> tags. Since all browsers now support H.264, this was a very easy transition.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>&lt;video autoplay loop muted inline&gt;\n  &lt;source src=&quot;eye-of-the-tiger-video.webm&quot; type=&quot;video\/webm&quot;&gt;\n  &lt;source src=&quot;eye-of-the-tiger-video.mp4&quot; type=&quot;video\/mp4&quot;&gt;\n  &lt;img src=&quot;eye-of-the-tiger-fallback.gif&quot; \/&gt;\n&lt;\/video&gt;\n<\/code><\/pre>\n<p>Transcoding animated Gifs to MP4 is fairly straightforward. You just need to run <code>ffmpeg -i source.gif output.mp4<\/code><\/p>\n<p>However, not everyone can overhaul their CMS and convert <code>&lt;img&gt;<\/code> to <code>&lt;video&gt;<\/code>. Even if you can, there are three problems with this method of delivering Gif-like, micro-form video:<\/p>\n<h3>1. Browser Performance is Slow With <code>&lt;video&gt;<\/code><\/h3>\n<p>As <a href=\"https:\/\/discuss.httparchive.org\/t\/the-elephant-in-the-room-video\/1087\">Doug Sillars recently pointed out in a HTTP Archive post<\/a>, there is huge visual presentation performance penalty when using the <code>&lt;video&gt;<\/code> tag.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/colinbendell.cloudinary.com\/image\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/discourse-httparchive-VideoPerf.png\" alt=\"Chart showing speed index of sites with and without video for comparing MP4 vs GIF\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1400\" height=\"805\"\/><\/p>\n<p>Unlike <code>&lt;img&gt;<\/code> tags, browsers do <a href=\"https:\/\/yoavweiss.github.io\/preloader-velocity-nyc-talk\/#\/32\">not preload <code>&lt;video&gt;<\/code><\/a> content. Generally preloaders only preload JavaScript, CSS, and image resources because they are critical for the page layout. Since <code>&lt;video&gt;<\/code> content can be any length \u2013 from micro-form to long-form \u2013 <code>&lt;video&gt;<\/code> tags are skipped until the main thread is ready to parse their content. This delays the loading of <code>&lt;video&gt;<\/code> content by many hundreds of milliseconds.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/colinbendell.cloudinary.com\/image\/upload\/c_crop,f_auto,q_auto,h_169,w_2400,x_660\/velocity-filmstrip.png\" alt=\"Image of frames loading in a video\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2400\" height=\"169\"\/><\/p>\n<p>For example, the hero video at the top of the <a href=\"https:\/\/conferences.oreilly.com\/velocity\/vl-ca\">Velocity conference page<\/a> is only requested 5 full seconds into the page load. It\u2019s the <a href=\"https:\/\/www.webpagetest.org\/result\/171201_S2_f4f9bb24f9308827f69a8f2d5ffe09fa\/3\/details\/\">27th requested resource<\/a> and it isn\u2019t even requested until after Start Render, after webfonts are loaded.<\/p>\n<p>Worse yet, many browsers assume that <code>&lt;video&gt;<\/code> tags contain long-form content. Instead of downloading the whole video file at once, which would waste your cell data plan in cases where you do not end up watching the whole video, the browser will first perform a 1-byte request to test if the server supports <a href=\"https:\/\/tools.ietf.org\/html\/rfc7233\">HTTP Range Requests<\/a>. Then it will follow with multiple range requests in various chunk sizes to ensure that the video is adequately (but not over-) buffered. The consequence is multiple TCP round trips before the browser can even start to decode the content and significant delays before the user sees anything. On high-latency cellular connections, these round trips can set video loads back by hundreds or thousands of milliseconds.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/colinbendell.cloudinary.com\/image\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/safari-range-requests.png\" alt=\"Screenshot of MP4 files\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1400\" height=\"184\"\/><\/p>\n<p>And what performs even worse than the native <code>&lt;video&gt;<\/code> element? The typical JavaScript video player. Often, the easiest way to embed a video on a site is to use a hosted service like YouTube or Vimeo and avoid the complexities of video encoding, hosting, and UX. This is normally a great idea, but for micro-form video, or critical content like hero videos, it just adds to the delay because of the JavaScript players and supporting resources that these hosting services inject (css\/js\/jpg\/woff). In addition to the <code>&lt;video&gt;<\/code> markup you are forcing the browser to download, evaluate, and execute the JavaScript player, and only then can the video start to load.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/colinbendell.cloudinary.com\/image\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/v1512155054\/videoplayer-waterfall.png\" alt=\"Screenshot of list of various javasript video load times\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1400\" height=\"189\"\/><\/p>\n<p>As many people know, I love my Loki jacket because of its built in mitts, balaclava, and a hood that is sized for helmets. But take a look at the Loki USA homepage \u2013 which uses a great hero-video, hosted on Vimeo:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/colinbendell.cloudinary.com\/image\/upload\/c_scale,h_50,w_800\/f_auto,q_auto\/lokiusa-filmstrip.png\" alt=\"Image of frames loading in a video\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"800\" height=\"50\"\/><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/colinbendell.cloudinary.com\/video\/upload\/du_20.1\/e_loop,fl_animated,f_auto,q_auto\/lokiusa-video.gif\" alt=\"GIF showing javascript loading on the Loki USA website\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"512\" height=\"448\"\/><\/p>\n<p>If you look closely, you can see that the JavaScript for the player is actually requested soon after DOM Complete. But it isn\u2019t fully loaded and ready to start the video stream until much later.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/colinbendell.cloudinary.com\/image\/upload\/c_scale,f_auto,q_auto,dpr_2.0\/v1512154815\/lokiusa-waterfall.png\" alt=\"Image of chart showing the load time versus video play start\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"332\" height=\"900\"\/><\/p>\n<p>Check out the <a href=\"https:\/\/www.webpagetest.org\/result\/171201_M1_8c08554c16f8e3e6dfc378289105d5e5\/1\/details\/#waterfall_view_step1\">WPT Results<\/a><\/p>\n<h3>2. You Can\u2019t Right-Click and Save Video<\/h3>\n<p>Most long-form video content (e.g., vlogs, TV, movies) is delivered via JavaScript-based players. Usually these players provide users with a convenient \u201cshare now\u201d link or bookmark tool, so they can come back to YouTube (or wherever) and find the video again. In contrast, micro-form content, like memes and <a href=\"https:\/\/cloudinary.com\/glossary\/cinemagraphs\">cinemagraphs<\/a>, usually doesn\u2019t come via a player, and users expect to be able to download animated Gifs and send them to friends, like they can with any image on the web. That meme of the dancing cat was so funny! I have to share it with all my friends!<\/p>\n<p>If you use <code>&lt;video&gt;<\/code> tags to deliver micro-form video, users can\u2019t right-click, click-and-drag, or force touch, and save. And their dancing-cat joy becomes a frustrating UX surprise.<\/p>\n<h3>3. Autoplay Abuse<\/h3>\n<p>Finally, using <code>&lt;video&gt;<\/code> tags and MP4s instead of <code>&lt;img&gt;<\/code> tags and GIFs is brings you into the middle of an ongoing cat and mouse game between browsers and unconscionable ad vendors, who abuse the <code>&lt;video autoplay&gt;<\/code> attribute in order to get the users\u2019 attention. Historically, mobile browsers have ignored the autoplay attribute and\/or refused to play videos inline, requiring them to go full screen. Over the last couple of years, <a href=\"https:\/\/webkit.org\/blog\/6784\/new-video-policies-for-ios\/\">Apple<\/a> and <a href=\"https:\/\/blog.chromium.org\/2017\/09\/unified-autoplay.html\">Google<\/a> have both relaxed their restrictions on inline, autoplay videos, allowing for Gif-like experiences with the <code>&lt;video&gt;<\/code> tag. But again, ad networks have abused this, causing further restrictions: if you want to autoplay <code>&lt;video&gt;<\/code> tags you need to mark the content with <code>muted<\/code> or remove the audio track all together.<\/p>\n<h2>But We Already Have Animated WebP! And Animated PNG!<\/h2>\n<p>The GIF format isn\u2019t the only animation-capable, still-image format. WebP and PNG have animation support, too. But, like GIF, they were not designed <em>for<\/em> animation and result in much larger files, compared to dedicated video codecs like H.264, H.265, VP9, and AV1.<\/p>\n<p>Animated PNG is now widely supported across all browsers, and while it addresses the color pallete limitation of GIF, it is still an inefficient file format for compressing video.<\/p>\n<p>Animated WebP is better, but compared to true video formats, it\u2019s still problematic. Aside from not having a formal standard, animated WebP lacks chroma subsampling and wide-gamut support. Further, the ecosystem of support is fragmented. Not even all versions of Android, Chrome, and Opera support animated WebP \u2013 even though those browsers advertise support with the <code>Accept: image\/webp<\/code>. You need Chrome 42, Opera 15+ or Android 5+.<\/p>\n<p><a href=\"https:\/\/caniuse.com\/#feat=webp\"><img decoding=\"async\" src=\"https:\/\/colinbendell.cloudinary.com\/image\/upload\/c_scale,f_auto,q_auto,w_800\/webp.png\" alt=\"Chart showing WebP support across browsers\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"800\" height=\"98\"\/><\/a><\/p>\n<p><a href=\"https:\/\/caniuse.com\/#feat=webm\"><img decoding=\"async\" src=\"https:\/\/colinbendell.cloudinary.com\/image\/upload\/c_scale,f_auto,q_auto,w_800\/webM.png\" alt=\"Chart showing WebM support across browsers\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"800\" height=\"101\"\/><\/a><\/p>\n<p><a href=\"https:\/\/caniuse.com\/#feat=apng\"><img decoding=\"async\" src=\"https:\/\/colinbendell.cloudinary.com\/image\/upload\/c_scale,f_auto,q_auto,w_800\/apng.png\" alt=\"Chart showing APNG support across browsers\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"800\" height=\"96\"\/><\/a><\/p>\n<p><a href=\"https:\/\/caniuse.com\/#feat=hevc\"><img decoding=\"async\" src=\"https:\/\/colinbendell.cloudinary.com\/image\/upload\/c_scale,f_auto,q_auto,w_800\/hevc.png\" alt=\"Chart showing HEVC support across browsers\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"800\" height=\"94\"\/><\/a><\/p>\n<p>So while animated WebPs compress much better than animated GIFs or aPNGs, we can do better. (See file size comparisons below)<\/p>\n<h2>Having Our Cake and Eating It, Too<\/h2>\n<p>By enabling true video formats (like MP4) to be included in <code>&lt;img&gt;<\/code> tags, Safari Technology Preview has fixed these performance and UX problems. Now, our micro-form videos can be small and efficient (like MP4s delivered via the <code>&lt;video&gt;<\/code> tag) <em>and<\/em> they can can be easily preloaded, autoplayed, and shared (like our old friend, the animated GIF).<\/p>\n<pre class=\"js-syntax-highlighted\"><code>&lt;img src=&quot;ottawa-river.mp4&quot;&gt;\n<\/code><\/pre>\n<p>So how much faster is this going to be? Pull up the developer tools and see the difference in Safari Technology Preview and other browsers:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/colinbendell.cloudinary.com\/video\/upload\/c_scale,w_500\/l_text:arial_20:GIF:%208.4MB%0Dmp4:386KB,g_north_west,y_20,x_20\/fl_animated,f_auto,q_auto\/Ottawa_River.gif\" alt=\"Image showing rocks stacked in a river comparing mp4 vs gif size\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"500\" height=\"280\"\/><\/p>\n<p>Unfortunately Safari doesn\u2019t play nice with WebPageTest, and creating reliable benchmark tests is complicated. Likewise, Tech Preview\u2019s usage is fairly low, so comparing performance with RUM tools is not yet practical.<\/p>\n<p>We can, however, do two things. First, compare raw byte sizes, and second, use the <a href=\"https:\/\/html.spec.whatwg.org\/multipage\/embedded-content.html#dom-img-decode\">Image.decode()<\/a> promise to measure the device impact of different resources.<\/p>\n<h2>MP4 vs. GIF size | Byte Savings<\/h2>\n<p>First, the byte size savings. To compare this I took the trending top 100 animated GIFs from <a href=\"https:\/\/giphy.com\/\">giphy.com<\/a> and <a href=\"https:\/\/gist.github.com\/colinbendell\/2aeb9d09af45dbe26ccdf5842253238d\">converted them into VP8, VP9, WebP, H.264, and H.265<\/a>.<\/p>\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p><em>NB:<\/em> These results should be taken as directional only! Each codec could be tuned much more; as you can see the default VP9 encoding settings fair worse, here, than the default VP8 outputs. A more comprehensive study should be done that considers visual quality, measured by SSIM.<\/p><\/div>\n<p>Below are the <a href=\"https:\/\/docs.google.com\/a\/bendell.ca\/spreadsheets\/d\/1T5dR6tDeKDsTi9_Xg93hljZPsX1WlBGCcJLr9acYhZ4\/edit?usp=sharing\">median (p50) results<\/a> of the conversion:<\/p>\n<figure class=\"table-wrapper\"><table>\n<thead>\n<tr>\n<th>Format<\/th>\n<th>Bytes p50<\/th>\n<th>% change p50<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>GIF<\/td>\n<td>1,713KB<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td>WebP<\/td>\n<td>310KB<\/td>\n<td>-81%<\/td>\n<\/tr>\n<tr>\n<td>WebM\/VP8<\/td>\n<td>57KB<\/td>\n<td>-97%<\/td>\n<\/tr>\n<tr>\n<td>WebM\/VP9<\/td>\n<td>66KB<\/td>\n<td>-96%<\/td>\n<\/tr>\n<tr>\n<td>WebM\/AV1<\/td>\n<td>TBD<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td>MP4\/H.264<\/td>\n<td>102KB<\/td>\n<td>-93%<\/td>\n<\/tr>\n<tr>\n<td>MP4\/H.265<\/td>\n<td>43KB<\/td>\n<td>-97%<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n<p>So, yes, an animated WebP will almost always be smaller than an animated GIF \u2013 but any video format will be much, <em>much<\/em> smaller. This shouldn\u2019t surprise anyone since modern video codecs are highly optimized for online video streaming. H.265 fairs very well, and we should expect the upcoming AV1 to fair well, too.<\/p>\n<p>The benefits here will not only be faster transit but also substantial <a href=\"https:\/\/whatdoesmysitecost.com\/\">data-plan cost savings for end users<\/a>.<\/p>\n<p>Net-net, using video in <code>&lt;img&gt;<\/code> tags is going to be far, far better for users on cellular connections.<\/p>\n<h2>MP4 vs. GIF | Decode and Visual Performance Improvements<\/h2>\n<p>Next, let\u2019s consider the impact that decoding and displaying micro-form videos has on the browsing experience. H.264 (and H.265) has the notable advantage of being hardware decoded instead of using the primary core for decode.<\/p>\n<p>How can we measure this? Since browsers haven\u2019t yet implemented the proposed <a href=\"https:\/\/docs.google.com\/document\/d\/1yRYfYR1DnHtgwC4HRR04ipVVhT1h5gkI6yPmKCgJkyQ\/edit?usp=sharing\">hero image API<\/a>, we can use Steve Souder\u2019s <a href=\"https:\/\/speedcurve.com\/blog\/user-timing-and-custom-metrics\/\">User Timing and Custom Metric strategy<\/a> as a good aproximation of when the image starts to display to the user. This strategy doesn\u2019t measure frame rate, but it does tell us roughly when the first frame is displayed. Better yet, we can also use the newly adopted <a href=\"https:\/\/html.spec.whatwg.org\/multipage\/embedded-content.html#dom-img-decode\">Image.decode()<\/a> event promise to measure decode performance. In the test page below, I inject a unique GIF and MP4 in an <code>&lt;img&gt;<\/code> tag 100 times and compare the decode and paint performance.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">let<\/span> image = <span class=\"hljs-keyword\">new<\/span> Image;\nt_startReq = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Date<\/span>().getTime();\n<span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"testimg\"<\/span>).appendChild(image);\nimage.onload = timeOnLoad;\nimage.src = src;\n<span class=\"hljs-keyword\">return<\/span> image.decode().then(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> { resolve(image); });\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The results are quite impressive! Even on my powerful 2017 MacBook Pro, running the test locally, with no network throttling, I can see GIFs taking 20x longer than MP4s to draw the first frame (signaled by the <code>onload<\/code> event), and 7x longer to decode!<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/colinbendell.cloudinary.com\/image\/upload\/c_scale,f_auto,q_auto,w_600\/v1512144761\/gif_v_mp4.png\" alt=\"Image showing rocks stacked in a river comparing mp4 vs gif size\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"600\" height=\"506\"\/><\/p>\n<p>Curious? <a href=\"https:\/\/github.com\/colinbendell\/gif_perf_test\">Clone the repo<\/a> and test for yourself. I will note that adding network conditions on the transit of the GIF v. MP4 will disproportionately skew the test results. Specifically: since decode can start happening before the last byte finishes, the delta between transfer, display and decode becomes much smaller. What this really tells us is that just the byte savings alone will substantially improve the user experience. However, factoring out the network as I\u2019ve done on a localhost run, you can see that using video has substantial performance benefits for energy consumption as well.<\/p>\n<h2>How Can You Implement This?<\/h2>\n<p>So now that Safari Technology Preview supports this design pattern, how can you actually take advantage of it, without serving broken images to non-supporting browsers? Good news! It\u2019s relatively easy.<\/p>\n<h3>Option 1: Use Responsive Images<\/h3>\n<p>The simplest way is to use the <code>&lt;source type&gt;<\/code> attribute of the HTML5 <code>&lt;picture&gt;<\/code> tag.<\/p>\n<pre class=\"js-syntax-highlighted\"><code>&lt;picture&gt;\n  &lt;source type=\u201dvideo\/mp4\u201d srcset=\u201dcats.mp4\u201d&gt;\n  &lt;source type=\u201dimage\/webp\u201d srcset=\u201dcats.webp\u201d&gt;\n  &lt;img src=\u201dcats.gif\u201d&gt;\n&lt;\/picture&gt;\n<\/code><\/pre>\n<p>I\u2019d like to say we can stop there. However, there is this <a href=\"https:\/\/bugs.webkit.org\/show_bug.cgi?id=179231\">nasty WebKit bug<\/a> in Safari that causes the preloader to download the <em>first<\/em> <code>&lt;source&gt;<\/code> regardless of the MIME type declaration. The main DOM loader realizes the error and selects the correct one. However, the damage will be done. The preloader squanders its opportunity to download the image early and on top of that, starts downloading the wrong version, wasting bytes. The good news is that I\u2019ve patched this bug and the patch should land in Safari TP 45.<\/p>\n<p>In short, using the <code>&lt;picture&gt;<\/code> and <code>&lt;source type&gt;<\/code> for MIME type selection is not advisable until the next version of Safari reaches 90%+ of Safari\u2019s total user base.<\/p>\n<h3>Option 2: Use MP4, Animated WebP and Fallback to GIF<\/h3>\n<p>If you don\u2019t want to change your HTML markup, you can use HTTP to send MP4s to Safari with content negotiation. In order to do so, you must generate multiple copies of your cinemagraphs (just like before) and <code>Vary<\/code>responses based on both the <code>Accept<\/code> and <code>User-Agent<\/code> headers.<\/p>\n<p>This will get a bit cleaner once <a href=\"https:\/\/bugs.webkit.org\/show_bug.cgi?id=179178\">WebKit BUG 179178<\/a> is resolved and you can add a test for the <code>Accept: video\/*<\/code> header, (the same way that you can test for <code>Accept: image\/webp<\/code>, now). But the end result is that each browser gets the best format for <code>&lt;img&gt;<\/code>-based micro-form videos that it supports:<\/p>\n<figure class=\"table-wrapper\"><table>\n<thead>\n<tr>\n<th>Browser<\/th>\n<th>Accept Header<\/th>\n<th>Response<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Safari TP41+<\/td>\n<td><\/td>\n<td>H.264 MP4<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>Accept: video\/mp4<\/td>\n<td>H.264 MP4<\/td>\n<\/tr>\n<tr>\n<td>Chrome 42+<\/td>\n<td>Accept: image\/webp<\/td>\n<td>aWebP<\/td>\n<\/tr>\n<tr>\n<td>Opera 15<\/td>\n<td>Accept: image\/webp<\/td>\n<td>aWebP<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>Accept: image\/apng<\/td>\n<td>aPNG<\/td>\n<\/tr>\n<tr>\n<td>Default<\/td>\n<td><\/td>\n<td>GIF<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n<p>In nginx this would look something like:<\/p>\n<pre class=\"js-syntax-highlighted\"><code>if ($http_user_agent ~* &quot;Safari\/605[.0-9]+$&quot;) {\n   rewrite ^\/(.*)$ https:\/\/www.domain2.com\/$1 permanent;\n}\n\nmap $http_user_agent $mp4_suffix {\n    default   &quot;&quot;;\n    \u201c~*Safari\/605\u201d  &quot;.mp4&quot;;\n  }\n\nlocation ~* .(gif)$ {\n      add_header Vary Accept;\n      try_files $uri$mp4_suffix $uri =404;\n    }\n\n<\/code><\/pre>\n<p>Of course, don\u2019t forget the <code>Vary: Accept, User-Agent<\/code> to tell coffee-shop proxies and your CDN to cache each response differently. In fact, you should probably mark the Cache-Control as private and use TLS to ensure that the less sophisticated ISP Performance-Enhancing-Proxies don\u2019t cache the content.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"HTTP\" data-shcb-language-slug=\"http\"><span><code class=\"hljs language-http shcb-wrap-lines\"><span class=\"hljs-keyword\">GET<\/span> <span class=\"hljs-string\">\/example.gif<\/span> HTTP\/1.1\n<span class=\"hljs-attribute\">Accept<\/span>: image\/png; video\/*; *\/*\n<span class=\"hljs-attribute\">User-Agent<\/span>: User-Agent: Mozilla\/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit\/605.1.13 (KHTML, like Gecko) Version\/11.1 Safari\/605.1.13\n\n\u2026\n\nHTTP\/1.1 200 OK\nContent-Type: video\/mp4\nContent-Length: 22378567\nVary: Accept, User-Agent\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTTP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">http<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<h3>Option 3: Use RESS and Fall Back to <code>&lt;video&gt;<\/code> Tag<\/h3>\n<p>If you can manipulate your HTML, you can adopt the Responsive-Server-Side (RESS) technique. This option moves the browser detection logic into your HTML output.<\/p>\n<p>For example, you could do it like this with PHP:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> <span class=\"hljs-keyword\">if<\/span>(strlen(strstr($_SERVER&#91;<span class=\"hljs-string\">'HTTP_USER_AGENT'<\/span>],<span class=\"hljs-string\">\"Safari\/605\"<\/span>)) &lt;= <span class=\"hljs-number\">0<\/span> ){ <span class=\"hljs-comment\">\/\/ if not firefox <span class=\"hljs-meta\">?&gt;<\/span><\/span><\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\u201dexample.mp4\u201d<\/span>&gt;<\/span>\n<span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> } <span class=\"hljs-keyword\">else<\/span> {<span class=\"hljs-meta\">?&gt;<\/span><\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\u201dexample.gif\u201d<\/span>&gt;<\/span>\n<span class=\"php\"><span class=\"hljs-meta\">&lt;?php<\/span> }<span class=\"hljs-meta\">?&gt;<\/span><\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>As above, be sure to emit a <code>Vary: User-Agent<\/code> response to inform your CDN that there are different versions of your HTML to cache. Some CDNs automatically honor the <code>Vary<\/code> headers while others can support this with a simple update to the CDN configuration.<\/p>\n<p><strong>Bonus:<\/strong> Don\u2019t forget to remove the audio track.<\/p>\n<p>Now, since you aren\u2019t converting GIF to MP4s but rather you are converting MP4s to GIFs, we should also remember to strip the audio track for extra byte savings. (Please tell me you aren\u2019t using GIFs as your originals. Right?!) Audio tracks add extra bytes that we can quickly strip off since we know that our videos will be played on mute anyway. The simplest way to do this with ffmpeg is:<\/p>\n<pre class=\"js-syntax-highlighted\"><code>ffmpeg -i cats.mp4 -vcodec copy -an cats.mp4\n<\/code><\/pre>\n<h2>Are There Size Limits?<\/h2>\n<p>As I\u2019m writing this, Safari will blindly download whatever video you specify in the <code>&lt;img&gt;<\/code> tag, no matter how long it is. On the one hand, this is expected because it helps improve the performance of the browser. Yet, this can be deadly if you push down a 120-minute video to the user. I\u2019ve tested multiple sizes and all were downloaded as long as the user hung around. So, be courteous to your users. If you want to push longer-form video content, use the <code>&lt;video&gt;<\/code> tag for better performance.<\/p>\n<h2>What\u2019s Next? Responsive Video and Hero Backgrounds<\/h2>\n<p>Now that we can deliver MP4s via <code>&lt;img&gt;<\/code> tags, doors are opening to many new use cases. Two that come to mind: responsive video, and background videos. Now that we can put MP4s in <code>srcset<\/code>s, vary our responses for them using Client Hints and Content-DPR, and art direct them with <code>&lt;picture media&gt;<\/code>, well \u2013 think of the possibilities!<\/p>\n<pre class=\"js-syntax-highlighted\"><code>&lt;img src=&quot;cat.mp4&quot; alt=&quot;cat&quot;\n  srcset=&quot;cat-160.mp4 160w, cat-320.mp4 320w, cat-640.mp4 640w, cat-1280.mp4 1280w&quot;\n  sizes=&quot;(max-width: 480px) 100vw, (max-width: 900px) 33vw, 254px&quot;&gt;\n<\/code><\/pre>\n<p>Video in CSS <code>background-image: url(.mp4)<\/code> works, too!<\/p>\n<pre class=\"js-syntax-highlighted\"><code>&lt;div style=\u201dwidth:800px, height: 200px, background-image:url(colin.mp4)\u201d\/&gt;\n<\/code><\/pre>\n<h2>Conclusion<\/h2>\n<p>By enabling video content in <code>&lt;img&gt;<\/code> tags, Safari Technology Preview is paving the way for awesome GIF-like experiences, <em>without<\/em> the terrible performance and quality costs associated with GIF files. This functionality will be fantastic for users, developers, designers, and the web. Besides the enormous performance wins that this change enables, it opens up many new use cases that media and <a href=\"https:\/\/cloudinary.com\/guides\/e-commerce-platform\/select-the-right-e-commerce-platform-for-your-needs\">e-commerce businesses<\/a> have been yearning to implement for years. Here\u2019s hoping the other browsers will soon follow. Google? Microsoft? Mozilla? Samsung? Your move!<\/p>\n<p><em>This was originally posted on <a href=\"https:\/\/calendar.perfplanet.com\/2017\/animated-gif-without-the-gif\/\">Performance Calendar<\/a><\/em><\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":21647,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[128,227,305],"class_list":["post-21646","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-gif","tag-performance-optimization","tag-video-api"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>MP4 vs. GIF | Embed MP4 in HTML Tags for Improved GIF-Like Experience<\/title>\n<meta name=\"description\" content=\"Learn how to use MP4 in HTML tags to produce the GIF experience while saving space and providing a better user experience.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Evolution of &lt;img&gt;: Gif Without the GIF\" \/>\n<meta property=\"og:description\" content=\"Learn how to use MP4 in HTML tags to produce the GIF experience while saving space and providing a better user experience.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2018-01-03T17:28:31+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-11-07T00:15:37+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649720751\/Web_Assets\/blog\/Mario_1\/Mario_1.gif?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"700\" \/>\n\t<meta property=\"og:image:height\" content=\"432\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/gif\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Evolution of &lt;img>: Gif Without the GIF\",\"datePublished\":\"2018-01-03T17:28:31+00:00\",\"dateModified\":\"2025-11-07T00:15:37+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif\"},\"wordCount\":8,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649720751\/Web_Assets\/blog\/Mario_1\/Mario_1.gif?_i=AA\",\"keywords\":[\"GIF\",\"Performance Optimization\",\"Video API\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2018\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif\",\"url\":\"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif\",\"name\":\"MP4 vs. GIF | Embed MP4 in HTML Tags for Improved GIF-Like Experience\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649720751\/Web_Assets\/blog\/Mario_1\/Mario_1.gif?_i=AA\",\"datePublished\":\"2018-01-03T17:28:31+00:00\",\"dateModified\":\"2025-11-07T00:15:37+00:00\",\"description\":\"Learn how to use MP4 in HTML tags to produce the GIF experience while saving space and providing a better user experience.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649720751\/Web_Assets\/blog\/Mario_1\/Mario_1.gif?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649720751\/Web_Assets\/blog\/Mario_1\/Mario_1.gif?_i=AA\",\"width\":700,\"height\":432,\"caption\":\"GIF Image showing various versions of Super Mario running\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Evolution of &lt;img>: Gif Without the GIF\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"MP4 vs. GIF | Embed MP4 in HTML Tags for Improved GIF-Like Experience","description":"Learn how to use MP4 in HTML tags to produce the GIF experience while saving space and providing a better user experience.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif","og_locale":"en_US","og_type":"article","og_title":"Evolution of &lt;img>: Gif Without the GIF","og_description":"Learn how to use MP4 in HTML tags to produce the GIF experience while saving space and providing a better user experience.","og_url":"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif","og_site_name":"Cloudinary Blog","article_published_time":"2018-01-03T17:28:31+00:00","article_modified_time":"2025-11-07T00:15:37+00:00","og_image":[{"width":700,"height":432,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649720751\/Web_Assets\/blog\/Mario_1\/Mario_1.gif?_i=AA","type":"image\/gif"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif"},"author":{"name":"","@id":""},"headline":"Evolution of &lt;img>: Gif Without the GIF","datePublished":"2018-01-03T17:28:31+00:00","dateModified":"2025-11-07T00:15:37+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif"},"wordCount":8,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649720751\/Web_Assets\/blog\/Mario_1\/Mario_1.gif?_i=AA","keywords":["GIF","Performance Optimization","Video API"],"inLanguage":"en-US","copyrightYear":"2018","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif","url":"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif","name":"MP4 vs. GIF | Embed MP4 in HTML Tags for Improved GIF-Like Experience","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649720751\/Web_Assets\/blog\/Mario_1\/Mario_1.gif?_i=AA","datePublished":"2018-01-03T17:28:31+00:00","dateModified":"2025-11-07T00:15:37+00:00","description":"Learn how to use MP4 in HTML tags to produce the GIF experience while saving space and providing a better user experience.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649720751\/Web_Assets\/blog\/Mario_1\/Mario_1.gif?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649720751\/Web_Assets\/blog\/Mario_1\/Mario_1.gif?_i=AA","width":700,"height":432,"caption":"GIF Image showing various versions of Super Mario running"},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/evolution_of_img_gif_without_the_gif#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Evolution of &lt;img>: Gif Without the GIF"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649720751\/Web_Assets\/blog\/Mario_1\/Mario_1.gif?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/21646","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=21646"}],"version-history":[{"count":9,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/21646\/revisions"}],"predecessor-version":[{"id":39144,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/21646\/revisions\/39144"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/21647"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=21646"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=21646"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=21646"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}