本篇內(nèi)容主要講解“瀏覽器的工作原理是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“瀏覽器的工作原理是什么”吧!
在永定等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都做網(wǎng)站、網(wǎng)站設(shè)計 網(wǎng)站設(shè)計制作按需定制,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計,成都全網(wǎng)營銷,外貿(mào)營銷網(wǎng)站建設(shè),永定網(wǎng)站建設(shè)費用合理。
瀏覽器架構(gòu)
在講瀏覽器架構(gòu)之前,先理解兩個概念,進程和線程。
進程(process)是程序的一次執(zhí)行過程,是一個動態(tài)概念,是程序在執(zhí)行過程中分配和管理資源的基本單位,線程(thread)是CPU調(diào)度和分派的基本單位,它可與同屬一個進程的其他的線程共享進程所擁有的全部資源。
簡單的說呢,進程可以理解成正在執(zhí)行的應(yīng)用程序,而線程呢,可以理解成我們應(yīng)用程序中的代碼的執(zhí)行器。而他們的關(guān)系可想而知,線程是跑在進程里面的,一個進程里面可能有一個或者多個線程,而一個線程,只能隸屬于一個進程。
大家都知道,瀏覽器屬于一個應(yīng)用程序,而應(yīng)用程序的一次執(zhí)行,可以理解為計算機啟動了一個進程,進程啟動后,CPU會給該進程分配相應(yīng)的內(nèi)存空間,當我們的進程得到了內(nèi)存之后,就可以使用線程進行資源調(diào)度,進而完成我們應(yīng)用程序的功能。
而在應(yīng)用程序中,為了滿足功能的需要,啟動的進程會創(chuàng)建另外的新的進程來處理其他任務(wù),這些創(chuàng)建出來的新的進程擁有全新的獨立的內(nèi)存空間,不能與原來的進程內(nèi)向內(nèi)存,如果這些進程之間需要通信,可以通過IPC機制(Inter Process Communication)來進行。
很多應(yīng)用程序都會采取這種多進程的方式來工作,因為進程和進程之間是互相獨立的它們互不影響,也就是說,當其中一個進程掛掉了之后,不會影響到其他進程的執(zhí)行,只需要重啟掛掉的進程就可以恢復運行。
瀏覽器的多進程架構(gòu)
假如我們?nèi)ラ_發(fā)一個瀏覽器,它的架構(gòu)可以是一個單進程多線程的應(yīng)用程序,也可以是一個使用IPC通信的多進程應(yīng)用程序。
不同的瀏覽器使用不同的架構(gòu),下面主要以Chrome為例,介紹瀏覽器的多進程架構(gòu)。
在Chrome中,主要的進程有4個:
瀏覽器進程 (Browser Process):負責瀏覽器的TAB的前進、后退、地址欄、書簽欄的工作和處理瀏覽器的一些不可見的底層操作,比如網(wǎng)絡(luò)請求和文件訪問。
渲染進程 (Renderer Process):負責一個Tab內(nèi)的顯示相關(guān)的工作,也稱渲染引擎。
插件進程 (Plugin Process):負責控制網(wǎng)頁使用到的插件
GPU進程 (GPU Process):負責處理整個應(yīng)用程序的GPU任務(wù)
這4個進程之間的關(guān)系是什么呢?
首先,當我們是要瀏覽一個網(wǎng)頁,我們會在瀏覽器的地址欄里輸入URL,這個時候Browser Process會向這個URL發(fā)送請求,獲取這個URL的HTML內(nèi)容,然后將HTML交給Renderer Process,Renderer Process解析HTML內(nèi)容,解析遇到需要請求網(wǎng)絡(luò)的資源又返回來交給Browser Process進行加載,同時通知Browser Process,需要Plugin Process加載插件資源,執(zhí)行插件代碼。解析完成后,Renderer Process計算得到圖像幀,并將這些圖像幀交給GPU Process,GPU Process將其轉(zhuǎn)化為圖像顯示屏幕。
多進程架構(gòu)的好處
Chrome為什么要使用多進程架構(gòu)呢?
第一,更高的容錯性。當今WEB應(yīng)用中,HTML,JavaScript和CSS日益復雜,這些跑在渲染引擎的代碼,頻繁的出現(xiàn)BUG,而有些BUG會直接導致渲染引擎崩潰,多進程架構(gòu)使得每一個渲染引擎運行在各自的進程中,相互之間不受影響,也就是說,當其中一個頁面崩潰掛掉之后,其他頁面還可以正常的運行不收影響。
第二,更高的安全性和沙盒性(sanboxing)。渲染引擎會經(jīng)常性的在網(wǎng)絡(luò)上遇到不可信、甚至是惡意的代碼,它們會利用這些漏洞在你的電腦上安裝惡意的軟件,針對這一問題,瀏覽器對不同進程限制了不同的權(quán)限,并為其提供沙盒運行環(huán)境,使其更安全更可靠
第三,更高的響應(yīng)速度。在單進程的架構(gòu)中,各個任務(wù)相互競爭搶奪CPU資源,使得瀏覽器響應(yīng)速度變慢,而多進程架構(gòu)正好規(guī)避了這一缺點。
多進程架構(gòu)優(yōu)化
之前的我們說到,Renderer Process的作用是負責一個Tab內(nèi)的顯示相關(guān)的工作,這就意味著,一個Tab,就會有一個Renderer Process,這些進程之間的內(nèi)存無法進行共享,而不同進程的內(nèi)存常常需要包含相同的內(nèi)容。
瀏覽器的進程模式
為了節(jié)省內(nèi)存,Chrome提供了四種進程模式(Process Models),不同的進程模式會對 tab 進程做不同的處理。
Process-per-site-instance (default) - 同一個 site-instance 使用一個進程
Process-per-site - 同一個 site 使用一個進程
Process-per-tab - 每個 tab 使用一個進程
Single process - 所有 tab 共用一個進程
這里需要給出 site 和 site-instance 的定義
site 指的是相同的 registered domain name(如: google.com ,bbc.co.uk)和scheme (如:https://)。比如a.baidu.com和b.baidu.com就可以理解為同一個 site(注意這里要和 Same-origin policy 區(qū)分開來,同源策略還涉及到子域名和端口)。
site-instance 指的是一組 connected pages from the same site,這里 connected 的定義是 can obtain references to each other in script code 怎么理解這段話呢。滿足下面兩中情況并且打開的新頁面和舊頁面屬于上面定義的同一個 site,就屬于同一個 site-instance
用戶通過這種方式點擊打開的新頁面
JS代碼打開的新頁面(比如 window.open)
理解了概念之后,下面解釋四個進程模式
首先是Single process,顧名思義,單進程模式,所有tab都會使用同一個進程。接下來是Process-per-tab ,也是顧名思義,每打開一個tab,會新建一個進程。而對于Process-per-site,當你打開 a.baidu.com 頁面,在打開 b.baidu.com 的頁面,這兩個頁面的tab使用的是共一個進程,因為這兩個頁面的site相同,而如此一來,如果其中一個tab崩潰了,而另一個tab也會崩潰。
Process-per-site-instance 是最重要的,因為這個是 Chrome 默認使用的模式,也就是幾乎所有的用戶都在用的模式。當你打開一個 tab 訪問 a.baidu.com ,然后再打開一個 tab 訪問 b.baidu.com,這兩個 tab 會使用兩個進程。而如果你在 a.baidu.com 中,通過JS代碼打開了 b.baidu.com 頁面,這兩個 tab 會使用同一個進程。
默認模式選擇
那么為什么瀏覽器使用Process-per-site-instance作為默認的進程模式呢?
Process-per-site-instance兼容了性能與易用性,是一個比較中庸通用的模式。
相較于 Process-per-tab,能夠少開很多進程,就意味著更少的內(nèi)存占用
相較于 Process-per-site,能夠更好的隔離相同域名下毫無關(guān)聯(lián)的 tab,更加安全
導航過程都發(fā)生了什么
前面我們講了瀏覽器的多進程架構(gòu),講了多進程架構(gòu)的各種好處,和Chrome是怎么優(yōu)化多進程架構(gòu)的,下面從用戶瀏覽網(wǎng)頁這一簡單的場景,來深入了解進程和線程是如何呈現(xiàn)我們的網(wǎng)站頁面的。
網(wǎng)頁加載過程
之前我們我們提到,tab以外的大部分工作由瀏覽器進程Browser Process負責,針對工作的不同,Browser Process 劃分出不同的工作線程:
UI thread:控制瀏覽器上的按鈕及輸入框;
network thread:處理網(wǎng)絡(luò)請求,從網(wǎng)上獲取數(shù)據(jù);
storage thread: 控制文件等的訪問;
第一步:處理輸入
當我們在瀏覽器的地址欄輸入內(nèi)容按下回車時,UI thread會判斷輸入的內(nèi)容是搜索關(guān)鍵詞(search query)還是URL,如果是搜索關(guān)鍵詞,跳轉(zhuǎn)至默認搜索引擎對應(yīng)都搜索URL,如果輸入的內(nèi)容是URL,則開始請求URL。
第二步:開始導航
回車按下后,UI thread將關(guān)鍵詞搜索對應(yīng)的URL或輸入的URL交給網(wǎng)絡(luò)線程Network thread,此時UI線程使Tab前的圖標展示為加載中狀態(tài),然后網(wǎng)絡(luò)進程進行一系列諸如DNS尋址,建立TLS連接等操作進行資源請求,如果收到服務(wù)器的301重定向響應(yīng),它就會告知UI線程進行重定向然后它會再次發(fā)起一個新的網(wǎng)絡(luò)請求。
第三步:讀取響應(yīng)
network thread接收到服務(wù)器的響應(yīng)后,開始解析HTTP響應(yīng)報文,然后根據(jù)響應(yīng)頭中的Content-Type字段來確定響應(yīng)主體的媒體類型(MIME Type),如果媒體類型是一個HTML文件,則將響應(yīng)數(shù)據(jù)交給渲染進程(renderer process)來進行下一步的工作,如果是 zip 文件或者其它文件,會把相關(guān)數(shù)據(jù)傳輸給下載管理器。
與此同時,瀏覽器會進行 Safe Browsing 安全檢查,如果域名或者請求內(nèi)容匹配到已知的惡意站點,network thread 會展示一個警告頁。除此之外,網(wǎng)絡(luò)線程還會做 CORB(Cross Origin Read Blocking)檢查來確定那些敏感的跨站數(shù)據(jù)不會被發(fā)送至渲染進程。
第四步:查找渲染進程
各種檢查完畢以后,network thread 確信瀏覽器可以導航到請求網(wǎng)頁,network thread 會通知 UI thread 數(shù)據(jù)已經(jīng)準備好,UI thread 會查找到一個 renderer process 進行網(wǎng)頁的渲染。
瀏覽器為了對查找渲染進程這一步驟進行優(yōu)化,考慮到網(wǎng)絡(luò)請求獲取響應(yīng)需要時間,所以在第二步開始,瀏覽器已經(jīng)預(yù)先查找和啟動了一個渲染進程,如果中間步驟一切順利,當 network thread 接收到數(shù)據(jù)時,渲染進程已經(jīng)準備好了,但是如果遇到重定向,這個準備好的渲染進程也許就不可用了,這個時候會重新啟動一個渲染進程。
第五步:提交導航
到了這一步,數(shù)據(jù)和渲染進程都準備好了,Browser Process 會向 Renderer Process 發(fā)送IPC消息來確認導航,此時,瀏覽器進程將準備好的數(shù)據(jù)發(fā)送給渲染進程,渲染進程接收到數(shù)據(jù)之后,又發(fā)送IPC消息給瀏覽器進程,告訴瀏覽器進程導航已經(jīng)提交了,頁面開始加載。
這個時候?qū)Ш綑跁拢踩甘痉拢ǖ刂非懊娴男℃i),訪問歷史列表(history tab)更新,即可以通過前進后退來切換該頁面。
第六步:初始化加載完成
當導航提交完成后,渲染進程開始加載資源及渲染頁面(詳細內(nèi)容下文介紹),當頁面渲染完成后(頁面及內(nèi)部的iframe都觸發(fā)了onload事件),會向瀏覽器進程發(fā)送IPC消息,告知瀏覽器進程,這個時候UI thread會停止展示tab中的加載中圖標。
網(wǎng)頁渲染原理
導航過程完成之后,瀏覽器進程把數(shù)據(jù)交給了渲染進程,渲染進程負責tab內(nèi)的所有事情,核心目的就是將HTML/CSS/JS代碼,轉(zhuǎn)化為用戶可進行交互的web頁面。那么渲染進程是如何工作的呢?
渲染進程中,包含線程分別是:
一個主線程(main thread)
多個工作線程(work thread)
一個合成器線程(compositor thread)
多個光柵化線程(raster thread)
不同的線程,有著不同的工作職責。
構(gòu)建DOM
當渲染進程接受到導航的確認信息后,開始接受來自瀏覽器進程的數(shù)據(jù),這個時候,主線程會解析數(shù)據(jù)轉(zhuǎn)化為DOM(Document Object Model)對象。
DOM為WEB開發(fā)人員通過JavaScript與網(wǎng)頁進行交互的數(shù)據(jù)結(jié)構(gòu)及API。
資源子加載
在構(gòu)建DOM的過程中,會解析到圖片、CSS、JavaScript腳本等資源,這些資源是需要從網(wǎng)絡(luò)或者緩存中獲取的,主線程在構(gòu)建DOM過程中如果遇到了這些資源,逐一發(fā)起請求去獲取,而為了提升效率,瀏覽器也會運行預(yù)加載掃描(preload scanner)程序,如果如果HTML中存在img、link等標簽,預(yù)加載掃描程序會把這些請求傳遞給Browser Process的network thread進行資源下載。
JavaScript的下載與執(zhí)行
構(gòu)建DOM過程中,如果遇到