亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務,提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

瀏覽器內(nèi)核(渲染進程)

瀏覽器的渲染進程是多線程的!包含了哪些線程(列舉一些主要常駐線程):

GUI渲染線程

  • 負責渲染瀏覽器界面,解析html,css,構(gòu)建DOM樹和RenderObject樹,布局和繪制等。
  • 當界面需要重繪(Repaint)或由于某種操作引發(fā)回流(reflow)時,該線程就會執(zhí)行
  • 注意,GUI渲染線程與JS引擎線程是互斥的,當JS引擎執(zhí)行時GUI線程會被掛起(相當于被凍結(jié)了),GUI更新會被保存在一個隊列中等到JS引擎空閑時立即被執(zhí)行。

JS引擎線程

  • 也稱為JS內(nèi)核,負責處理JAVAscript腳本程序。(例如V8引擎)
  • JS引擎線程負責解析JavaScript腳本,運行代碼。
  • JS引擎一直等待著任務隊列中任務的到來,然后加以處理,一個Tab頁(renderer進程)中無論什么時候都只有一個JS線程在運行JS程序
  • 同樣注意,GUI渲染線程與JS引擎線程是互斥的,所以如果JS執(zhí)行的時間過長,這樣就會造成頁面的渲染不連貫,導致頁面渲染加載阻塞。

事件觸發(fā)線程

  • 歸屬于瀏覽器而不是JS引擎,用來控制事件循環(huán)(可以理解,JS引擎自己都忙不過來,需要瀏覽器另開線程協(xié)助)
  • 當JS引擎執(zhí)行代碼塊如setTimeOut時(也可來自瀏覽器內(nèi)核的其他線程,如鼠標點擊、AJAX異步請求等),會將對應任務添加到事件線程中
  • 當對應的事件符合觸發(fā)條件被觸發(fā)時,該線程會把事件添加到待處理隊列的隊尾,等待JS引擎的處理
  • 注意,由于JS的單線程關(guān)系,所以這些待處理隊列中的事件都得排隊等待JS引擎處理(當JS引擎空閑時才會去執(zhí)行)

定時觸發(fā)器線程

  • 傳說中的setInterval與setTimeout所在線程
  • 瀏覽器定時計數(shù)器并不是由JavaScript引擎計數(shù)的,(因為JavaScript引擎是單線程的, 如果處于阻塞線程狀態(tài)就會影響記計時的準確)
  • 因此通過單獨線程來計時并觸發(fā)定時(計時完畢后,添加到事件隊列中,等待JS引擎空閑后執(zhí)行)
  • 注意,W3C在HTML標準中規(guī)定,規(guī)定要求setTimeout中低于4ms的時間間隔算為4ms。

異步http請求線程

  • 在XMLHttpRequest在連接后是通過瀏覽器新開一個線程請求。
  • 將檢測到狀態(tài)變更時,如果設置有回調(diào)函數(shù),異步線程就產(chǎn)生狀態(tài)變更事件,將這個回調(diào)再放入事件隊列中。再由JavaScript引擎執(zhí)行。

梳理瀏覽器內(nèi)核中線程之間的關(guān)系

GUI渲染線程與JS引擎線程互斥:

由于JavaScript是可操縱DOM的,如果在修改這些元素屬性同時渲染界面(即JS線程和UI線程同時運行),那么渲染線程前后獲得的元素數(shù)據(jù)就可能不一致了。

WebWorker,JS的多線程:

  • 創(chuàng)建Worker時,JS引擎向瀏覽器申請開一個子線程(子線程是瀏覽器開的,完全受主線程控制,而且不能操作DOM)。
  • JS引擎線程與worker線程間通過特定的方式通信(postMessage API,需要通過序列化對象來與線程交互特定的數(shù)據(jù))。

從Event Loop談JS的運行機制

  • JS分為同步任務和異步任務
  • 同步任務都在主線程上執(zhí)行,形成一個執(zhí)行棧
  • 主線程之外,事件觸發(fā)線程管理著一個任務隊列,只要異步任務有了運行結(jié)果,就在任務隊列之中放置一個事件。
  • 一旦執(zhí)行棧中的所有同步任務執(zhí)行完畢(此時JS引擎空閑),系統(tǒng)就會讀取任務隊列,將可運行的異步任務添加到可執(zhí)行棧中,開始執(zhí)行。

 

Javascript運行機制深入

 

 

看到這里,應該就可以理解了:為什么有時候setTimeout推入的事件不能準時執(zhí)行?因為可能在它推入到事件列表時,主線程還不空閑,正在執(zhí)行其它代碼, 所以自然有誤差。

事件循環(huán)機制進一步補充

 

Javascript運行機制深入

 

 

  • 主線程運行時會產(chǎn)生執(zhí)行棧, 棧中的代碼調(diào)用某些api時,它們會在事件隊列中添加各種事件(當滿足觸發(fā)條件后,如ajax請求完畢)
  • 而棧中的代碼執(zhí)行完畢,就會讀取事件隊列中的事件,去執(zhí)行那些回調(diào)
  • 如此循環(huán)
  • 注意,總是要等待棧中的代碼執(zhí)行完畢后才會去讀取事件隊列中的事件

事件循環(huán)進階:macrotask與microtask

英文參考看這理

console.log('script start');
setTimeout(function() {
 console.log('setTimeout');
}, 0);
Promise.resolve().then(function() {
 console.log('promise1');
}).then(function() {
 console.log('promise2');
});
console.log('script end');
輸出效果是:
1
2
3
4

5script start

script end

promise1

promise2

setTimeout

為什么呢?因為Promise里有了一個一個新的概念:microtask

或者,進一步,JS中分為兩種任務類型:macrotask和microtask,在ECMAScript中,microtask稱為jobs,macrotask可稱為task

它們的定義?區(qū)別?簡單點可以按如下理解:

macrotask(又稱之為宏任務),可以理解是每次執(zhí)行棧執(zhí)行的代碼就是一個宏任務(包括每次從事件隊列中獲取一個事件回調(diào)并放到執(zhí)行棧中執(zhí)行)

  • 每一個task會從頭到尾將這個任務執(zhí)行完畢,不會執(zhí)行其它
  • 瀏覽器為了能夠使得JS內(nèi)部task與DOM任務能夠有序的執(zhí)行,會在一個task執(zhí)行結(jié)束后,在下一個 task 執(zhí)行開始前,對頁面進行重新渲染 (task->渲染->task->…)

microtask(又稱為微任務),可以理解是在當前 task 執(zhí)行結(jié)束后立即執(zhí)行的任務

  • 也就是說,在當前task任務后,下一個task之前,在渲染之前
  • 所以它的響應速度相比setTimeout(setTimeout是task)會更快,因為無需等渲染
  • 也就是說,在某一個macrotask執(zhí)行完后,就會將在它執(zhí)行期間產(chǎn)生的所有microtask都執(zhí)行完畢(在渲染前)

分別很么樣的場景會形成macrotask和microtask呢?

  • macrotask:主代碼塊,setTimeout,setInterval等(可以看到,事件隊列中的每一個事件都是一個macrotask)
  • microtask:Promise,process.nextTick等

補充:在node環(huán)境下,process.nextTick的優(yōu)先級高于Promise,也就是可以簡單理解為:在宏任務結(jié)束后會先執(zhí)行微任務隊列中的nextTickQueue部分,然后才會執(zhí)行微任務中的Promise部分。

process.nextTick(function(){
 console.log(7);
});
new Promise(function(resolve){
 console.log(3);
 resolve();
 console.log(4);
}).then(function(){
 console.log(5);
});
process.nextTick(function(){
 console.log(8);
});

這段代碼運行結(jié)果是3,4,7,8,5

所以,總結(jié)下運行機制:

  • 執(zhí)行一個宏任務(棧中沒有就從事件隊列中獲?。?/li>
  • 執(zhí)行過程中如果遇到微任務,就將它添加到微任務的任務隊列中
  • 宏任務執(zhí)行完畢后,立即執(zhí)行當前微任務隊列中的所有微任務(依次執(zhí)行)
  • 當前宏任務執(zhí)行完畢,開始檢查渲染,然后GUI線程接管渲染
  • 渲染完畢后,JS線程繼續(xù)接管,開始下一個宏任務(從事件隊列中獲?。?/li>

 

Javascript運行機制深入

 

 

分享到:
標簽:Javascript
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定