一、前言
在《JS魔法堂:jsDeferred源碼剖析》中我們了解到img元素加載失敗可以作為函數異步執行的優化方案,本文打算對img元素的加載行為進行更深入的探討。
二、資源加載的相關屬性和事件
資源加載首先當然是確定資源位置的 src屬性 、隨之就是資源加載成功與否的 onload事件 和 onerror事件 ,對于IE5~10來說還多了一個 onreadystatechage事件 和與該事件相關聯的 readyState屬性 和 complete屬性 。
onload事件 ,當資源加載完成并成功解析后觸發(若加載的不是image/*類型的資源,則解析失敗)。
onerror事件 ,當找不到資源或解析失敗后觸發。
onreadystatechange事件 ,在onload事件后觸發。
readyState屬性 ,用于表示IMG元素當前的資源裝載狀態,默認值為"uninitialized",onload事件觸發后變為"complete"(onload事件處理函數運行時,readyState依然為"uninitialized")。
complete屬性 ,用于表示IMG元素的資源是否成功解析。默認為false,,onload事件觸發后變為true(onload事件處理函數運行時,readyState依然為false)。
src屬性 ,用于指定資源位置URI。常見的URI格式為 http://..... 、 https://... 、 javascript:... 和 data:image/*,... 。而不同的瀏覽器對不同的URI支持程度和行為均有所差異。關于URI的資訊可以參考:URI Scheme、Uniform resource identifier。
三、實驗開始
本次實驗將創建 img元素 并對其的 src屬性 分別賦予以下內容 fsjohnhuang.png 、 :0 、 空字符串 、 空白字符串 、 //:0 、 javascript:void 0 和 data:image/png,foo ,并訂閱img元素的onload和onerror事件,IE5~10下還訂閱了onreadystatechange事件,統計整理其在IE5~11、Chrome和FF下的行為特點和事件響應延時。具體實驗統計如下:
測試環境:
1.測試頁面地址為http://localhost:9000/test.html
2. 圖片fsjohnhuang.png的大小為12KB
符號說明:
N/A 表示該列事件不觸發。
src屬性值 | 備注 | Chrome | FireFox | IE5~11 | |||||||
onload事件 | onerror事件 | 備注 | onload事件 | onerror事件 | 備注 | onload事件 | onerror事件 |
IE5~10 on ready state change |
備注 | ||
fsjohnhuang.png |
有效URI, URI自動補全為 http://localhost :9000/fsjohnhu ang.png |
首次請求延時為2~5ms | N/A |
1.發起資源請求; 2.由于對資源進行緩存,后續對同一資源的請求,延時為0~1ms |
首次請求延時為4~10ms | N/A |
1.發起資源請求; 2.由于對資源進行緩存,后續對同一資源的請求,延時為0~1ms |
首次請求延時為3~9ms | N/A | 發生在onload事件之后 |
1.發起資源請求; 2.由于對資源進行緩存,后續對同一資源的請求,延時為0~1ms |
:0 |
無效URI, URI自動補全為http://localhost :9000/:0 若IMG元素 在渲染樹中, 則會顯示加載 失敗的示意圖。 |
N/A | 延時為5~300+ms | 1.發起資源請求 | N/A | 延時為16~60ms | 1.發起資源請求 | N/A | 首次請求延時為16ms左右 | N/A |
1.發起資源請求; 2.由于對資源進行緩存,后續對同一資源的請求,延時為0~1ms |
空字符串,"" | 無效URI | N/A | 延時為0~1ms |
1.不發起資源請求; 2. 若IMG元素在渲染樹中,不顯示加載失敗的示意圖。 |
N/A | N/A |
1.不發起資源請求; 2. 若IMG元素在渲染樹中,顯示加載失敗的示意圖。 |
N/A | 延時為0~1ms | N/A |
1.不發起資源請求; 2. 若IMG元素在渲染樹中,不顯示加載失敗的示意圖。 |
空白字符串," " | 無效URI | N/A | 延時為0~1ms |
1.不發起資源請求; 2. 若IMG元素在渲染樹中,不顯示加載失敗的示意圖。 |
N/A | 延時為16~60ms |
1.發起資源請求; 2. 若IMG元素在渲染樹中,顯示加載失敗的示意圖。 |
N/A | 首次延時為14ms左右 | N/A |
1.發起資源請求; 2. 若IMG元素在渲染樹中,顯示加載失敗的示意圖; 3. 由于對資源進行緩存,后續對同一資源的請求,延時為0~1ms |
//:0 | 無效URI,會自動補全為http://:0/ | N/A | 延時為0~1ms |
1.不發起資源請求; 2. 若IMG元素在渲染樹中,不顯示加載失敗的示意圖。 |
N/A | 延時為0~1ms |
1.不發起資源請求; 2. 若IMG元素在渲染樹中,顯示加載失敗的示意圖。 |
N/A | 延時為0~1ms | N/A |
1.發起資源請求,但會被瀏覽器取消掉(No Server Hits); 2. 若IMG元素在渲染樹中,顯示加載失敗的示意圖。 |
javascript:void 0 | 無效的JavaScript URI Scheme | N/A | 延時為1~2ms |
1.發起資源請求,但會被瀏覽器取消掉(No Server Hits); 2. 若IMG元素在渲染樹中,顯示加載失敗的示意圖。 |
N/A | 延時為1~2ms |
1.發起資源請求,但會被瀏覽器取消掉(No Server Hits); 2. 若IMG元素在渲染樹中,顯示加載失敗的示意圖。 |
N/A | N/A | N/A |
1.通過JS執行img.src= "javascript:void 0"會報"拒絕訪問"的異常。假如通過$.html()或靜態html方式設置src為javascript:void 0,則不會報該異常。 |
data:image/png,f |
無效的Data URI Scheme |
N/A | 延時0~1ms |
1.不會發起資源請求; 2. 若IMG元素在渲染樹中,顯示加載失敗的示意圖。 |
N/A | 延時為1~2ms |
1.不會發起資源請求; 2. 若IMG元素在渲染樹中,顯示加載失敗的示意圖。 |
N/A | 延時0~1ms | N/A |
1.不會發起資源請求; 2. 若IMG元素在渲染樹中,顯示加載失敗的示意圖。 |
由上述統計數據可知,在Chrome、FF和IE中行為比較同一的是加載無效DataURI Scheme。延時也比較短且穩定。因此jsDeffered采用此方式來為異步執行提速!
四、總結
這里僅僅對IMG元素加載http、javascript和data的URI Scheme等進行實驗,加上實驗手段等問題,難免導致統計數據不全面,若有紕漏希望大家指正,謝謝。
尊重原創,轉載請注明來自:http://www.cnblogs.com/fsjohnhuang/p/4148933.html ^_^肥子John
五、參考
http://www.w3help.org/zh-cn/causes/BX9021
http://stackoverflow.com/questions/5775469/whats-the-valid-way-to-include-an-image-with-no-src
文章列表