瀏覽器解析JS機制
一、瀏覽器的運行機制
瀏覽器是多進程的,其中包含了:
1)GPU進程
2)第三方插件進程
3)瀏覽器渲染進程
4)Browser進程
這里面的進程很好理解,瀏覽器本身,第三方插件擴容,瀏覽器渲染,GPU。其中,瀏覽器渲染JS就是通過瀏覽器渲染進程進行的。
瀏覽器渲染引擎是多線程的,其中包括以下線程:
1)GUI渲染線程 ---> 界面渲染
2)JS引擎線程 ---> JS處理
3)事件觸發線程 ---> 事件處理
4)定時器線程 ---> 定時器處理
5)http異步請求線程 ----> 異步請求處理
一般我們前端所學的就是對以上線程的操作和處理,管理好以上線程對我們前端技術能夠有很大的提升。
二、JS引擎線程處理
在JS引擎線程中,可以分為同步和異步任務,其中:
1)同步任務全部通過主線程執行,形成 執行棧
2)異步任務通過事件觸發線程或者定時器線程處理,形成 任務隊列
3)當執行棧中的任務全部處理完成,主線程為空閑的時候,會從任務隊列中提取任務到執行棧中執行。
以上就是瀏覽器中JS的執行機制。
三、瀏覽器中的任務類型及一些案例
JS引擎線程和GUI渲染是沖突的,因為JS引擎線程可能存在修改dom造成頁面 重繪(repatian) / 回流(reflow) 的操作,所以當JS引擎線程busy的時候會將GUI渲染線程放在隊列中,等待JS引擎線程空閑。
在進行前端性能優化的時候有時會遇到JS引擎線程需要計算大量數據造成GUI渲染線程長時間懸掛,導致頁面長時間無法加載的情況。這時候我們可以在JS中定義webworker, 它相當於在JS引擎線程外掛了一個線程,用於單獨處理大數據,長時間的任務。
有一道面試題是這樣的:
let a = 1; console.log(a); setTimeout( () => { console.log(a+1); }, 0); setTimeout( () => { console.log(a+2); }, 0); Promise.resolve().then( () => { console.log(a+3); }) console.log(a+4);
其結果為:
1 5 4 2 3
而為什么setTimeout(function(), 0) 會在大量同步操作后執行,是因為 setTimeout 和 setInterva 都是掛在定時器觸發線程下面, 也是需要等待執行棧的完成之后才能執行。
在JS中又兩種任務,同步任務和異步任務,又有兩種任務類型 macrotask 和 microtask :
1)macr0task: 宏任務,如主代碼塊任務,setTimeout,setInterval等,是從事件隊列中取一個事件回調放到執行棧中執行。
2)microtask:微任務,如Promise,Process.nextTick(),是執行棧執行完后立即執行的任務。