2011年6月23日木曜日

<img src="" /> とした時に起きる、ブラウザ間での動作の違いについて

<img src="" /> としたときの動作をブラウザ別に並べよ。(一つのブラウザにバージョン別の挙動を書いても良い)
http://twitter.com/azu_re/status/83761909039505408

というので、img要素のsrc属性値を空にしたときの動作について、以前調べたものを今更だけど置いておきます。
調査目的は表題とは若干違って、<img src="http://~" /> という要素のsrcを空にした場合、その通信は停止するのかという事を知りたくて調べてました。
04WebServerというローカルサーバーを使って試していたので、Apacheなど一般的なものだと異なる可能性も捨てきれませんが参考程度に。
バージョンも古い事に注意してください。(おそらく動作は異なるように修正されている気がします)


2010年12月1日

目的:XHRDOMにより画像を読み込むことができるが、XHRabort()DOMsrc=""とすることで通信が本当に停止しているかを確認する。

  • Firefox 3.6.12
  • Chrome 7.0.517.44
  • Safari 5.0.3
  • Opera 10.63

XHR

abotによる停止

onabort

接続が切れてるか(サーバーのログから見る)

IE6-8

発生しない*1

500, Internal Server Error データ送信中に切断もしくはネットワークエラーが発生しました(以下500 Internal Server Error)

Firefox

発生

500, Internal Server Error

Chrome

発生

500, Internal Server Error

Safari

発生

500, Internal Server Error

Opera

発生しない

500, Internal Server Error

*1 IE6-8XHRにはonabort実装されていない

プロファイラを利用して確認

clip_image001

しかし、abort()後にxhr.readyState == 4となるため、自分でabortフラグを管理することでabort()によってreadyState==4 になったことがわかるのでonabortの代用は可能

DOM(Imageオブジェクトを使用) - example.htmlで実行した場合

停止(srcを空に)

onerrorイベント

空の場合の読み込み

接続が切れてるか(サーバーのログから見る)

IE6-8

発生

example.html

500, Internal Server Error

Firefox

発生しない

読み込まない

500, Internal Server Error

Chrome

発生

example.html

500, Internal Server Error

Safari

発生

example.html

500, Internal Server Error

Opera

発生しない

読み込まない

500, Internal Server Error

どちらの方法もサーバから切断しているため、通信は停止できたと思われる。
が、
IE6-8ではimg.src = "";としたときに、そのスクリプトがあるページ( example.html)を読み込もうと無駄な通信をしてしまう。

これは、属性値が空の場合の挙動がブラウザの実装依存になっているため、ブラウザ間で挙動の違いが存在し、属性値が空をページそのものと解釈して読み込み処理が起きてしまっている。
2010年のごく最近にWHATWGでの議論により、属性値が空の場合は読み込まれないことが適切という結論がでたらしい。

よってHTML5ES5ではこの結論を追従した実装になっているだろうという話。
下の記事によると
Firefox3.5Opera以外のブラウザで属性値が空の場合に無駄な読み込みが発生しているので、結果と一致している。

つまり、<img.src="" />としたことで、画像の読み込みが停止できているように見えるが、IEの場合には自分がいるページを読み込む無駄な通信が生まれてしまっている。Firefox以外ではonerrorが発生していることから、errorを発生させて画像の読み込みを停止させているのではないかと推測できる。(追記:この辺推測なので、正確性は保証されません)

DOMのImageオブジェクトでの読み込み停止は、実際にはエラーにより停止しているというのが近いのかもしれない。
window.stop()によってDOM(Imageオブジェクト)での読み込みも停止できるが、他の通信も止まる。(ブラウザによって異なるかも)

0 コメント:

コメントを投稿