Image Optimization with Cloudinary

By  on  

We're always looking for ways to improve site speed; we lazy load, minify and concatenate, create sprites, experiment with caching, and just about everything else we can think of.  With all of the performance optimization strategies available, the best way to decrease page size always comes back to image optimization.  Image optimization techniques include:

  • choosing the optimal image format
  • using the best compression algorithm
  • serving the optimized image size per device
  • serving images from a scaled, fast source
  • scale images to usage size

The idea behind image optimization is simple but the execution hasn't always been: each of those optimizations usually requires a separate solution which makes automation difficult.  Enter Cloudinary: uploading, storing, manipulating, and delivering images and videos on the web.

Quick Hits

A few important points about Cloudinary:

  • Cloudinary provides APIs for Node.js, Rails, django, PHP, jQuery, Angular, .NET, Java, iOS, Android, basic command line, and simple HTML src URL structure embedding
  • Cloudinary allows on the fly advanced manipulations including art-directed cropping, facial detection based transformations and more
  • Cloudinary automatically creates art-directed responsive images
  • Cloudinary provides an admin reporting interface
  • Cloudinary has a dozen plugins for further optimization of images and delivery
  • Cloudinary allows users to create custom transformations of images in their admin interface
  • Cloudinary has advanced cropping and positioning, including facial detection, social media avatar sizing, and more
  • Cloudinary has a fully featured offering for basic use-case available for free

Using Cloudinary

There are many use cases for a service like Cloudinary.  When I think about my site, I see one obvious need:  resized, optimized images on post list pages.  Google PageSpeed crucifies my site for image size and I can't blame them:  I have a regex routine that searches for the first image in a post and uses that as the post image, but the routine doesn't optimize images, so if the image is very large, I may scale it down with HTML attributes but the download size is still massive.

Cloudinary would easily solve my problem and in a variety of different ways, but I think the best route would be with Node.js.  I'd start by installing their module and then pushing an image to it:

// npm install cloudinary
var cloudinary = require('cloudinary');

// Setup
cloudinary.config({
        cloud_name: 'david-walsh-blog',
        api_key: '###############',
        api_secret: '###############'
});

// Get me my modified image!
cloudinary.image('logo.png', { width: 200, height: 200, crop: 'fill' });

What's returned is the img HTML tag for the resized, optimized image:

<img src='https://res.cloudinary.com/david-wash-blog/image/upload/c_fill,h_200,w_200/logo.png' height='200' width='200'/>

Since my blog runs on WordPress I could easily use the PHP API instead:

\Cloudinary\Uploader::upload("/home/logo.png");

/*
Array
(
[public_id] => c87hg9xfxrd4itiim3t0
[version] => 1371995958
[signature] => f8645b000be7d717599affc89a068157e4748276
[width] => 864
[height] => 576
[format] => jpg
[resource_type] => image
[created_at] => 2013-06-23T13:59:18Z
[bytes] => 120253
[type] => upload
[url] => https://res.cloudinary.com/demo/image/upload/v1371995958/logo.png
[secure_url] => https://res.cloudinary.com/demo/image/upload/v1371995958/logo.png
)
*/

To reduce calls to Cloudinary I can store the secure_url URL and use that when I build post list page output!  With the image up on the server, now you can retrieve and modify it!

Retrieving Images

One of the main takeaways from using Cloudinary is that it's ultra convenient to use a system that allows you to easily generate and retrieve a different image based on a URL.  Here are a few examples:

<!-- Use HTML to put image into account -->
<img src="https://res.cloudinary.com/demo/image/fetch/https://davidwalsh.name/demo/logo.png">

<!-- Create a Facebook social image -->
<img src="https://res.cloudinary.com/demo/image/facebook/w_150,r_max/logo.png">

<!-- Create a Twitter, sepia social image -->
<img src="https://res.cloudinary.com/demo/image/twitter/w_150,e_sepia/logo.png">

<!-- Create a greyscale image -->
<img src="https://res.cloudinary.com/demo/image/upload/e_grayscale/sample.jpg">

<!-- Create a YouTube screen image -->
<img src="https://res.cloudinary.com/demo/image/youtube/https://www.youtube.com/watch?v=aNwnPElsJGE">

<!-- Create a round-cornered, sized animated GIF -->
<img src="https://res.cloudinary.com/demo/image/upload/w_200,h_200,c_crop,r_max/kitten_fighting.gif">

<!-- Create a sized image overlay -->
<img src="https://res.cloudinary.com/demo/image/upload/l_face_left/w_200,h_200,c_thumb,g_face,r_max/fl_layer_apply,g_north_east/flower.jpg">

<!-- Use conditional overlays -->
<img src="https://res.cloudinary.com/demo/image/upload/if_w_lt_600/l_text:Arial_20:Image shown in full scale,co_white,g_south_east/c_scale,e_blur:400,u_small_dinosaur,w_600/if_end/v1458729247/small_dinosaur.jpg">

Though you can use just about every image modification feature by modifying the image URL, I'm going to use the Node.js API in some cases to give you a flavor of Cloudinary's different APIs.

Responsive Images

Cloudinary provides a jQuery plugin and strategy for responsive imagery, oftentimes used in grid systems:

<img data-src="https://res.cloudinary.com/david-walsh-blog/image/upload/w_auto/logo.jpg" class="cld-responsive">
// Using the jQuery plugin: https://cloudinary.com/documentation/jquery_integration#getting_started_guide
$.cloudinary.responsive(); // That's it!

You can modify the URLs to configure what image sizes you'd like:

Cloudinary Columns

I love that simple URL modification allows you to modify the format and size of an image -- it makes experimenting and prototyping a breeze.

Responsive Images with <picture>

If you're looking to serve media via the <picture> element for different media queries, Cloudinary has an excellent structure for doing that as well:

<picture>

  <!-- wide crop -->
  <source 
    media="(min-width: 600px)"
    srcset="https://res.cloudinary.com/eeeps/image/upload/c_fill,ar_2:1,g_face,f_auto,q_70,w_600/on_the_phone.jpg 600w,
            https://res.cloudinary.com/eeeps/image/upload/c_fill,ar_2:1,g_face,f_auto,q_70,w_1200/on_the_phone.jpg 1200w"
    sizes="100vw" />

  <!-- standard crop -->
  <img
    srcset="https://res.cloudinary.com/eeeps/image/upload/f_auto,q_70,w_400/on_the_phone.jpg 400w,
            https://res.cloudinary.com/eeeps/image/upload/f_auto,q_70,w_800/on_the_phone.jpg 800w"
    src="https://res.cloudinary.com/eeeps/image/upload/f_auto,q_70,w_400/on_the_phone.jpg"
    alt="President Obama on the phone in the Oval Office"
    sizes="100vw" />

</picture>

The above yields this awesome effect:

Image Format and Manipulation

You can convert image formats along the way:

// Format image to PNG
cloudinary.image("logo", { format: 'png' });

// Format image to 50% quality
cloudinary.image("logo.jpg", { quality: 50 });

// Get a thumbnail image of the second page of a PDF
cloudinary.image("multi_page_pdf.jpg", { width: 100, height: 140, crop: 'fill', page: 2 });

If you want to play with filters and other modifications:

cloudinary.image("smartphone.png", {
  underlay: "site_bg.jpg",
  width: 80, height: 80, effect: "brightness:100",
  transformation: {crop: 'fill', height: 80, width: 80 }
});

Automatic Format Conversion

Cloudinary's automatic format conversion functionality is really neat -- this feature replaces the original image format with a format that will be performant in the client browser.  Chrome will be provided a WebP image and IE users will get a JPEG-XR format image:

<!-- "f_auto" triggers automatic formatting -->
<img src="https://res.cloudinary.com/demo/image/upload/w_500,f_auto/sample.jpg">

These WebP and JPEG-XR format updates should provide an awesome performance load boost!  I highly recommend using it!

Video Customization

You can even customize video output, from simple sizing to watermarks and text additions:

<!-- Sized video -->
https://res.cloudinary.com/demo/video/upload/w_200,h_200,c_fill,g_north/dog.mp4

<!-- Video with overlay and brightness customizations -->
https://res.cloudinary.com/demo/video/upload/ac_none,w_500/l_cloudinary_icon,g_north_east,e_brightness:200,o_40,x_5,y_5,w_120/l_text:Roboto_34px_bold:Cute Dog,co_white,g_west,x_10,so_3/dog.mp4

Hosting your videos with Cloudinary will allow you to have the same advantages of manipulation and performant cloud hosting as your images will have!

Try Cloudinary!

Cloudinary is an awesome one-stop shop for uploading, storing, manipulating, and delivering images and video.  The APIs are all intuitive, effective, and easy to use.  The optimization plugs are all useful and the included face detection, sepia/greyscale transformations, and social media image creation a huge, handy bonus. You can sign up for Cloudinary for free to give it a shot -- they have loads of awesome documentation and example projects to get your started!

More Reading

Recent Features

  • By
    Write Simple, Elegant and Maintainable Media Queries with Sass

    I spent a few months experimenting with different approaches for writing simple, elegant and maintainable media queries with Sass. Each solution had something that I really liked, but I couldn't find one that covered everything I needed to do, so I ventured into creating my...

  • By
    Introducing MooTools Templated

    One major problem with creating UI components with the MooTools JavaScript framework is that there isn't a great way of allowing customization of template and ease of node creation. As of today, there are two ways of creating: new Element Madness The first way to create UI-driven...

Incredible Demos

  • By
    background-size Matters

    It's something that makes all men live in fear, and are often uncertain of. It's never spoken, but the curiosity is always there. Nine out of ten women agree in the affirmative. Advertisers do their best to make us feel inadequate but...

  • By
    Detect Vendor Prefix with JavaScript

    Regardless of our position on vendor prefixes, we have to live with them and occasionally use them to make things work.  These prefixes can be used in two formats:  the CSS format (-moz-, as in -moz-element) and the JS format (navigator.mozApps).  The awesome X-Tag project has...

Discussion

  1. I never heard of it. I’m using ShortPixel so far, with great results actually, but I’ll give it a try to this Cloudinary. Thanks!

  2. The best thing about Cloudinary is that it seamlessly applies advanced image size shrinking logic to make sure that your images are as small as possible without degrading their viewing quality.

  3. David, do you know of other examples of node-based optimizers that work in a fashion similar to cloudinary? I’m very interested in these methods for developing a “Sustainable Web Design” strategy. I was working on a “green boilerplate” with tools like this a few years ago, but now the route to go seems to be bundling cloud services into the design workflow.

    What would be awesome is if minifiers and compressors would allow the increase in efficiency to be recorded and stored. That would allow an LCA (Life-Cycle Assessment) model to be built for projects, similar to industrial design and architecture. And that in turn would allow reporting of a “carbon footprint” so web designers and devs could rank themselves as “green” services.

    So, if you find more things that improve WPO (and thereby increase web sustainability) please post. Tim Frick at MightyBytes, who created EcoGrader (http://ecograder.com) is finishing a book on Sustainable Web Design for O’Reilly would also be very interested (http://sustainablewebdesign.org).

  4. I have tried their service. The service is fast and generous – even the free plan is more than what a regular user needs.

  5. Thanks for sharing. Cloudinary has explained in the best way how to proceed for image optimization, which gonna be helping in decreasing the page load time of a website.

  6. Many thanks for the above article. I just wondered if there exists a comparison between say, simply minimizing images and using Cloudinary with regards to page speed / SEO performance? That is, can I know in advance how much extra performance I could generate from using Cloudinary?

    Many thanks for any useful comments on this,
    Regards
    Norbert

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!