Bloggerでレスポンシブデザインの画像サイズ問題を解決する方法

  0 件のコメント
Update:  picture/img + srcsetを使った例を末尾に追加しました。記事全体を<div>で囲む必要がないようにコードを単純化しました。
レスポンシブデザインでは、スマホからPCまで様々なサイズの画面に画像が表示されます。どの場合でもぼけずに綺麗な画像を表示しようとすると、最大サイズの画像を送るしかありません。しかし、画面の小さなスマホに対しては大きすぎて、データ転送量(=パケット代)とバッテリーの無駄。これがレスポンシブデザインの画像サイズ問題です。


どのくらいサイズが違うのか?

レスポンシブデザイン以前のブログでは、写真の表示サイズは自分が決めた値に固定だったのですが、レスポンシブデザインでは様々なサイズで画像が表示されるのでこのような問題が発生します。例えばiPhone6の解像度は横375pixel、対するPCでは(私のブログでは)940pixel。JPEGのファイルサイズ(=データ転送量)にすると5〜6倍も違います。

解決方法の候補

これを解決するには、デバイスの画面解像度に応じて複数サイズの画像から表示に最適なサイズのものを選んで、ブラウザに送るしかありません。調べたところ以下の方法がありました。原理的には以下の順でスマートそうなのですが:

① <picutre>のsrcsetで複数解像度の画像から自動選択可能とする(HTML5)。
② <img>のsrcsetで複数解像度の画像から自動選択可能とする(HTML5)。
③ まず最小の画像を表示し、後でJavascriptで適切な画像に置き換える。(※最初から置き換えたいところですが、置き換えるタイミングが存在しないよう。)

どれがベストか?

2016/1時点ではパーフェクトな解はなく、以下の順になりそうです。picutreとimgのsrcsetは原理的には同じはずですが、現時点ではブラウザにより少し異なる挙動となりました。

③ Javascript

画像の転送が2回発生するため、ページの転送時間が数百ms延びる。体感的には比べないとわからないレベルかも。転送データ量の増加は最低限なのであまり気にしなくていいかも。

① picture+srcset

IE11が未サポートで最大サイズの画像が表示される。EdgeはOK。Chrome,Firefox,Safariの最新版はOKそう。IE10以前は不明。ただし、IE11でも見られないわけではないし、モバイルでIEというパターンは少ないと思われるので、そろそろこの方法でも許容範囲かな? (デスクトップやノートPCでIE10以前という方がどの程度いらっしゃるかによりますね...。)

② img+srcset

同上。

ブラウザ以外に注意する点

上記はブラウザに関するものですが、FeedlyやPocketなどのサービスでは、いずれの方法でも多かれ少なかれ問題が出る可能性があります(コンテンツによるよう)。Javascriptでは最小の画像が表示に使われたり、picture/imgでsrcsetを使うと、そもそも画像が出なかったり。これらは意外に盲点かもしれません。

また、個人ブログなので簡単に適用できることも必要です。Blogger以外のブログサービスは知りませんが、Bloggerでは、画像を一つアップロードすると、URLの指定で任意サイズの画像を取得できます。これをJavascriptと組み合わせると、比較的簡単な記事ソースの修正で行けそうな感じです。これに対してpictureやsrcsetだと、変換プログラムを作らなくていけないくらい、記事HTMLソースへの修正が多そうです。

今回ご紹介する方法では、スクリプトの設置と、アップロードした画像のURLの一部書き換えで対応しています。これならまあ許容範囲ではないでしょうか。エディタに記事ソースをコピーして全置換という方法もありますし。

Blogger用の画像サイズ自動選択Javascript

以下のスクリプトを、記事のソース編集画面で記事の後に貼り付けます (最後の2行、<div id="MY-CONTENTS-AREA"> </div>も必須ですのでご注意ください)。このコードのポイントは、Bloggerにアップロードした画像は、URLの指定で簡単にサイズ指定できることを利用している点。わざわざ複数の解像度の画像を準備する必要がありません。(そういえばFlickrにも同じ機能がありますね。)

Bloggerでは、imgタグのsrc属性の中に.../s1600/...のような箇所がありますが、このs(sizeのs)の後ろの数字は長辺の画素数なので、表示領域の幅と代表的なスマホの解像度から適切な画像のサイズを決め(if文の部分)、この値を書き換えて(replace)やれば、ブラウザが画面サイズに応じた画像をサーバーに要求し、表示されます。

<script type="text/javascript">
<!--
function mmBloggerAutoImage(){
  var mca   =document.getElementById('MY-CONTENTS-AREA').parentNode;
  var clntw =mca.clientWidth;
  var imgs  =mca.getElementsByTagName('img');
  if (clntw>940){        imageSize="s1600";
  } else if (clntw>800){ imageSize="s940";
  } else if (clntw>640){ imageSize="s800";
  } else if (clntw>420){ imageSize="s640";
  } else if (clntw>375){ imageSize="s420";
  } else if (clntw>320){ imageSize="s375";
  } else if (clntw>200){ imageSize="s320";
  } else                 imageSize="s200";
  for(var i=0; i<imgs.length; i++){
    imgs[i].src = imgs[i].src.replace(/\/s.{1,4}\//g, '/'+imageSize+'/');
  }
}
document.addEventListener("DOMContentLoaded", mmBloggerAutoImage, false);
window.onresize = mmBloggerAutoImage;
-->
</script>
<div id="MY-CONTENTS-AREA">
</div>

※中身の背景をちょっと説明

スクリプトの最後の2行は、定番のソース書き換えに適切なタイミングのイベントの登録です。DOMContentLoaded (DOMの構築完了だが、HTMLソースの読み込み完了ではない。画像の要求は既に発行されてしまっている。)よりも早く、記事ソースのHTML読み込み後、画像の転送要求前に発生するイベントがあればいいのですが、それはなさそうです。

記事ソースの修正箇所

Bloggerで画像をアップロードすると、そのソースは以下のようになります。赤字のimgタグのsrc中のs1600、これが最初の転送に使う画像サイズになるので、s16とか小さくします。小さければ小さいほど転送量の無駄は減りますが、Feedlyではこの部分の画像を使っているようなので、豆粒画像になってしまいます。そこそこ見えるサイズにとどめるのであれば、ユーザー数の多いiPhone系に合わせ、s375がいいかもしれません。そこはさじ加減で。

<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOnGfOug0QW_MYcYKvKoAuC0h12rlM6Zutr-DO9XfNIp84d1y0mYty4exO4Mji7Nn26BcOhqqqZvRCvrMuL84oW8O2-t47ROgSxudgjuegXA1st8tck7w2Ylh1Ok-xR_zKak_-C2fCXfs/s1600/20160123_ONERYOKUDO-1.jpg" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOnGfOug0QW_MYcYKvKoAuC0h12rlM6Zutr-DO9XfNIp84d1y0mYty4exO4Mji7Nn26BcOhqqqZvRCvrMuL84oW8O2-t47ROgSxudgjuegXA1st8tck7w2Ylh1Ok-xR_zKak_-C2fCXfs/s1600/20160123_ONERYOKUDO-1.jpg" style="max-width: 100%;" /></a></div>

なお、記事の最初の画像はs1600のままにして、2枚目以降の値を小さくすることも考慮しましょう。1枚目の画像はその記事の代表画像として使われるため、解像度が小さすぎると、引き伸ばされてボケボケの画像になってしまいますので。

この方法で画像がどうなるかのサンプル

上記のスクリプトを設置し、記事画像のソースを修正したサンプルは以下のようになります。画面の幅を変えて、画像の右クリックなどで画像サイズを見ていただければ、画面幅にあったサイズの画像が転送されているのがわかると思います。(うまくいっていない場合はご連絡いただけると助かります。)

---

でもやっぱりカッコよくsrcsetとsizesを使いたい

【こちらの記事】に注意点とBloggerでのやり方をまとめました。サンプルは以下になります。

PICTURE

picture

IMG




0 件のコメント :

コメントを投稿

Related Posts Plugin for WordPress, Blogger...