JavaScript 更新 DOM elements 好卡

最近被問到一個 JavaScript 的問題,我覺得算是滿基本的。所以我很直覺的用一般的思維回答了錯誤的答案。 後來被糾正之後,我才恍然大悟最近再看的一些 UI 卡卡的問題的根本原因。

這個問題大概是這樣:


上面這段 Code 執行之後,Ajax 的 onSuccess handler 會不會在 for loop 到一半的時候被呼叫?還是會等到整個 postData 離開之後才有機會被呼叫呢?

我想大概只有我才會傻傻的說要看 for loop 有多 heavy … 我完全忘了考慮瀏覽器上的 JavaScript 環境都是 single thread,每一個 segment 都是一個 event request,而瀏覽器的 event queue 一次只有一個 event 能被處理。換句話說,當 postData 這個 function body segment 被執行的時候,是沒有任何人插的進去的。就算網路超快,Ajax request 立刻回來也沒機會立刻執行 onSuccess,一定要等到 postData segement 離開為止才有機會繼續處理 event queue 中的下一個 event!

我剎那間一驚,就是這個卡住我 UI 啊。


這樣寫的話 for loop segment 整個是一個 event ,每個 append 的 function call 都被 append 到 event queue 後面,所以想像一下如果 for loop 裡面做太多事情 update dom elements,你就會覺得整個 UI 卡住。但如果是寫 Web Application 很像不知不覺就會這樣寫。解決方法其實很容易,只要想辦法讓 for loop 的每一個 run 都變成一個獨立 event 就可以了。

最直覺得方式是這樣改:

但是這有個很嚴重的問題是如果 loop 裡有用到 i 的話會意想不到的 i 永遠都是 1000!所以比較好的應該是:

setTimeout 是一個很好的 trick 來建立獨立的 event 丟到 event queue 裡面,而時間值給 0 代表的是儘快的執行。這樣一改寫之後 browser 就會有機會可以在中途處理 user input event 並且也能夠看起來即時地更新 UI。



Comments
  1. 回覆
    • 回覆
  2. 回覆
  3. 回覆

Leave a Reply

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *