画像の圧縮

モバイルサイトは素早くモバイル端末にロードされ、端末リソースをあまり多く使用しないことが非常に重要です。モバイルウェブサイトでリソース消費が大きい要素のひとつがイメージです。flamingoを使ってスニペットを作成してモバイルサイトのイメージ圧縮に使用できます。

  1. 新しいスニペットを作成します
  2. 以下のコードをスニペットにコピー・ペーストします。
(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. イメージ圧縮を行いたいページ上でBODYタグの前でこの スニペットを呼び出します
  2. IMGタグの src 属性を修正し、data-src 属性を追加します。data-src 属性には元のイメージファイルへのパスが含まれ、src 属性にはローダーファイルへのパスが含まれる必要があります。例えば以下の通りです。

イメージには圧縮は適用されません。

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

イメージには圧縮が適用されます。

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