本篇文章通過圖文為你介紹了V8引擎大概的執行過程,你可以瞭解到代碼是從從掃描器Scaner變成tokens,從解析器Parser變成AST,從解釋器變成位元組碼等等。·以及JavaScript代碼在執行的過程中,它在記憶體的情況是如何變化的,讓你從更加底層的角度去理解你的js代碼是如何運行的。瞭解這些後... ...
本篇文章通過圖文為你介紹了V8引擎大概的執行過程,你可以瞭解到代碼是從掃描器Scaner變成tokens,從解析器Parser變成AST,從解釋器變成位元組碼等等。以及JavaScript代碼在執行的過程中,它在記憶體的情況是如何變化的,讓你從更加底層的角度去理解你的js代碼是如何運行的。瞭解這些後你就能從更加底層的角度去理解var的變數提升,閉包的形成等了。
瀏覽器原理
瀏覽器內核與js引擎
瀏覽器內核又稱“排版引擎”,“渲染引擎”,“瀏覽器引擎”,叫法很多,簡單來說乾的活就是將代碼(HTML,XML,CSS,圖片等)解析排版佈局後輸出到顯示器讓你看到。
JavaScript引擎是一個專門處理JavaScript腳本的虛擬機,一般會附帶在網頁瀏覽器之中。
主流瀏覽器內核與js引擎:
瀏覽器 | 內核 | js引擎 |
---|---|---|
Safari | WebKit | javaScriptCore |
Chrome | Blink | V8 |
firefox | Gecko | SpiderMonkey... |
瀏覽器渲染過程概述
輸入網址,伺服器返回html,瀏覽器內核開始解析html,遇到link 等之類則會暫停,去下載對應的css或者js。
- 首先hmtl會被解析為dom樹;
- 然後css會被解析為cssom規則樹;
- 根據dom樹和cssom規則樹構建渲染樹。
- 瀏覽器根據渲染數據進行佈局(迴流),此階段瀏覽器計算各節點在頁面中確切位置和大小,也稱自動重排。
- 佈局後進行繪製,將內容顯示在屏幕上。
渲染引擎不會等所有html解析完成後再去,構建render tree,而是解析完一部分就顯示一部分。以提高用戶體驗。
V8引擎的執行
V8引擎解析過程概述
BLinK內核遇到js代碼後,會以流的形式傳遞給v8,然其開始工作:
- 首先接收到流後,會有掃描器Scanner對其進行詞法分析將代碼轉化為
tokens
; - 然後解析器parser將其轉換為AST抽象語法樹。
- 再由解釋器ignition(圖中閃電部分)生成位元組碼再進行執行。
Parser再探:
Parser解析的時並不會進行全量解析(全部解析1.耗時間;2.解析後的位元組碼需放入記憶體耗記憶體),而是有延遲解析的策略,也就是一種按需解析給方案,( 理解:首先會Perpaser會解析出所需的最少限度的內容,比如內部有未調用的函數,則解析出函數聲明,當調用時則paser對該函數進行完整的解析 )。
Ignition再探:
Ignition關註的是減少 V8 的記憶體開銷,會進行執行前的優化工作。它會將AST進行分析將多次調用的函數標記為熱點函數 交由TurboFan進行編譯生成優化後的機器碼(優化,方便快速調用)執行。而單次調用的函數則會被生成位元組碼再做執行。所以它也會有編譯過程的,所以也有人對JS是否是解釋型語言有爭議。而正如最新的MDN上的文檔說的JavaScript是一種具有函數優先的輕量級,解釋型或即時編譯型的編程語言,應該是最準確的吧。
V8記憶體模型
V8的記憶體主要分為堆和棧兩部分,用以執行代碼,和JVM有點類似