【綜合篇】瀏覽器的工做原理:瀏覽器幕後揭祕

web(給達達前端加星標,提高前端技能)前端

瞭解瀏覽器是如何工做的,可以讓你站在更高的角度去理解前端vue

瀏覽器的發展歷程的三大路線,第一是應用程序web化,第二是web應用移動化,第三是web操做系統化。是否是有點不直白。web

應用程序web化就是隨着如今技術的發展,如今愈來愈多的應用轉向了瀏覽器與服務器,就是B/S架構;web應用移動化,就是在移動設備應用,什麼是移動設備呢。面試

「移動設備:也被稱爲行動裝置(英語:Mobile device)、流動裝置、手持裝置(handheld device)等,是一種口袋大小的計算設備,一般有一個小的顯示螢幕,觸控輸入,或是小型的鍵盤。由於經過它能夠隨時隨地訪問得到各類信息,這一類設備很快變得流行。和諸如手提電腦和智能手機之類的移動計算設備一塊兒,PDA表明了新的計算機領域。」ajax

移動設備的優勢,方便性,靈活性,安全性,交互性,低成本。編程

什麼是應用程序Web化小程序

應用虛擬化、桌面虛擬化、服務器虛擬化......全球領先的雲計算、虛擬化系統平臺、應用程序發佈和程序web化IT產品提供商--GOOSUU Networks公司[高速計算機科技]。segmentfault

Web應用程序是一種經過Web訪問的應用程序,好處就是用戶容易訪問的應用程序,只須要有瀏覽器便可,不須要再安裝其餘軟件。api

應用程序的兩種模式C/S、B/Spromise

C/S是客戶端/服務器端程序,就是說這類程序通常獨立運行。

B/S是瀏覽器端/服務器端應用程序,這類應用程序通常藉助IE等瀏覽器來運行。WEB應用程序通常是B/S模式。Web應用程序首先是「應用程序」,和用標準的程序語言,如C、C++等編寫出來的程序沒有什麼本質上的不一樣。

Web應用程序有本身獨特的地方,就是它是基於Web的,而不是採用傳統方法運行的。換句話說,它是典型的瀏覽器/服務器架構的產物。

爲何要學習Web應用程序

Web應用程序開發,是目前軟件開發領域的三大方向之一。

什麼是web應用移動化

前端是個很大的概念,是用戶可以看到,直接接觸到的層面都算是前端,好比IOS客戶端界面,安卓客戶端界面,網頁界面,甚至PC/MAC 桌面端軟件界面,如今的說法通常是指Web前端,也就是針對於網頁端開發的工做。

Web App指的是【Web application】,也就是以瀏覽器做爲客戶端的軟件。

Mobile Web App 指在手機端打開的Web App,移動設備應用,渲染流程過於複雜且性能不及原生應用,離線時用戶沒法使用,沒法接收消息推送,移動端沒有一級入口。

什麼是web操做系統化

web操做系統

第一是利用web技術構建一個純粹的操做系統,如ChromeOS

第二是瀏覽器的底層結構往操做系統架構方向發展

基於 HTML5 構建 Web 操做系統

HTML5 具備兼容性好,安全性高,功能豐富,開發便捷等優勢,特別適合如 Web 操做系統一類的富客戶端互聯網應用的前端開發。

瀏覽器逐漸走向操做系統,瀏覽器中引入多種編程語言的支持,簡化渲染流程,使得渲染過程更加高效,加大了對系統設備特性的支持,提供對複雜web項目開發的支持。

瀏覽器中的JavaScript執行機制,瀏覽器端的Event Loop,瀏覽器的渲染機制與優化。

web apis

dom(document)

ajax(xmlhttprequest)

timeout(setTimeout)

瀏覽器裏面跑了不少進程,多進程,瀏覽器是multi-process,進程包含了線程,進程是咱們操做系統執行的最小的單位,一個進程佔用一個端口,一個進程裏面能夠包含多個線程。

一個瀏覽器只有一個browser process,負責管理tabs,協調其餘process和render process存至memory內的bitmap繪製到頁面上的。

瀏覽器端的Event Loop

一個函數執行棧,一個事件隊列,一個微任務隊列。

每一個事件隊列中取一個事件時有微任務就把微任務執行完,纔開始執行事件。

一段代碼的運行

從一段JavaScript源碼,解析,抽象語法樹,執行上下文,解釋器,字節碼,編譯器。

執行棧ECStack

執行棧

foo(),query(),hello(),web apis中,dom,ajax,setTimeout

任務隊列

onLoad,onClick。

事件隊列

添加事件,(其餘事件,樣式計算,佈局,定時器,JavaScript,dom,click)取出事件-》單線程執行事件,單線程,一次只能處理一個事件。

JavaScript的核心

對象,原型鏈,構造函數,執行上下文堆棧,執行上下文,變量對象,活動對象,做用域鏈,閉包,this。

運行時的描述

對於每一個執行上下文,三個重要的屬性,變量對象,做用域鏈,this。

執行上下文,第一,函數的形參,當進入到函數執行上下文時,變量對象的一個屬性,其屬性名就是形參的名字,其值就是實參的值,對於沒有傳遞的參數其值爲undefined。

函數聲明,變量對象的一個屬性,其屬性名和值都是函數對象建立出來的,若是變量對象已經包含了相同名字的屬性,則替換它的值。

變量聲明,變量對象的一個屬性,其屬性名即爲變量名,其值爲undefined,若是變量名和已經聲明的函數名或者函數的參數名相同,則不會影響已經存在的屬性。

變量對象

全局對象是一個進入任何執行上下文前就建立出來的對象,此對象以單例形式存在,它的屬性在任何地方均可以直接訪問,其生命週期隨着程序的結束而終止。

全局對象在建立的時候,這些屬性也被初始化,math,string,date,parseInt等等,同時,其中一些對象會指向全局對象自己,好比dom中,全局對象上的window屬性就指向了全局對象,可是,並不是全部的實現都是。

在引用全局對象的屬性時,前綴一般能夠省略,由於全局對象是不能經過名字直接訪問的,然而 ,經過全局對象上的this值,以及經過dom中的window對象這樣遞歸引用的方式能夠訪問到全局對象。

函數上下文中的變量對象

在函數的執行上下文中,變量對象在進入函數上下文的時候建立出來,初始化的時候會建立一個arguments屬性,其值就是arguments對象。

它的屬性有,callee對當前函數的引用,length實參的個數,properties-indexes的個數等於arguments.length,arguments對象的properties-indexs的值和當前形參是共享的。

處理上下文代碼的階段

分兩個階段,第一,進入執行上下文,第二,執行代碼。

函數的形參(當進入函數執行上下文時),變量對象的一個屬性,其屬性名就是形參的名字,其值就是實參的值,對於沒有傳遞的參數,其值爲undefined

函數聲明,變量對象的一個屬性,其屬性名和值都是函數對象建立出來的,若是變量對象已經包含了相同名字的屬性,則替換它的值

變量聲明,變量對象的一個屬性,其屬性名即爲變量名,其值爲undefined,若是變量名和已經聲明的函數名或者函數的參數名相同,則不會影響已經存在的屬性。

微任務和宏任務對頁面渲染的影響

setTimeout的不肯定性

是瀏覽器用於定時循環操做的一個接口,相似於setTimeout,主要用途是按針對網頁進行的重繪。

設置這個api的目的是爲了讓各類網頁動畫效果可以有一個統一的刷新機制,從而節省系統資源,提升系統性能,改善視覺效果,代碼中使用這個api,就是告訴瀏覽器但願執行一個動畫,讓瀏覽器在下一個動畫幀安排一次網頁重繪。

宏任務,tasks,一些異步任務的回調會依次進入macro task queue,等待後續被調用,異步任務:

微任務,jobs,另外一些異步任務的回調會一次進入micro task queue,等待後續被調用,異步任務包含:

process.nextTick(Node都有)

promise.then()

object.observe

mutaionObserver

promise

構造函數裏的代碼是同步執行的。

微任務能夠多個同時執行,宏任務一次只能執行一個。

Promise宏任務,Promise.then是微任務,宏任務先,console.log,再到微任務。

瀏覽器內核分紅兩部分:渲染引擎和js引擎

目前使用的主流瀏覽器有五個:

Internet Explorer、Firefox、Safari、Chrome 瀏覽器和 Opera。

瀏覽器的主要功能是向服務器發出請求,在瀏覽器窗口中展現您選擇的網絡資源。這裏所說的資源通常是指 HTML 文檔,也能夠是 PDF、圖片或其餘的類型。

資源的位置由用戶使用 URI(統一資源標示符)指定。

呈現引擎一開始會從網絡層獲取請求文檔的內容,內容的大小通常限制在 8000 個塊之內。

主流程示例

圖:WebKit 主流程

圖:Mozilla 的 Gecko 呈現引擎主流程

解析的過程能夠分紅兩個子過程:詞法分析和語法分析。

圖:從源文檔到解析樹

解析一般是在翻譯過程當中使用的,而翻譯是指將輸入文檔轉換成另外一種格式。

圖:編譯流程

學習瀏覽器的工做原理

第一,能夠評估web開發項目的可能性,第二,從更高的緯度去審視頁面,第三,在快節奏的技術迭代中把握本質。

爲啥打開一個頁面,有4個進程

Chrome打開一個頁面須要啓動多少進程?能夠點擊Chrome瀏覽器右上角的「選項」菜單,選擇「更多工具」子菜單,點擊「任務管理器」。查看進程,任務管理器。

多線程能夠並行處理任務,可是線程是不能單獨存在的,它是由進程來啓動和管理的。一個進程就是一個程序的運行實例。線程是依附於進程的,而進程中使用多線程並行處理能提高運算效率。

進程中的任意一線程執行出錯,都會致使整個進程的崩潰。線程之間共享進程中的數據。當一個進程關閉以後,操做系統會回收進程所佔用的內存。進程之間的內容相互隔離。

單進程瀏覽器時代

單進程瀏覽器是指瀏覽器的全部功能模塊都是運行在同一個進程裏,單進程瀏覽器不穩定、不流暢和不安全。

多進程瀏覽器時代

最新的Chrome瀏覽器包括:

1個瀏覽器(Browser)主進程、1個 GPU 進程、1個網絡(NetWork)進程、多個渲染進程和多個插件進程。

僅打開了1個頁面,爲何有4個進程

由於打開1個頁面至少須要1個網絡進程、1個瀏覽器進程、1個GPU進程以及1個渲染進程,共4個。

多進程模型提高了瀏覽器的穩定性、流暢性和安全性,可是資源佔用大,體系架構複雜。

什麼叫FP,指的是首次渲染,影響FP指標的是網絡加載速度。

如何保證頁面文件能被完整地送達瀏覽器呢?

從「數據包如何送達主機」「主機如何將數據包轉交給應用」和「數據是如何被完整地送達應用程序」這三個方面。

互聯網中的數據是經過數據包來傳輸的

TCP(Transmission Control Protocol,傳輸控制協議)是一種面向鏈接的、可靠的、基於字節流的傳輸層通訊協議。

一個完整的TCP鏈接的生命週期包括了「創建鏈接」「傳輸數據」和「斷開鏈接」三個階段。

互聯網中的數據是經過數據包來傳輸的,數據包在傳輸過程當中容易丟失或出錯。

IP負責把數據包送達目的主機。

UDP負責把數據包送達具體應用。

TCP保證了數據完整地傳輸,它的鏈接可分爲三個階段:創建鏈接、傳輸數據和斷開鏈接。

丟包通常是什麼緣由 

網絡問題,線路故障,路由錯誤等底層的問題都有可能致使丟包

你怎麼理解 HTTP 和 TCP 的關係?

HTTP是創建在TCP協議之上的,屬於應用層,TCP提供給HTTP可靠的鏈接,HTTP給應用提供更方便的使用接口。 

http協議是超文本協議,瀏覽器發出http請求,TCP會把請求向底層傳遞知道web服務器,而後web服務器返回http請求的response,瀏覽器渲染數據,下層爲上層提供服務。

HTTP協議和TCP協議都是TCP/IP協議簇的子集。HTTP協議屬於應用層,TCP協議屬於傳輸層,HTTP協議位於TCP協議的上層。

請求方要發送的數據包,在應用層加上HTTP頭之後會交給傳輸層的TCP協議處理,應答方接收到的數據包,在傳輸層拆掉TCP頭之後交給應用層的HTTP協議處理。

創建 TCP 鏈接後會順序收發數據,請求方和應答方都必須依據 HTTP 規範構建和解析HTTP報文。

爲啥打開第二次網站,速度比較快,第一次比較慢呢?

HTTP是一種容許瀏覽器向服務器獲取資源的協議,是Web的基礎,HTTP是瀏覽器使用最廣的協議。

爲啥打開第二次快呢?

由於第一次加載時,緩存了一些耗時的資源,瀏覽器緩存的有DNS緩存和頁面資源緩存。

瀏覽器的一個請求從發送到返回是一個怎樣的過程?

【綜合篇】Web前端性能優化原理問題

首先,用戶從瀏覽器進程裏輸入請求信息,而後,網絡進程發起url請求,服務器響應url請求後,瀏覽器進程就又要開始準備渲染進程了,渲染進程準備好後,向渲染進程提交頁面數據,渲染進程接收後,開始解析頁面和加載。

用戶發出URL請求到頁面開始解析的這個過程,就叫作導航。

渲染是怎麼變成頁面的呢?

HTML的內容是由標記和文本組成。CSS又稱爲層疊樣式表,是由選擇器和屬性組成。JavaScript(簡稱爲JS),使用它可使網頁的內容「動」起來。

構建DOM樹

瀏覽器沒法直接理解和使用HTML,因此須要將HTML轉換爲瀏覽器可以理解的結構——DOM樹。

重排和重繪都是渲染進程的主線程中進行的,減小這類操做能夠減小主線程的資源佔用,提升主線程繪製效率。

在編寫js時儘可能減小dom操做或合併dom操做,dom操做須要從新生成dom樹,若是影響佈局就須要從新生成佈局樹,再從新生成分層樹,再進行繪製。

變量提高

什麼是JavaScript中的聲明和賦值

JavaScript引擎把變量的聲明和函數的聲明提高到代碼開頭的「行爲」。變量被提高後,會給變量設置默認值,這個默認值就是undefined。

函數和變量在執行以前都提高到了代碼開頭。

代碼中出現相同的變量或者函數怎麼辦?會覆蓋。

爲何JavaScript代碼會溢出呢?

調用棧就是用來管理函數調用關係的一種數據結構。什麼是函數調用,函數調用就是運行一個函數。

什麼是JavaScript的調用棧

管理執行上下文的棧稱爲執行上下文棧,又稱調用棧。

棧溢出,是一種用來管理執行上下文的數據結構,符合後進先出的規則,調用棧是有大小的。

一篇文章帶你瞭解JavaScript中的函數表達式,遞歸,閉包,變量,this對象,模塊做用域

迴流,重繪。

引發迴流的因素,第一是dom節點增長或者是刪除,第二是元素的尺寸,邊距,填充,邊框,寬高,第三dom節點位置變化,第四dom節點display顯示與否,第五,頁面渲染初始化,瀏覽器窗口尺寸變化,向瀏覽器請求某些樣式信息。

瀏覽器性能優化

迴流比重繪的代價更高,迴流的花銷更render tree有多少節點須要從新構建有關係,使用隊列處理來優化,儘量減小重繪和迴流

原理,瀏覽器會維護一個隊列,把全部會引發的迴流,重繪的操做放入在這個隊列,等隊列中的數量或者到了必定的時間間隔,瀏覽器就會flush隊列,進行一個批處理。

時間線定義:在瀏覽器加載頁面開始的那一刻到頁面加載徹底結束的這個過程當中,按照順序發生的每一件事情的總流程,就是時間線。

時間線產生過程,頁面加載就產生一個document對象,js就起做用了,涉及到dom功能體就生效了。

查看文檔解析的三個狀態變化

// 只要 readyState 狀態發生變化就觸發,瀏覽器JS引擎實時監聽
console.log(document.readyState); // loading
document.onreadystatechange = function() {
    console.log(document.readyState); // interactive -> complete
}

監聽 DOMContentLoaded

// 監聽 DOMContentLoaded:在'interactive' :文檔解析完成以後觸發
document.addEventListener('DOMContentLoaded', function(){
    console.log('DOMContentLoaded');
}, false);

window.onload 與 DOMContentLoaded 區別

window.onload:在文檔加載完成以後觸發

DOMContentLoaded:在文檔解析完成以後觸發

渲染流程:HTML、CSS、JavaScript是如何變成頁面?

從 HTML 到 DOM、樣式計算、佈局、圖層、繪製、光柵化、合成和顯示

DOM樹:

渲染進程將 HTML 內容轉換爲可以讀懂的DOM 樹結構。

樣式計算:

渲染引擎將 CSS 樣式錶轉化爲瀏覽器能夠理解的styleSheets,計算出 DOM 節點的樣式。

佈局樹:

建立佈局樹,並計算元素的佈局信息。

分層:

對佈局樹進行分層,並生成分層樹。

繪製:

爲每一個圖層生成繪製列表,並將其提交到合成線程。

光柵化:

合成線程將圖層分紅圖塊,並在光柵化線程池中將圖塊轉換成位圖。

合成:

合成線程發送繪製圖塊命令DrawQuad給瀏覽器進程。

顯示:

瀏覽器進程根據 DrawQuad 消息生成頁面,並顯示到顯示器上。

服務器端處理瀏覽器端發送過來的HTTP請求

一、返回請求

(成功狀態碼200,沒找到頁面404,響應行、響應頭、響應體)

二、斷開鏈接

(服務器向客戶端返回請求數據,關閉TCP鏈接)

三、重定向

頁面二次打開會很快?

一、DNS緩存

二、頁面資源緩存

爲了解決UDP數據包傳輸過程容易丟失,引入TCP。

TCP:

把數據完整地送達應用程序,是一種面向鏈接的、可靠的、基於字節流的傳輸層通訊協議。

TCP兩個特色:

一、對於數據包丟失的狀況,TCP提供重傳機制;

二、TCP引入數據包排序機制,用來保證把亂序的數據包組合成一個完整的文件。

「FP」指從頁面加載到首次開始繪製的時長。影響FP指標:網絡加載速度。

HTTPWebSocket都是基於TCP/IP的,TCP/IP是優化Web頁面的加載速度的根基。

IP經過IP地址信息把數據包發送到指定的電腦,而UDP經過端口把數據包分發給正確程序。

JavaScript中的變量

分爲基本類型和引用類型

原始值,存在棧內存stack,而且不可改變值,引用值,值指針存在棧內存,值存在堆內存。

訪問堆內存中的數據,從棧內存中獲取該對象的地址引用,再從堆內存中獲取咱們想要的數據。

學習一下

【面試須要】掌握JavaScript中的this,call,apply的原理

什麼是做用域鏈,什麼是閉包呢?變量是經過做用域鏈來查找,什麼是詞法做用域,其做用域鏈是由詞法做用域決定的。

整個詞法做用域鏈的順序是: foo函數做用域—>bar函數做用域—>main函數做用域—>全局做用域。

全局執行上下文、函數執行上下文和eval執行上下文,經過函數的call方法來設置函數執行上下文的this指向。

===

數據是如何存儲的?咱們把這種在使用以前就須要確認其變量數據類型的稱爲靜態語言。咱們把在運行過程當中須要檢查數據類型的語言稱爲動態語言。

JavaScript是一種弱類型,動態的語言。

來吧!一文完全搞懂引用類型!

在JavaScript的執行過程當中, 主要有三種類型內存空間,分別是代碼空間、棧空間和堆空間。

常狀況下,棧空間都不會設置太大,主要用來存放一些原始類型的小數據。堆空間很大,能存放不少大的數據。

原始類型的賦值會完整複製變量值,而引用類型的賦值是複製引用地址。

垃圾數據是如何自動回收的?

使用後的數據不須要了,就稱爲垃圾數據,不刪除,就會愈來愈多,就須要進行回收,垃圾數據回收分爲手動回收和自動回收。

產生的垃圾數據是由垃圾回收器來釋放的,並不須要手動經過代碼來釋放。

調用棧中的數據是如何回收的

【面試Vue全家桶】vue前端交互模式-es7的語法結構?async/await

一篇文章帶你瞭解JavaScript中的面向 「對象」

瀏覽器工做原理

瀏覽器的組成

交互部分(UI)

網絡請求部分(Socket)

JavaScript引擎部分(解析執行JavaScript)

渲染引擎部分(渲染HTML、CSS等)

數據存儲部分(cookie、HTML5中的本地存儲LocalStorage、SessionStorage)

HTTP請求報文和響應報文格式

DNS 解析過程

解析過程

你天天都在使用的HTTP協議,究竟是什麼鬼?

TCP的 「三次握手」 和「四次揮手」,究竟是什麼鬼?

線程VS進程:一、線程是不能單獨存在的,它是由進程來啓動和管理的二、啓動一個程序的時候,操做系統會爲該程序建立一塊內存,用來存放代碼、運行中的數據和一個執行任務的主線程,咱們把這樣的一個運行環境叫進程。

使用Promise,告別回調函數

封裝異步代碼,讓處理流程變得線性

輸入數據和輸出結果

分析了產生回調地獄的緣由:多層嵌套的問題;每種任務的處理結果存在兩種可能性(成功或失敗),須要在每種任務執行結束後分別處理這兩種可能性。

瀏覽器的三大進化路線:

PWA,全稱是Progressive Web App

漸進式網頁應用,漸進式+Web應用,它是一套理念,漸進式加強Web的優點,並經過技術手段漸進式縮短和本地應用或者小程序的距離。

web應用缺點

Web應用缺乏離線使用能力,Web應用還缺乏了消息推送的能力,Web應用缺乏一級入口。

什麼是Service Worker

攔截請求和緩存資源

瀏覽器涉及不少概念,不只繁多並且瑣碎,包括網絡、渲染、安全,以及大前端相關的大量概念。

參考連接

http://taligarsiel.com/Projec..._browsers_we_will_talk_about

推薦閱讀  點擊標題可跳轉

【面試Vue全家桶】vue前端交互模式-es7的語法結構?async/await

【面試須要-Vue全家桶】一文帶你看透Vue前端路由

【面試須要】掌握JavaScript中的this,call,apply的原理

2019年的每一天日更只爲等待她的出現,好好過餘生,慶餘年 | 掘金年度徵文

進來就是一家人【達達前端技術社羣⑥】

以爲本文對你有幫助?請分享給更多人

關注「達達前端」加星標,提高前端技能

在博客平臺裏,將來的路還很長,也但願本身之後的文章你們能多多支持,多多批評指正,咱們一塊兒進步,一塊兒走花路。

很是感謝讀者能看到這裏,若是這個文章寫得還不錯,以爲「達達」我有點東西的話,以爲我可以堅持的學習,以爲此人能夠交朋友的話, 求點贊,求關注,求分享,對暖男我來講真的

很是有用!

感謝閱讀,原創不易,喜歡就點個[在看] or [轉發朋友圈],這是我寫做最大的動力。

意見反饋

若本號內容有作得不到位的地方(好比:涉及版權或其餘問題),請及時聯繫咱們進行整改便可,會在第一時間進行處理。

這是一個有質量,有態度的公衆號

點關注,有好運

好文章,我在看❤️