一個頁面從輸入URL到加載顯現完成,發生了什麼?

口試典範題——URL加載

一、觸及基礎知識點:

1. 盤算機收集

  1. 五層因特爾協定棧:

    • 應用層(dns、http):DNS剖析成IP並完成http請求發送;
    • 傳輸層(tcp、udp):三次握手四次揮手形式豎立tcp銜接;
    • 收集層(IP、ARP):IP尋址;
    • 數據鏈路層(PPP):將請求數據封裝成幀;
    • 物理層:應用物理介質傳輸比特流(傳輸的時刻經由歷程雙絞線、電磁波等)
    • OIS七層框架:多了兩層即,會話層(處置懲罰兩個通訊體系中交流信息的示意體式格局)和示意層(治理差別用戶和歷程之間的對話)。
  2. get和post的區分

    • get發生一個tcp數據包,post發生兩個
    • get請求時會把headers和data數據一同發送出去;
    • post請求時,瀏覽器先發送headers,服務器100繼承,瀏覽器再發送data。
  3. DNS查詢獲得IP

    1. 請求信息:起首檢察域名的當地DNS緩存,該緩存存儲盤算機近來檢索到的信息,假如盤算機不曉得答案,那末就須要實行一個DNS查詢來查找答案;
    2. 訊問遞歸式DNS服務器:

      • 假如信息不存儲在當地,盤算時機聯絡您的ISP(收集提供商)的遞歸DNS服務器;
      • 這些專用盤算時機為你實行一個DNS查詢事情;
      • 遞歸服務器有本身的緩存,所以這個查詢歷程平常在這裏完成,並將信息還回給用戶;
    3. 訊問根域名服務器

      • 假如遞歸服務器沒有答案,他們會查詢根域名服務器;
      • 根域名服務器是一種盤算機,它扮演着一種DNS的電話接線員的角色,他們不曉得答案,但能夠將我們的疑問指向曉得在那裡能夠找到答案的人。
    4. 訊問TLD域名服務器:

      • 根域名服務器將檢察請求的第一部份,按從右到左的遞次,從www.dyn.com中找到.com,並將請求指向.com對應的頂級域名服務器(TLD).com;
      • 每一個TLD,如(.com,.org,.us)都有本身的頂級域名服務器,
      • 這些服務器沒有我們須要的信息,但他們能夠直接將我們指導到有信息的服務器。
    5. 訊問威望的DNS服務器

      • TLD域名服務器會繼承搜檢請求的下一部份(dyn)www.dyn.com,並將查詢指向擔任此特定域名的服務器;
      • 這些威望的服務器將擔任相識關於特定域的一切信息,並將信息存儲在DNS紀錄。
    6. 找回紀錄:
      -遞歸服務器從威望服務器中檢索dyn.com的紀錄,並將紀錄存儲在當地緩存;

      • 假如其他任何人請求dyn.com的主機紀錄,遞歸服務器已有答案了,並不須要再次舉行查找;
      • 一切紀錄都有一個限期,一段時候后,遞歸服務器將須要請求一個新的紀錄副本,以確保信息不回過期。
    7. 吸收答案:

      • 有了答案,遞歸服務器將紀錄返回到盤算機,
      • 您的盤算機將紀錄存儲在緩存中,從紀錄中讀取IP地點,然後將這些信息傳遞給瀏覽器;
      • 然後瀏覽器就能夠依據IP地點和服務器舉行銜接豎立。
  4. TCPIP請求

    • http的實質就是TCPIP請求;
    • 須要閱歷3次握手豎立銜接,4次揮手斷開銜接;
    • TCP將http長報文劃分為短報文,經由歷程三次握手與服務器端豎立銜接,舉行牢靠傳輸。
    • 三次握手:

      • 客戶端:你是XXX服務端嗎?
      • 服務端: 我是XXX服務端,你是客戶端嗎?
      • 客服端: 是的,我是客戶端
      • 豎立銜接勝利后,接下來就能夠舉行正式的傳輸數據。
    • 四次揮手斷開銜接

      • 主動方:我已封閉了向你那裡的信息發送通道,只能被動接收信息了;
      • 被動方: 收到通道封閉的信息;
      • 被動方: 我如今也封閉了向你那裡發送信息的通道
      • 主動方: 左後收到信息,銜接斷開,以後兩邊沒法通訊
  5. TCP/IP的併發限定:

    • 瀏覽器對同一個域名下併發的TCP銜接是有限定的(2-10個不等)
    • 而且在http1.0中每每一個資本的下載就須要一個tcp/ip請求

2. 瀏覽器機制

(1)歷程和線程的觀點

  1. 歷程是CPU資本分派的最小單元,是能具有資本和自力運轉的最小單元;
  2. 線程是CPU調理的最小單元,線程是豎立在歷程的基礎上的一次順序運轉單元,一個歷程能夠具有多個線程;
  3. 淺顯的講:歷程是一個工場,工場有它自力的資本,工場之間互相自力->歷程之間互相自力,線程是工場中的工人,多個工人之間能夠合作完成使命,工場內有一個或多個工人,工人之間同享空間。

(2)多歷程的瀏覽器

瀏覽器是多歷程的,有一個主控歷程,以及每一個tab頁面都邑開一個歷程(某些情況下多個tab由於優化戰略會兼并)

  • 瀏覽器重要歷程:
  1. Browser歷程:瀏覽器的主歷程,擔任諧和、主控,只要一個,作用:

    • 擔任瀏覽器界面的顯現、與用戶交互(如行進、退卻等)
    • 擔任各個頁面的治理,建立和燒毀其他歷程;
    • 將Renderer歷程獲得的內存中的Bitmap繪製到用戶界面上
    • 收集資本的治理和下載等
  2. 第三方插件歷程: 每種範例的插件對應一個歷程,僅當該插件運用時才建立;
  3. GPU歷程: 最多一個,用於3D繪製等;
  4. 瀏覽器襯着歷程(Renderer歷程、瀏覽器內核、內部是多線程)

    • 默許沒打開一個tab頁面,就會啟動一個Renderer歷程;
    • 擔任頁面的襯着,劇本的實行,事宜的處置懲罰。
  • 瀏覽器多歷程的上風

    1. 防止單個page crash影響全部瀏覽器;
    2. 防止第三方插件crash影響全部瀏覽器
    3. 多歷程充分應用多核上風;
    4. 方便運用沙盒模子斷絕插件等歷程,進步瀏覽器穩定性

簡單點明白:假如瀏覽器是單歷程,那末某個tab頁或第三方插件崩潰了,就會致使全部瀏覽器崩潰,體驗度極差,不過多歷程內存斲喪會更大,有點用空間換時候。

瀏覽器內核(襯着歷程)

  • 瀏覽器襯着歷程內部是多線程,包含重要線程有:

1.GUI襯着線程:

  • (1)擔任瀏覽器界面的襯着,剖析HTML、CSS,構建DOM樹和RenderObject樹,規劃和繪製等;
  • (2) 當界面須要重繪(Repaint)或由於某種操縱激發迴流(reflow)時該線程會實行;
  • 注重:GUI襯着線程和JS引擎線程是互斥的,當JS引擎實行時GUI線程會被掛起,GUI更新會保存在一個行列中等JS引擎空閑時馬上實行。

2.JS引擎線程:

  • JS內核,擔任處置懲罰JavaScript劇本順序(V8引擎)
  • 擔任剖析JavaScript劇本,運轉代碼;
  • JS引擎一向守候着使命行列中的使命到來,然後加以處置懲罰,一個tab頁面(renderer歷程)中不管什麼時刻都只要一個JS線程在運轉JS順序;
  • 注重:由於GUI襯着線程和JS引擎線程是互斥的,所以假如JS順序運轉時候太長,如許會致使頁面襯着不連貫,致使頁面襯着加載壅塞;

3.事宜觸發線程:

  • 歸屬於瀏覽器,而不是JS引擎,用來掌握事宜輪迴;
  • 當JS引擎實行代碼塊如setTimeOut時(也能夠來自瀏覽器內核的其他線程,如鼠標單擊事宜、AJAX異步請求等),會將對應的使命添加到事宜線程中;
  • 當對應的事宜相符觸發前提被觸發時,該線程就會把事宜添加到JS的待處置懲罰行列的隊尾,守候JS引擎的處置懲罰;
  • 注重:由於JS的單線程的關聯所以這些待處置懲罰行列中的事宜都得列隊守候JS引擎處置懲罰(當JS引擎空閑時才會去實行)。

4.定時觸發器線程:

  • setTimeOut與setInterval地點的線程;
  • 瀏覽器的定時計數器並非由JavaScript引擎計數的,(由於JavaScript是單線程,假如處於壅塞狀況就會影響計時的正確)因而經由歷程零丁的線程來計時並觸發定時(計時終了后,添加到事宜行列,守候JS引擎空閑時實行)

5.異步http請求線程:

  • 在XMLHttpRequest在銜接后是經由歷程瀏覽器新開一個線程請求的
  • 將檢測到狀況變動時,假如設置有回調函數,異步線程就將發生狀況變動事宜,將這個回調在放到事宜行列中,再由JavaScript引擎實行。

一、 一個頁面從輸入URL到加載顯現完成,這個歷程發生了什麼?

  • 簡約版:

    • 瀏覽器依據請求的URL交給DNS域名剖析,找到實在的IP,向服務器提議請求;
    • 服務器交給背景處置懲罰完成后返回數據,瀏覽器吸收文件(HTML、CSS、JavaScript等);
    • 瀏覽器對加載到的資本(HTML、CSS、JavaScript等)舉行語法剖析,構建相應的內部數據構造(DOM樹、CSS樹、render樹等);
    • 載入剖析到的資本文件、襯着頁面、完成。
  • 細緻版:

    1. 起首瀏覽器開啟一個線程來處置懲罰這個請求,對URL分析判斷,假如是http協定就根據Web體式格局來處置懲罰;
    2. 其次瀏覽器會對URL舉行剖析,平常包含(協定頭、主機域名或IP地點、端口號、請求途徑、查詢參數、hash等),然後開啟收集線程發出一個完整到http請求;
    3. 固然平常我們輸入的URL是服務器域名,這時候就須要DNS經由歷程域名查詢獲得對應的IP;
    4. DNS起首會檢察瀏覽器DNS緩存,沒有就查詢盤算機當地DNS緩存,還沒有就訊問遞歸式DNS服務器(即收集提供商,平常這個服務器都邑有本身的緩存,所以IP查詢平常在這裏完成),假如沒有緩存,那就須要經由歷程根域名和TLD域名服務器指到對應的威望DNS服務器找回紀錄,並緩存到遞歸式服務器,然後遞歸服務器在將紀錄返回給當地。
    5. 有了IP地點,此時收集層便會經由歷程IP地點尋的對應服務器的物理地點
    6. 尋得服務器地點,客戶端在收集傳輸層便能夠和服務器經由歷程三次握手豎立tcpip銜接
    7. 銜接豎立后收集數據鏈路層將數據包裝成幀;
    8. 末了物理層應用物理介質舉行傳輸;
    9. 到了服務器,就會經由歷程相反的體式格局將數據一層一層的復原歸去;
    10. 請求到了背景服務器,平常會有一致的考證,如平安考證、跨域考證等,考證未經由歷程就直接返回相應的http報文
    11. 考證經由歷程后,就會進入背景代碼,此時順序收到請求,然後實行對應的操縱(如查詢數據庫等);
    12. 假如瀏覽器訪問過,且緩存上有對應的資本,便會與服務器末了修正時候對照,一致便返回304,通知瀏覽器可運用當地緩存;
    13. 前端瀏覽器吸收到相應勝利的報文後便最先下載網頁
    14. 下載完的網頁將被交給瀏覽器內核(襯着歷程)舉行處置懲罰:

      1. 依據頂部定義的DTD範例舉行對應的剖析體式格局;
      2. 襯着歷程內部是多線程的,網頁的剖析將會被交給內部的GUI襯着線程處置懲罰;
      3. 起首襯着線程中的HTML詮釋器,將HTML網頁和資本從字撙節詮釋轉換成字符流;
      4. 再經由歷程詞法分析器將字符流詮釋成詞語;
      5. 以後經由語法分析器依據詞語構建成節點;末了經由歷程這些節點組建一個DOM樹;
      6. 這個歷程當中,假如碰到的DOM節點是JavaScript代碼,就會挪用JavaScript引擎對JavaScript代碼舉行詮釋實行,此時由JavaScript引擎和GUI襯着線程的互斥,GUI襯着線程就會被掛起,襯着歷程住手;假如JavaScript代碼的運轉中對DOM樹舉行了修正,那末DOM的構建須要重新最先;
      7. 假如節點須要依靠其他資本,如(圖片,CSS等),便會挪用收集模塊的資本加載器來加載它們,但它們是異步的,不會壅塞當前DOM樹的構建;
      8. 假如碰到的是JavaScript資本URL(沒有標記異步),則須要住手當前DOM的構建,直到JavaScript的資本加載並被JavaScript引擎實行后才繼承構建DOM;
      9. 關於CSS,CSS詮釋器會將CSS文件詮釋成內部示意構造,天生CSS劃定規矩樹;
      10. 然後兼并CSS劃定規矩樹和DOM樹,天生render襯着樹;
      11. 末了對render樹舉行規劃和繪製,並將效果經由歷程IO線程傳遞給Browser掌握歷程舉行顯現。
    原文作者:keywords
    原文地址: https://segmentfault.com/a/1190000014872028
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞