JavaScript程式碼是怎麼在瀏覽器裡面執行的?下面簡單探索一下
瀏覽器核心(Rendering Engine
),常見的叫法如:排版引擎、解釋引擎、渲染引擎,現在流行稱為瀏覽器核心。
瀏覽器 | 核心 | 說明 |
---|---|---|
IE | Trident | IE、獵豹安全、360極速瀏覽器、百度瀏覽器 |
FireFox | Gecko | 可惜這幾年已經沒落了,開啟速度慢、升級頻繁、豬一樣的隊友flash、神一樣的對手chrome。 |
Safari | Webkit | 從Safari推出之時起,它的渲染引擎就是Webkit,一提到 webkit,首先想到的便是 chrome,可以說,chrome 將 Webkit核心 深入人心,殊不知,Webkit 的鼻祖其實是 Safari。 |
Chrome | Chromium/Blink | 在 Chromium 專案中研發 Blink 渲染引擎(即瀏覽器核心),內建於 Chrome 瀏覽器之中。Blink 其實是 WebKit 的分支。大部分國產瀏覽器最新版都採用Blink核心。二次開發 |
Opera | Blink |
HTML
首先會被瀏覽器核心中的HTML Parser
解析,最終會構建成一顆DOM樹。
CSS
會被瀏覽器核心中的CSS Parser
解析,形成CSS規則,CSS規則和DOM樹結合形成一個渲染樹,通過layout(佈局)生成最終的渲染樹。
為什麼要有
layout
呢?因為要適配不同尺寸的螢幕。有了渲染樹之後就可以繪製展現出來了。
SpiderMonkey:第一款js引擎,由Brendan Eich開發(js作者)。
Chakra:微軟開發,由於IE瀏覽器。
JavascriptCore:webkit的js引擎,Apple公司開發。
V8:Google開發的強大js引擎,也幫助Chrome從眾多瀏覽器中脫穎而出。
這裡用webkit為列,webkit最重要的兩部分:
WebCore
: 負責HTML、CSS的解析、佈局、渲染等相關工作;JavascriptCore
:解析、執行js程式碼。下面是Chromium的架構圖
作用:javascript引擎幫助我們將js程式碼編譯成CPU認識的指令集,最終被cpu執行。
普通JavaScript引擎除了編譯之外還要負責執行以及記憶體管理。 js是解釋形語言,由引擎直接讀取原始碼,一邊編譯一邊執行,這樣效率相對較低,而編譯形語言(如c++)是把原始碼直接編譯成可直接執行的程式碼執行效率更高。
隨著技術的發展,對JavaScript效能的要求越來越高,V8引擎就是在此背景下產生的,它產生的目的就是為了提高javascript執行的效能。
V8引擎是一個JavaScript引擎實現,最初由一些語言方面專家設計,後被谷歌收購,隨後谷歌對其進行了開源。
V8使用C++開發,在執行JavaScript之前,相比其它的JavaScript的引擎轉換成位元組碼或解釋執行,V8將其編譯成原生機器碼(IA-32, x86-64, ARM, or MIPS CPUs),並且使用瞭如內聯快取(inline caching)等方法來提高效能。
V8引擎會先將javascript程式碼轉換成AST(抽象語法樹),事實上所有的程式語言都會將原始碼解析成抽象語法樹(abstract syntax tree, AST)。
AST是電腦科學中很早的一個概念,不是V8特有的(只是V8在轉換過程中做了非常多的優化),更不是javascript特有的。
AST的作用也不僅僅是用來在V8的編譯上,比如我們常用的babel外掛將 es6->es5 、ts->js 、死區分析、Dead Code、編譯壓縮打包、css前處理器、eslint等等,這些功能的實現都離不開AST。
瀏覽器核心將原始碼以流的方式交給v8引擎,v8引擎獲取到原始碼並進行編碼轉換
詞法分析Scanner,將程式碼轉成tokens
語法分析Parser、Preparser,直接將tokens轉換成AST樹結構
位元組碼生成
parser就是直接將tokens轉換成AST樹結構
preParse稱之為預解析,為什麼需要預解析呢?
這是因為並不是所有的js程式碼一開始就會被執行,如果對所有的js程式碼都進行解析,會影響網頁執行效率。所以v8引擎就實現了延遲解析的方案,將不必要的函數進行預解析,也就是隻解析暫時需要的內容,而對函數的全量解析是在函數被呼叫時才會進行
比如我們在一個函數outer內部定義了另外一個函數inner,那麼inner函數就會進行預解析
下面看一下線上解析AST的範例