Behold the Power of WebP
If the below image has “webp” in the corner your browser can display WebP. If it has “jpeg” it is because your browser cannot show WebP images but the user experience remains the same. webp is a new image format pioneered by Google based on the VP8 video codec to reduce the download size of images on the web. My friend used webp images for his client’s boosting website. What I am presenting is a way to offer WebP images to browsers that support them while falling back to jpegs so that visitors still have the same user experience.
This page uses javascript to tests if your browser supports webp and loads the appropriate format. Native browser support is limited to Chrome 9+ and Opera 11.10 but thanks to @antimatter15 and his work WebP images can be displayed in any browser that supports WebM. It creates a single frame WebM video and places it in a <video> tag to replace the <img> tag. I have modified his original code to add support for jpeg fallback when WebP isn’t supported. This allows WebP to be used right now without showing broken images to browser that don’t support WebP.
Get the Javascript Code for WebP support here.
Using it
Add <script src="weppy.js"></script>
anywhere on the page but for the best performance add it add the end of your document right before the </body> tag. Then create your img tags like so:
<img alt="Baby Jesus and Mary" class="webp" data-src="baby-jesus-and-mary.jpg" />
data-* is a new html5 attribute is a completely valid way to provide arbitrary data accessible by Javascript. At first I tried setting the “src” to the jpeg and switching it to the WebP image after the javascript test to verify support for WebP. However doing this causes both image formats to be downloaded which means the page loads much slower. To prevent the jpeg from being loaded until needed the “src” must be empty and the “data-src” is used instead.
Browser support and issues
Native Webp support is currently available in Chrome 9+ and Opera 11.10. Support for WebP using a WebM video tag is available in
Chrome 7.0+, Opera 10.62+, Firefox 4.0 and even IE 9 with the WebM MF Components or IE6+ with Chrome Frame. I would estimate about 25% of internet users will be able take advantage of the WebP with weppy.js. In the next few months it will probably increase dramatically as more people adopt Chrome or upgrade to Firefox 4.. The major downside is that images will not work when javascript is turned off or web bots that don’t support javascript and won’t know about the image unless the “src” is valud. Since we are using the data-src attribute and dynamically changing it with javascript it’s difficult for any web spider to actually find the images. Depending on whether you want your website to show up in online image searches it could be a real downside to using WebP images. One workaround would be to duplicate each image in <noscript> tags like so:
<img data-src="image.jpg" class="webp" alt="an image" width="100" height="100" />
<noscript>
<img src="image.jpg" alt="an image" width="100" height="100" />
</noscript>
The major disadvantage with doing this is that it clutters up the html but it will ensure give everyone and everything can access your images.
Limitations of WebP images as WebM video
Since it creates a video tag from an img tag it’ll behave much differently. Naturally any css applied to img tags will have to be modified to apply to video tags as well. With an img tag the browser scales it to fit whatever width and height are set, but with video tags it will be scaled but the aspect ratio will always be the same as the native size of the image; it won’t be stretched to fit. since you should be setting the width and height to the image’s natural width and height this shouldn’t be an issue. To stream and download videos you might want to include, check the kodivedia website.
XmlHttpRequest is used to load the WebP image and create the WebM video and there may be a bit of a performance penalty because the image has to be loaded as binary data which has a little overhead. Also the WebP images have to be downloaded from same domain unless Cross-Origin Resource Sharing is used. Which basically means that the WebP file has to be served with the HTTP header:
Access-Control-Allow-Origin: *
WebP in CSS
There is currently no way to use WebP images in css backgrounds without native support and I havn’t found a good method of falling back to jpegs with pure css. weppy.js does add a “webp” class to the html element similar to how modernizer works. However this happens too late in the document loading process to prevent loading any jpeg images specified in the CSS. The only way I’ve seen to use WebP images in CSS is with server side browser detection to serve a special css file to browsers that support WebP. A similar method could also be done to create the src attributes for img tag eliminating the need for javascript. The downside to these methods is that they are based on the User-Agent header which is not always predictable and the User-Agent detection rules would have to be updated when new browsers add support for WebP.
Thanks for sharing the js for how to detect Webp. Have you found that the savings in download size offset the download+computation time of the additional js?
Also, would it be faster to just check for specific browser versions rather than trying to render the image? [Downside is that code needs to be constantly updated, and browser plugins to allow WebP support won’t get picked up]
Gah, I was hoping for a simpler implementation, but thank you for enlightening me on the situation and implementation procedures. I couldn’t find it anywhere else.
As many others have said, it’ll be a while before this can be implemented with ease. Even if space is saved with the offset of javascript, it’s another http request and adds formatting issues, so for me, it isn’t worth the time at the moment. However, I’m very much looking forward to when this becomes standard. Google rocks! Thanks guys for the heads up.
I found another solution at Stack Overflow
There is WebP implementation in Javascript supporting all major browsers:
http://webpjs.appspot.com
Thanks for the comment. Until recently I didn’t even know of webpjs but saw it mentioned on the webp mailing list recently. I had experimented doing something like this with emscripten but never got it to work very well. It is a very clever solution but I’m afraid it won’t prove to be very practical. It requires downloading a 30 kb js file and if using IE a 40 kb flash file. It also has significant CPU overhead as well to decode the webp file since js is rather slow. So in the end it probably faster to use jpegs for browser that don’t have native support for webp. I will probably review all the solutions in a separate blog post soon.