img.onload 思考

是這樣的,今天群里基友發了張截圖

Paste_Image.png
Paste_Image.png

研究一下

1.頁面渲染過程

這個標題下的內容很適合做這篇文章的導讀

下面這張圖是webkit渲染過程


Paste_Image.png
Paste_Image.png

雖然是渲染過程,但能了解到圖片資源的加載是瀏覽器通過圖片加載器異步請求獲取的。

2.代碼執行情況

javascript是單線程序解釋器,一定時間內只能執行一段代碼。

  • 同步執行的任務放到主線程按加入順序執行
  • 異步任務扔到任務隊列,主線程執行完之后會從任務隊列里按照先入先出的方式取任務(忽略些細節)

setTimeout和setInterval創建的都是異步任務,扔到任務隊列,接受的第二個參數意思是再過多久取消等待狀態。里面的定時/間歇回調執行的條件是

1?? 主線程任務執行完畢
2?? 任務隊列里輪到你了:你前面沒別人了 或者 你前面有人但是他條件不足 仍處于等待執行狀態
3?? 你的等待狀態為 可以執行 了

有上述3個執行條件加上一些瀏覽器默認設置,比如最小設置時間數,立即執行的毫秒數不是0等限制和實現的不同,嚴格執行是個夢。
尤其是setInterval容易發生后一個調用在前一個調用結束前啟動。
so 先改成標準的間歇使用方式。

var img = new Image();
var timesize = 20;
img.onload = function(){//事件注冊程序扔到任務隊列-DOM0級事件注冊方法
    console.log("事件上鉤了!圖片已load:"+img.height)
}

function fixTimer () {
    if(!!!img.height){
        console.log("沒買著繼續排隊")
        setTimeout(fixTimer,timesize);//扔到任務隊列
    }else{
        console.log("買到啦回家!:"+img.height)
        console.log("定時器 done")
    }
}
img.src = "http://7jpswm.com1.z0.glb.clouddn.com/transitionSnip20160122_155.png"http://ImageLoader-瀏覽器資源異步加載

setTimeout(fixTimer,timesize);//扔到任務隊列

預測執行結果

讀過紅寶書的一定看到過這段話:

新圖像元素不一定從添加到文檔后才開始下載,只要設置了src屬性就會開始下載

為什么?
因為src一旦設置,瀏覽器就把活搶走了,開始調用ImageLoader來加載圖片,而且是瀏覽器行為
如代碼所示
任務隊列第一個是事件處理程序onload
任務隊列第二個是定時任務setTimeout

當主線程沒任務時 有三條時間線
1?? javascript 主線程輪詢任務隊列過程:有沒有可執行的 取決于 等待狀態 解鎖條件
2?? ImageLoader 資源請求過程:時間取決于圖片大小 網絡狀況
3?? 圖片資源下載完成的時間:決定解鎖 事件處理程序的執行

第一種情況

  • 主線程執行完
  • 圖片有點大 網還有點慢 還沒請求到
  • 事件處理程序 準備好了嗎?no
  • setTimeout 到時間了嗎? yes 執行 獲取到圖片高度了嗎 no 繼續創建一個扔到隊列
  • 圖片請求到了 也下載完了
  • 事件處理程序 準備好了嗎? yes 執行
  • setTimetout 到時間了嗎?yes 執行 獲取到圖片高度了嗎 yes done

這種情況輸出為

沒買著繼續排隊
事件上鉤了!圖片已load
買到啦回家!

第二種情況

  • 主線程執行完
  • 圖片小 網絡快 一下就請求到 下載完了
  • 事件處理程序 準備好了嗎? yes 執行
  • setTimetout 到時間了嗎?yes 執行 獲取到圖片高度了嗎 yes done

這種情況輸出為

事件上鉤了!圖片已load
買到啦回家!

實際代碼跑例

Paste_Image.png
Paste_Image.png

第三種情況

  • 主線程執行完
  • 圖片大 還沒請求到
  • 事件處理程序 準備好了嗎? no 不執行
  • setTimetout 到時間了嗎?yes 執行 獲取到圖片高度了嗎 no 繼續排著
  • 圖片大 還沒請求到
  • 事件處理程序 準備好了嗎? no 不執行
  • 圖片大 但是嘎嘣就請求到了
  • setTimetout 到時間了嗎?yes 執行 獲取到圖片高度了嗎 yes 不用排了
  • 事件處理程序 準備好了嗎? yes 執行
    輸出為
沒買著繼續排隊
買到啦回家!
事件上鉤了!圖片已load

實際代碼跑例 換了個大圖

Paste_Image.png
Paste_Image.png

這里面你還可以加入 圖片大 請求到了 但是還沒下載到的情況分析 請看下圖

Paste_Image.png

只有content download才會觸發通知事件

總結

其實還有幾種情況 比如主線程存在阻塞、定時任務中存在同步阻塞等
不過 本篇想說明的是

由于代碼運行環境的特殊性 忽略基本實現和協作實現 會造成遺漏或者不可預測的運行結果
比如這里
基本實現——瀏覽器內js的運行機制
協作實現——就是瀏覽器的資源加載器

補充

  • 2016-11-14

圖片下載時在沒有禁用緩存或者沒有加請求隨機變量的情況下 會緩存。
當圖片被緩存時是無法觸發onload的。
這時候可以用img.complete來做圖片準備好觸發回調的邏輯。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,646評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,595評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,560評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,035評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,814評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,224評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,301評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,444評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,988評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,804評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,998評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,544評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,237評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,665評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,927評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,706評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,993評論 2 374

推薦閱讀更多精彩內容

  • 從哪說起呢? 單純講多線程編程真的不知道從哪下嘴。。 不如我直接引用一個最簡單的問題,以這個作為切入點好了 在ma...
    Mr_Baymax閱讀 2,810評論 1 17
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,785評論 18 139
  • 從三月份找實習到現在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發崗...
    時芥藍閱讀 42,324評論 11 349
  • GCD簡介 GCD 是 libdispatch 的市場名稱,而 libdispatch 作為 Apple 的一個庫...
    獨木舟的木閱讀 1,267評論 0 5
  • 等,斜斜的殘陽慢慢消失 看,藹藹的暮色沉沉落下 聽,知了的歌聲響徹山谷 笑,大黃狗啃著骨頭奔跑 說,新舊故事都娓娓...
    螢染閱讀 287評論 2 1