Compressing Images

It is very important that mobile site is loaded quickly on mobile devices and does not use too much device resources. One of the most resource-consuming elements of mobile web sites are images. In Flamingo, you can create a snippet and use it to compress images for your mobile site:

  1. Create a new snippet.
  2. Copy and paste the code below into your snippet.
(function(w, doc) {
   "use strict";

   var list = [],
       attribute = "data-src",
       apiURL = "http://ir.gomobile.i3design.com/api/resize",
       compression = {
           width: Math.max(doc.documentElement.clientWidth, doc.documentElement.clientHeight),
           height: 0,
           projectId: (w.Flamingo && w.Flamingo.dataUrl() || "")
                       .replace(/^(?:.*)\/([^\/]+)\/latest\/$/, "$1")
                       .replace(/^(?:.*)\/([^_]+)(?:[^\/]+)\/$/, "$1") || "unknown"
       };

   var Img = function(obj) {
       this.status = null;
       this.obj = obj;
       this.cap = obj.src;
       this.originalSrc = Img.makeOriginalSrc(obj.dataset.src);
       this.compressionSrc = [
               apiURL,
               compression.projectId,
               (obj.attributes.width && obj.attributes.width.value|0 || compression.width) * (w.devicePixelRatio || 1),
               compression.height,
               encodeURIComponent(this.originalSrc)
           ].join("/");

       this.init();
   };
       Img.prototype = {
           init: function() {
               this.obj.onload = this.success.bind(this);
               this.obj.onerror = this.error.bind(this);

               this.obj.removeAttribute(attribute);
           },
           deinit: function() {
               this.obj.onload = null;
               this.obj.onerror = null;
               clearListImg(this);
           },
           success: function() {
               this.status = "success";
               this.deinit();
           },
           error: function() {
               this.status = "error";

               var src;
               if (this.obj.src == this.compressionSrc)
                   src = this.originalSrc;
               else if (this.obj.src == this.originalSrc)
                   src = this.cap;

               if (src)
                   this.process(src);
           },
           process: function(src) {
               this.status = "process";
               this.obj.src = src && src || this.compressionSrc;
           }
       };

   Img.makeOriginalSrc = (function() {
       var anchor = doc.createElement("a");
       return function(src) {
           anchor.href = src;
           return anchor.href;
       };
   })();

   function arrayIterator(array, callback) {
       if (!array.length)
           return;

       var _l = array.length - 1,
           _1 = -1;

       while (_1 < _l) {
           if (callback(array[_1 += 1], _1) === false)
               break;
       }
   }

   function clearListImg(obj) {
       arrayIterator(list, function(el, index) {
           if (obj === el) {
               list.splice(index, 1);
               return false;
           }
       });
   }

   function imageProcession(name) {
       arrayIterator(list, function(el) {
           if (el.status !== null)
               return true;

           switch (name) {
               case "visible":
                   break;
               default:
                   el.process();
           }
       });
   }

   function imageCompression() {
       var elements = doc.querySelectorAll("img[" +attribute+ "]");
       if (!elements.length)
           return;

       arrayIterator(elements, function(el) {
           list.push(new Img(el));
       });

       imageProcession();
   }

   function run() {
       imageCompression();
       var intervalId = setInterval(function() {
           imageCompression();

           if (/^loaded|^i|^c/.test(doc.readyState)) {
               clearInterval(intervalId);
               return;
           }
       }, 250);
   }

   run();
 })(window, window.document);
  1. Call this snippet before the BODY tag on a page where you want to compress images.
  2. Modify the src attribute and add the data src attribute to the IMG tag. The data src attribute must contain the path to the original image file, and the src attribute must contain the path to the loader file, for example:

No compression is applied to the image:

<img width="150" src="/item/my-image.jpg">

Compression is applied to the image:

<img width="150" src="/images/loader.png" data-src="/item/my-image.jpg">