Skip to main content

[探索 3 分鐘] 網頁 onload 與 onready 的發生順序

不知道各位辛苦的開發者, 從英文來解讀這兩個事件, 會不會遇到混淆 ? 每過一段時間, 我就會覺得觸發的順序是先 load 再 ready ? 因為 ready 放在最後面, 這才叫 ready 阿 ! 然後又記錯了, 是很嚴重的相反。只好來做一個探索筆記加深印象。

先講結論, 正確順序是先 ready 再 load, 所以聯想為 "ready to load", 這個口訣希望能幫到大家, 來一起念三次:
ready to load
ready to load
ready to load

OnLoad

首先, MDN 文件很清楚這麼說:
The load event is fired when a resource and its dependent resources have finished loading.
是完成 load 時被觸發, 也就是 on loaded, on finished, 不是 on loadstart 或 on loading。這是內建的 JavaScript 事件, 常見的用途是在 body.onload, image.onload, 代表資源載入完畢了, 正在操作的用戶開始欣賞美麗的視覺。

OnReady

這個是一個非標準的事件, 並沒有內建, 網路上查到的 onready, DOMContentReady, document.ready ..., 基本上都是後來加工的。最常見的加工就是 jQuery 提供的 $(document).ready 函式, 時機點是 DOM 文件讀取完畢, 進入 ready to load (開始讀取圖片, 影音...等資源), 但對 JavsScript 腳本語言來說, 是絕佳的程式進入點 (因為你可以拿到所有的 DOM 物件了)。

程式筆記

用程式碼來記憶一下順序, 我在系統中撒了一堆程式碼片段, 在 console.log 時也把流水號加上去, 方便了解觸發順序。以下你覺得 log 顯示順序為何呢 ?
  • document.addEventListener("DOMContentLoaded")
  • body onload
  • image onloadstart onloadeddata onload
  • video onloadstart onloadeddata onload onprogress
  • $(document).ready
  • $(function ())
  • (function ())();
用 Chrome 察看結果如下, 有沒有覺得哪裡怪怪的 ?
這是一張 5.7 MB的大圖, <img id="img" src="https://edmullen.net/test/rc.jpg" />。難道 image 的 onload 代表「開始讀取」? 讓我們取消快取再試一次看看,
還好正常了, 圖片讀取從第一順位消失了。剛剛是快取, Chrome 的 network 分頁有一個 disable cache 的勾勾, 點下去可以 always 關閉快取, 做實驗才會正常。

回到主題, 對這個載入順序做個小結論,
  1. 快取的 onload 順序最快 (在本地就 response 了, 而其他 DOM 跟 resources 都要等 remote response)
  2. 然後是全域的立即函式 (IIFE, Immediately Invoked Function Expression, is a JavaScript function that runs as soon as it is defined.)
  3. 然後是 document.DOMContentLoaded (這個名字取得很好啊, 就是 DOM 元素讀取完畢, 加上 ed 就是完成式, 不要取什麼 onload 不知道在幹嘛)
  4. 然後是 jQuery 的 $(document).ready 或 $(function ())
  5. 然後是資源讀取時間, 圖片, 影音檔... 
    • video/audio 的狀態事件較豐富, 依序有 onloadstart onloadeddata onload onprogress
    • image 的狀態事件這個實驗只試出 onload, 而且是讀取完畢的意思
  6. 緊接著就是 body.onload 了, 代表不僅是文件解析完畢, 連資源都讀取完畢了, 是一個非常後期的狀態 (那為什麼不叫 body.onloaded ?)
希望這個整理對大家有幫助, 也歡迎補充。

參考資料

  • https://developer.mozilla.org/en-US/docs/Web/Events/load
  • https://developer.mozilla.org/en-US/docs/Web/Events/loadstart
  • https://developer.mozilla.org/en/docs/Web/HTML/Element/video
  • https://developer.mozilla.org/en-US/docs/Glossary/IIFE
  • https://www.w3schools.com/jsref/event_onloadeddata.asp
  • https://www.phpied.com/when-is-a-stylesheet-really-loaded/
  • https://stackoverflow.com/questions/3698200/window-onload-vs-document-ready

Comments