繼上篇《 不隻是前端,後端、産品和測試也需要了解的浏覽器知識(一)》介紹了浏覽器的基本情況、發展曆史以及市場占有率。
本篇文章将介紹浏覽器基本原理。在掌握基本原理後,通過技術深入,在研發過程中不斷創新,推動産品性能、使用者體驗的提升,來實作業務的增長,創造可持續的價值。
一、 業務系統呈現給使用者的節點
當使用者通路我們的業務系統時,浏覽器和伺服器之間會進行一系列複雜的互動過程。浏覽器整體的導航流程如下:
以下是使用者從輸入 URL 到看到業務系統頁面的詳細步驟:
1. 輸入 URL 并解析
1.1. 使用者輸入 URL 并按下Enter鍵
使用者在浏覽器位址欄中輸入業務系統的 URL,例如 https://www.businesssystem.com,并按下Enter鍵。
1.2. 浏覽器解析 URL
浏覽器解析輸入的 URL,确定協定(如 HTTPS)、主機名(如 www.businesssystem.com)、端口号(如果有)、路徑、查詢參數等。
1.3. DNS 解析:
浏覽器需要将主機名轉換為 IP 位址。這個過程稱為 DNS 解析,通常包括以下步驟:
•浏覽器首先檢查本地 DNS 緩存,看看是否有對應的 IP 位址。
•如果本地緩存中沒有,浏覽器會向作業系統查詢。
•作業系統會檢查自己的緩存,并可能向本地的 DNS 伺服器送出請求。
•本地 DNS 伺服器可能會遞歸查詢其他 DNS 伺服器,直到找到對應的 IP 位址。
2. 建立連接配接、發送請求并接收響應
2.1. 建立 TCP 連接配接
一旦獲得了 IP 位址,浏覽器會通過 TCP/IP 協定與伺服器建立連接配接。對于 HTTPS,浏覽器還會進行 SSL/TLS 握手,以建立安全連接配接。流程如下
2.2. 發送 HTTP 請求
連接配接建立後,浏覽器會建構一個 HTTP 請求并發送給伺服器。請求包括請求行(例如 GET /index.html HTTP/1.1)、請求頭(如 User-Agent、Accept 等)以及可能的請求體(對于 POST 請求)。
2.3. 伺服器處理請求
伺服器接收到請求後,會根據請求的内容進行處理:
•伺服器解析請求,确定所需的資源(如 HTML 檔案、圖檔、資料等)。
•伺服器可能需要與後端資料庫或其他服務進行互動,以生成響應内容。
•伺服器建構 HTTP 響應,包括狀态行(如 HTTP/1.1 200 OK)、響應頭(如 Content-Type、Content-Length 等)和響應體(實際的頁面内容)。
2.4. 發送 HTTP 響應
伺服器将建構好的 HTTP 響應發送回浏覽器。
2.5. 浏覽器接收響應
浏覽器接收到伺服器的響應後,會根據響應頭的資訊處理響應體:
•如果響應是重定向(如 301 或 302),浏覽器會根據 Location 頭再次發起請求。
•如果響應包含壓縮内容(如 gzip),浏覽器會解壓縮。
•浏覽器會根據 Content-Type 頭确定如何處理響應體(如 HTML、CSS、JavaScript、圖檔等)。
發送請求和接受響應流程如下:
3. 解析和加載資源、渲染頁面
3.1. 解析 HTML
浏覽器開始解析 HTML 文檔,建構 DOM 樹。解析過程中,浏覽器會處理各種 HTML 标簽,并根據需要發起其他請求(如 CSS、JavaScript、圖檔等)。
3.2. 加載和執行資源
•CSS:浏覽器解析 CSS 檔案并建構 CSSOM 樹,與 DOM 樹結合形成渲染樹。
•JavaScript:浏覽器解析和執行 JavaScript 代碼,可能會修改 DOM 樹或 CSSOM 樹。
•圖檔和其他資源:浏覽器會異步加載這些資源,并在加載完成後進行渲染。
3.3. 渲染頁面
浏覽器根據渲染樹計算每個元素的布局(位置和大小),并将頁面繪制到螢幕上。這個過程可能會涉及多次重繪和重排(reflow/repaint),尤其是在 JavaScript 修改 DOM 或 CSS 的情況下。
頁面渲染流程如下:
4. 使用者互動
頁面加載完成後,使用者可以與頁面進行互動。浏覽器會響應使用者的操作(如點選、輸入等),并可能通過 JavaScript 動态更新頁面内容。
5. 小結
業務系統的呈現過程主要是:URL解析、與伺服器建立連接配接、伺服器處理請求并傳回響應、下載下傳和解析響應、頁面渲染。
二、 系統呈現過程中的技術點
1. DNS解析優化
1.1. 啟用 DNS 預解析
•DNS 預解析(DNS Prefetching):浏覽器在使用者點選連結之前,提前解析該連結的域名,進而減少等待時間。
<link rel="dns-prefetch" href="//example.com">
1.2. DNS緩存優化
合理設定 DNS 記錄的 TTL(Time-To-Live),使得 DNS 記錄可以在用戶端和中間緩存伺服器上儲存适當的時間,減少重複解析請求。
•對于不經常變化的記錄,可以設定較長的 TTL 值(如 24 小時)。
•對于經常變化的記錄,可以設定較短的 TTL 值(如幾分鐘到幾小時)。
1.3. 負載均衡和備援
•負載均衡:使用 DNS 負載均衡技術,将流量配置設定到多台伺服器上,防止單點故障。
•備援配置:配置多個權威 DNS 伺服器,確定在一個伺服器故障時,其他伺服器可以繼續提供解析服務。
1.4. 減少 DNS 查詢次數
•合并資源:盡量将資源放在同一個域名下,減少跨域名的 DNS 查詢次數。
•減少外部資源:盡量減少頁面中引用的外部資源(如第三方腳本和樣式),以減少額外的 DNS 查詢。
2. http協定優化
2.1. 請求方法優化
•使用合适的請求方法:確定使用正确的 HTTP 方法(GET、POST、PUT、DELETE 等)來表示操作的意圖。例如,使用 GET 方法擷取資料,使用 POST 方法送出資料。
•避免不必要的請求:合并請求,減少頁面中的請求次數。例如,CSS 和 JavaScript 檔案可以合并,圖像可以使用精靈圖(sprite)。
2.2. 狀态碼優化
•正确使用狀态碼:確定伺服器傳回正确的 HTTP 狀态碼。例如,200 表示成功,404 表示資源未找到,500 表示伺服器錯誤。
•重定向優化:減少重定向次數,避免不必要的 301 或 302 重定向。
2.3. 請求頭和響應頭優化
•壓縮傳輸内容:使用 Gzip 或 Brotli 壓縮傳輸内容,減少傳輸資料量。
•緩存控制:使用緩存控制頭(如 Cache-Control、Expires)來緩存靜态資源,減少重複請求。
•内容安全政策(CSP):設定内容安全政策頭,防止跨站腳本攻擊(XSS)。
•減少頭部大小:删除不必要的請求和響應頭,減少頭部大小,加快傳輸速度。
2.4. HTTP/2 和 HTTP/3 優化
a. 多路複用
•啟用 HTTP/2 或 HTTP/3:這些協定支援多路複用,可以在一個 TCP 連接配接中同時發送多個請求和響應,減少延遲。
•減少域名分片:HTTP/2 和 HTTP/3 中,多路複用使得域名分片(将資源分布到多個子域名)不再必要,反而可能降低性能。
b. 頭部壓縮
•使用 HPACK(HTTP/2)或 QPACK(HTTP/3)頭部壓縮:這些協定支援頭部壓縮,減少傳輸的資料量。
c. 減少延遲
•使用優先級和依賴:HTTP/2 和 HTTP/3 支援請求優先級和依賴,確定關鍵資源優先加載。
•啟用 QUIC 協定(HTTP/3):QUIC 協定基于 UDP,減少了連接配接建立的延遲,提供更快的傳輸速度。
4. CDN優化
•使用 CDN:将靜态資源分發到全球各地的節點,減少使用者通路的延遲。
•邊緣計算:利用 CDN 的邊緣計算能力,在靠近使用者的節點上處理部分邏輯,減少伺服器負載。
•靜态資源托管:将靜态資源(如圖像、CSS、JavaScript)托管在 CDN 上,減少網絡延遲,加快加載速度。
5. 頁面渲染時優化
5.1. HTML 優化
a. 減少 DOM 複雜度
•簡化 HTML 結構:減少嵌套層級,避免過度複雜的 DOM 結構。
•删除不必要的元素:移除無用的 HTML 标簽和注釋。
b. 延遲加載非關鍵内容
•使用 defer 和 async:對非關鍵 JavaScript 檔案使用 defer 或 async 屬性,避免阻塞頁面渲染。
•懶加載圖像和視訊:使用 loading="lazy" 屬性或 JavaScript 實作懶加載,延遲加載視口外的圖像和視訊。
5.2. CSS 優化
a. 減少 CSS 檔案大小
•壓縮 CSS 檔案:使用工具(如 CSSNano、CleanCSS)壓縮 CSS 檔案,減少檔案大小。
•移除未使用的 CSS:使用工具(如 PurgeCSS)移除未使用的 CSS 規則。
b. 優化 CSS 加載
•使用外部樣式表:将 CSS 放在外部樣式表中,而不是内聯樣式,便于緩存和管理。
•放置 CSS 在 <head> 中: 確定 CSS 檔案在 <head> 中加載,以便盡快渲染頁面。
•避免 CSS 阻塞渲染:将關鍵 CSS 内聯到 HTML 中,非關鍵 CSS 異步加載。
5.3. JavaScript 優化
a. 減少 JavaScript 檔案大小
•壓縮和混淆:使用工具(如 UglifyJS、Terser)壓縮和混淆 JavaScript 檔案,減少檔案大小。
•移除未使用的代碼:使用工具(如 Webpack 的 Tree Shaking)移除未使用的代碼。
b. 優化 JavaScript 加載
•分離關鍵和非關鍵腳本:将關鍵腳本放在 <head> 中,非關鍵腳本放在頁面底部或使用 defer 和 async。
•代碼分割:使用 Webpack 等工具進行代碼分割,按需加載子產品。
c. 優化 JavaScript 執行
•減少重排和重繪:避免頻繁操作 DOM,使用文檔片段(Document Fragment)或虛拟 DOM 技術。
•使用節流和防抖:對高頻率事件(如滾動、輸入)使用節流(throttle)和防抖(debounce)技術,減少不必要的函數調用。
•減少 JavaScript 阻塞:避免長時間運作的 JavaScript 任務,使用 Web Workers 将複雜計算移到背景線程。
5.4. 圖像優化
a. 減少圖像檔案大小
•壓縮圖像:使用工具(如 ImageOptim、TinyPNG)壓縮圖像檔案,減少檔案大小。
•選擇合适的格式:根據圖像内容選擇合适的格式(如 JPEG、PNG、WebP),WebP 通常比 JPEG 和 PNG 更小。
b. 優化圖像加載
•使用響應式圖像:使用 srcset 和 sizes 屬性提供不同分辨率的圖像,适應不同裝置。
•懶加載圖像:使用 loading="lazy" 屬性或 JavaScript 實作圖像懶加載。
5.5. 其他優化政策
a. 優化字型加載
•使用字型顯示政策:使用 font-display 屬性控制字型加載行為,避免字型閃爍(FOIT)和不可見文本(FOUT)。
•減少字型檔案大小:使用子集化工具(如 Google Fonts 的子集化功能)隻加載需要的字元集,減少字型檔案大小。
6. 小結
在實際業務中我們需要針對頁面呈現過程中的每一個節點,去制定不同的優化政策。
三、總結
本文主要介紹了業務系統呈現給使用者所經曆的各個節點,以及作為技術人能在各節點中進行優化的點, 通過這些技術優化點,在研發過程中不斷創新,推動産品性能、使用者體驗的提升,來實作業務的增長,創造可持續的價值。