MobileSafari でプログレスバーを出さないように画像を読み込む
MobileSafari では、どうやら window load のタイミングで画像の読み込みを開始したとしても、その画像の読み込みが完了するまでプログレスバーが表示され続けます。setTimeout などで読み込み開始時間をずらせば回避できますが、プログレスバーが消えたタイミングを取得する術はありません。
何が困るって、バックグラウンドで画像を読み込みたいのに、プログレスバーの表示が終わる前に読み込みを開始するとめちゃくちゃ重いページみたいな印象を与えてしまうわけです。
どうやら、XHR であれば通信中であってもプログレスバーが消えるようなので、次のサンプルコードの loadImage のようにして画像を取得すれば良さそうです。
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=320,user-scalable=no">
</head>
<body style="width:100%; height:1000px;">
<img id="img" width="100" height="75">
<script>
function loadImage(img, url, callback) {
if (location.search.indexOf('lazy=1') !== -1 && window.URL) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.addEventListener('load', function(evt) {
if (this.status === 200) {
var blob = this.response;
img.addEventListener('load', function(evt) {
window.URL.revokeObjectURL(img.src);
if (callback) {
callback(evt);
}
});
img.src = window.URL.createObjectURL(blob);
}
});
xhr.send();
} else {
if (callback) {
img.addEventListener('load', callback);
}
img.src = url;
}
}
var imageUrl = 'http://dev.abicky.net/hatena/pack_image/wood-fence-texture-04.png?s=' + Date.now();
window.addEventListener('load', function(evt) {
loadImage(document.getElementById('img'), imageUrl);
});
</script>
</body>
</html>
注意点
- blob がサポートされてないとけっこう辛い処理が必要
- 画像のドメインが異なる場合はヘッダに Access-Control-Allow-Origin を付与する必要がある
大きめの画像を読み込む時に試してみると、体感速くなったように感じてもらえるかもしれないですね!