前端日拱一卒D2——瀏覽器基礎

DerekZ95發表於2018-07-19

前言

餘為前端菜鳥,感姿勢水平匱乏,難觀前端之大局。遂決定循前端知識之脈絡,以興趣為引,輔以幾分堅持,望於己能解惑致知、於同道能助力一二,豈不美哉。

本系列程式碼及文件均在 此處

從輸入url到展示頁面經歷了什麼?

  • 接收輸入,開啟執行緒處理
  • 呼叫方法分析url
  • DNS解析獲取對應IP地址
    • DNS(domain name system),解析過程由host->本地域名解析器快取->本地域名伺服器->根域名伺服器->頂級域名伺服器->二級域名伺服器
    • DNS prefetch可以使瀏覽器主動去執行域名解析,域名解析在後臺執行,可能連結出現前已經解析完了,可以減少使用者點選連結時的延遲,比如
      // taobao主頁
      <link rel="dns-prefetch" href="//g.alicdn.com" />
      <link rel="dns-prefetch" href="//img.alicdn.com" />
      複製程式碼
  • 與伺服器建立連線,確認後傳送報文
  • 到達伺服器處理請求,後端應用處理請求
  • 伺服器返回響應報文,適用相應快取策略
  • 瀏覽器下載文件(考慮快取策略)
  • 解析html建立dom tree,下載css/js
  • 解析渲染dom,css根據規則結合dom進行內容佈局和繪製渲染,js根據dom api操作dom,執行事件繫結等至展示過程完成

瀏覽器組成

20170516149492235386286.png

  • 使用者介面
  • 瀏覽器引擎 (查詢和操作渲染引擎的介面)
  • 渲染引擎 (顯示頁面內容)
  • 網路模組
  • js引擎 (負責js解釋執行,如V8引擎)
  • UI後端 (繪製基本的瀏覽器視窗內控制元件)
  • 資料持久化儲存 (可通過瀏覽器引擎提供的介面呼叫)

渲染引擎

渲染引擎負責解析html和css,將css規則應用到html標籤上,並將html渲染為頁面上具體的dom內容

過程

  • 解析html生成dom tree
  • 將dom樹節點順序提取,結合css規則計算樣式資料,構建render tree
  • render tree佈局,根據每個渲染樹節點的佈局屬性將節點固定到頁面的對應位置
  • 繪製render tree,將元素的顯示屬性(背景、顏色、文字等)應用到節點,完成整個dom在頁面上的顯示

頁面元素位置變化將導致重排和重繪(即佈局和繪製階段重新渲染),位置不變但是顯示樣式變化則會導致重繪。重新渲染的代價比較大,所以應勁量避免重排,減少重繪。

Gecko與Webkit

gecko-webkit

兩者在渲染引擎部分很類似,但也有區別。前者的css解析是在html解析完生成內容sink之後進行的,結合構建的樹叫做frame tree,後者css解析和html解析可以認為是並行的。

解析詳解

  • html解析

    從html文字標籤經過詞法分析->parse成dom物件,每個標籤中的每個元素在解析後對應都有一個原始型別

    html-dom

    let element = document.getElementById('div')
    let type = Object.prototype.toString.call(element).slice(8, -1)
    console.log(type)
    // HTMLDivElement
    複製程式碼

    dom元素標籤是文字化的html標識,dom元素物件是一個帶有父子關係的樹形物件

  • css解析

    css檔案被解析成一個CSSStyleSheet物件,該物件記憶體在多個CSSStyleRule,每個rule包含有選擇器資訊和宣告物件(樣式資訊)

    css-rule

  • render tree

    生成render tree的時候會遍歷dom樹的節點,為每個節點找到css rule並根據優先順序(老生常談的權重判斷方式)將多條rule合併生成最終該節點的樣式資訊新增到render tree上。

資料持久化

HTTP檔案快取

cache-rule

  • cache-control/expire 前者是相對時間,後者是絕對時間

    // 前端設定
    <meta http-equiv="Cache-Control" content="max-age=7200" />
    <meta http-equiv="Expires" content="Mon, 16 Jul 2018 23:00:00 GMT" />
    複製程式碼
  • Etag和Last-Modified是返回頭中的資訊,當本地快取失效時會將這些資訊一起傳送至服務端進行對比

  • 服務端進行決策是否有更新,返回200或者304

localStorage

  • 單個域名下的localStorage大小限制在幾M
  • 瀏覽器多個標籤頁開啟同一域名頁面時localStorage是共享的
  • 簡單的幾個方法getItem, setItem, removeItem, clear

sessionStorage

  • 會話結束時(瀏覽器關閉)自動清空

Cookie

  • basics

    • 單個域名下的cookie大小限制在4K
    • 每個cookie都是<key>=<value>的形式
    • cookie型別為string
    • cookie有域(domain)和路徑(path)的概念,一般不可跨域訪問,路徑遵循子目錄可訪問的規則
    • secure保證cookie在傳輸過程中加密
    document.cookie='name=123;expires=date;path=path;domain=domain;secure'
    複製程式碼
  • session cookie和永續性cookie

    前者生命週期為瀏覽器會話期間,儲存在記憶體中,後者一般會設定過期時間,儲存在硬碟上,到期後才會被清空失效

  • HttpOnly屬性

    httponly

    設定了HttpOnly的cookie只能通過請求頭髮送到服務端進行讀寫操作,避免了被前端js修改,保證了服務端驗證cookie的安全性

  • 操作

    document.cookie = 'name=123' // add
    document.cookie = 'name=1234' // edit
    document.cookie = 'name=1234;expires=xxxx' // expires為過去時間,則delete
    複製程式碼

Web SQL和IndexedDB

在客戶端進行資料儲存,適用場景不是很多,也存在一些安全問題,且行且看

Application Cache

  • 通過manifest配置檔案實現本地快取的解決方案
  • 在第二次訪問時,訪問appCache,檢查manifest檔案是否更新,將更新的檔案重新拉取並更新cache
  • 離線儲存的容量限制為5M,快取檔案必須和manifest同源
  • 將被廢棄,被sevice worker替代(後續pwa瞭解一下)

CacheStorage

這部分涉及到service worker,不是三言兩語能說清,所以請轉到 這裡

雖發表於此,卻畢竟為一人之言,又是每日學有所得之筆記,內容未必詳實,看官老爺們還望海涵。

相關文章