前言
餘為前端菜鳥,感姿勢水平匱乏,難觀前端之大局。遂決定循前端知識之脈絡,以興趣為引,輔以幾分堅持,望於己能解惑致知、於同道能助力一二,豈不美哉。
本系列程式碼及文件均在 此處
從輸入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,執行事件繫結等至展示過程完成
瀏覽器組成
- 使用者介面
- 瀏覽器引擎 (查詢和操作渲染引擎的介面)
- 渲染引擎 (顯示頁面內容)
- 網路模組
- js引擎 (負責js解釋執行,如V8引擎)
- UI後端 (繪製基本的瀏覽器視窗內控制元件)
- 資料持久化儲存 (可通過瀏覽器引擎提供的介面呼叫)
渲染引擎
渲染引擎負責解析html和css,將css規則應用到html標籤上,並將html渲染為頁面上具體的dom內容
過程
- 解析html生成dom tree
- 將dom樹節點順序提取,結合css規則計算樣式資料,構建render tree
- render tree佈局,根據每個渲染樹節點的佈局屬性將節點固定到頁面的對應位置
- 繪製render tree,將元素的顯示屬性(背景、顏色、文字等)應用到節點,完成整個dom在頁面上的顯示
頁面元素位置變化將導致重排和重繪(即佈局和繪製階段重新渲染),位置不變但是顯示樣式變化則會導致重繪。重新渲染的代價比較大,所以應勁量避免重排,減少重繪。
Gecko與Webkit
兩者在渲染引擎部分很類似,但也有區別。前者的css解析是在html解析完生成內容sink之後進行的,結合構建的樹叫做frame tree,後者css解析和html解析可以認為是並行的。
解析詳解
-
html解析
從html文字標籤經過詞法分析->parse成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包含有選擇器資訊和宣告物件(樣式資訊)
-
render tree
生成render tree的時候會遍歷dom樹的節點,為每個節點找到css rule並根據優先順序(老生常談的權重判斷方式)將多條rule合併生成最終該節點的樣式資訊新增到render tree上。
資料持久化
HTTP檔案快取
-
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的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,不是三言兩語能說清,所以請轉到 這裡
雖發表於此,卻畢竟為一人之言,又是每日學有所得之筆記,內容未必詳實,看官老爺們還望海涵。