摘要:我不該動你的,寫在前面的話本意是想好好研究下,看了幾篇博客后,才意識到作為前端打字員的我有多無知,這坑忒深了。這樣的話,如果是第一種解釋,應該在運行之前,頁面就變成了紅色否則就應該采取第二種解釋。
我不該動你的,Event Loops 寫在前面的話
本意是想好好研究下 Event Loops, 看了幾篇博客后,才意識到作為前端打字員的我有多無知,這坑忒深了。
macrotask?,microtask?,MutationObserver? 這些都是啥?規范還沒寫清楚?不同瀏覽器運行的還未必一樣?
但為了使自己養成經常總結的習慣,還是寫點什么吧。
故事的開始計算 fib(45) 是一個相當耗時的工作,在我的chrome里約需要15s左右。
問,頁面什么時候會變成紅色?在執行 console.now(1) 之前就變成紅色了嗎?
可以看到即使在 console.now(1) 執行之后,頁面仍舊沒有變紅。
關于這個現象,可以有兩種解釋:
document.getElementsByTagName("body")[0].style.backgroundColor = "red" 被當作一個異步事件,作為一個 task,被添加到 event loops
渲染引擎要等到 JS 引擎空閑時才開始工作
到底是哪一種?所以將上述代碼修改下
又增加了一個 setTimeout。這樣的話,如果是第一種解釋,應該在 console.now(3) 運行之前,頁面就變成了紅色;否則就應該采取第二種解釋。
運行結果如下,
可以看到在 console.now(3) 之后,頁面依舊沒有變色,看來就是渲染引擎要等到JS引擎完全空閑時才工作。
事情就這樣結束了嗎沒有,直到我看到文檔
An event loop must continually run through the following steps for as long as it exists:
Let oldestTask be the oldest task on one of the event loop"s task queues, if any, ignoring, in the case of a browsing context event loop, tasks whose associated Documents are not fully active. The user agent may pick any task queue. If there is no task to select, then jump to the microtasks step below.
Set the event loop"s currently running task to oldestTask.
Run oldestTask.
Set the event loop"s currently running task back to null.
Remove oldestTask from its task queue.
Microtasks: Perform a microtask checkpoint.
Update the rendering: If this event loop is a browsing context event loop (as opposed to a worker event loop), then run the following substeps.
…...
這段話第7點的意思,怎么理解起來像是每執行一次 Event Loops 的 task,最后都會更新視圖。
后來看到從event loop規范探究javaScript異步及瀏覽器更新渲染時機中
渲染更新(Update the rendering)會在event loop中的tasks和microtasks完成后進行,但并不是每輪event loop都會更新渲染,這取決于是否修改了dom和瀏覽器覺得是否有必要在此時立即將新狀態呈現給用戶。
會不會兩次 setTimeout 被合并了?
這樣調整之后,在運行 console.now(3) 之前,頁面的顏色就變了
這樣看來,就是在每一次task之后就可能會更新視圖,而不是等到JS引擎空閑
在執行完setTimeout0后,Event Loops 中實際上仍有 setTimeout1 待執行,但是瀏覽器先渲染了視圖,再執行了setTimeout ,這就推翻了之前渲染引擎要等到 JS 引擎空閑(Event Loops為空)時才開始工作。
同時我懷疑,之前代碼
setTimeout(function () { console.now(0) document.getElementsByTagName("body")[0].style.backgroundColor = "red" console.now(1) fib(45) console.now(2) }, 1000) setTimeout(function () { console.now(3) fib(45) console.now(4) }, 1000)
會不會被優化成
setTimeout(function () { console.now(0) document.getElementsByTagName("body")[0].style.backgroundColor = "red" console.now(1) fib(45) console.now(2) console.now(3) fib(45) console.now(4) }, 1000)坑深,今天先到這,休息下了 參考資料
https://github.com/aooy/blog/...
https://www.404forest.com/201...
http://javascript.ruanyifeng....
https://www.html5rocks.com/zh...
https://github.com/fredshare/...
http://lynnelv.github.io/js-e...
https://www.w3.org/TR/html5/w...
https://jakearchibald.com/201...
https://zhuanlan.zhihu.com/p/...
https://developers.google.com...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/90571.html
摘要:具體的可以用下面的圖來大致說明一下同步和異步任務分別進入不同的執行環境,同步的進入主線程,即主執行棧,異步的進入。主線程內的任務執行完畢為空,會去讀取對應的任務,推入主線程執行。 前言 眾所周知,JavaScript是一門單線程語言,雖然在html5中提出了Web-Worker,但這并未改變JavaScript是單線程這一核心。可看HTML規范中的這段話: To coordinate ...
摘要:規范中定義了瀏覽器何時進行渲染更新,了解它有助于性能優化。結合一些資料,對上邊規范給出一些理解有誤請指正每個線程都有自己的。列為,列為,列為。我們都知道是單線程,渲染計算和腳本運行共用同一線程網絡請求會有其他線程,導致腳本運行會阻塞渲染。 本文轉自blog 轉載請注明出處 異步的思考 event loops隱藏得比較深,很多人對它很陌生。但提起異步,相信每個人都知道。異步背后的靠山就是...
摘要:跨域請求詳解從繁至簡前端掘金什么是為什么要用是的一種使用模式,可用于解決主流瀏覽器的跨域數據訪問的問題。異步編程入門道典型的面試題前端掘金在界中,開發人員的需求量一直居高不下。 jsonp 跨域請求詳解——從繁至簡 - 前端 - 掘金什么是jsonp?為什么要用jsonp?JSONP(JSON with Padding)是JSON的一種使用模式,可用于解決主流瀏覽器的跨域數據訪問的問題...
摘要:如果某線程并未使用很多操作,它會在自己的時間片內一直占用處理器和。在中使用線程在和等大多數類系統上運行時,支持多線程編程。守護線程另一個避免使用模塊的原因是,它不支持守護線程。 這一篇是Python并發的第四篇,主要介紹進程和線程的定義,Python線程和全局解釋器鎖以及Python如何使用thread模塊處理并發 引言&動機 考慮一下這個場景,我們有10000條數據需要處理,處理每條...
閱讀 1652·2021-08-13 15:03
閱讀 2082·2019-08-30 15:54
閱讀 3544·2019-08-26 10:30
閱讀 1020·2019-08-26 10:22
閱讀 2746·2019-08-23 14:42
閱讀 1809·2019-08-22 11:16
閱讀 1038·2019-08-21 18:33
閱讀 3159·2019-08-21 17:28