前端技術演進(一):Web前端技術基礎

這個來自以前作的培訓,刪減了一些業務相關的,參考了不少資料( 參考資料列表),謝謝前輩們,麼麼噠 😘

每一個開發者或多或少都接觸過前端,但如今的前端變化有點快,這裏是截至2018年的前端,暫且叫:現代前端技術演進。javascript

互聯網信息呈現的方式主要依靠終端設備屏幕,現在,終端設備的種類愈來愈多,智能化愈來愈高,交互也愈來愈複雜。css

image.png | center | 827x411.29466666666667

蘋果官網的演進

1992年:html

image.png | left | 469x240

1996年:前端

image.png | left | 683x427

1998年:java

image.png | left | 683x427

1999年:git

image.png | left | 683x427

2000年:github

image.png | left | 550x436

2001年:web

image.png | left | 683x427

2003年:面試

image.png | left | 683x427

2005年:chrome

image.png | left | 480x407

2006年:

image.png | left | 827x516.875

2007年:

image.png | left | 827x516.875

2008年:

image.png | left | 827x516.875

2010年:

image.png | left | 827x516.875

2011年:

image.png | left | 827x516.875

喬布斯去世:

image.png | left | 827x516.875

2012年:

image.png | left | 827x516.875

2013年:

image.png | left | 827x516.875

2014年:

image.png | left | 827x516.875

2015年:

image.png | left | 827x516.875

2016年:

image.png | left | 827x385.4697845507094

2017年:

image.png | left | 827x462.73704520396916

2018年:

image.png | center | 827x562

蘋果的發展是IT行業的縮影,包含了工業設計、產品設計、硬件技術、用戶體驗、UI設計、前端技術等方方面面。

僅從前端來看,經過蘋果官網的演進,能夠看到,隨着互聯網和移動互聯網的快速發展,前端技術也發生了巨大的變化。

前端應用開發模式演變

一、靜態黃頁
二、服務器組裝數據的動態網頁
三、後端爲主的 MVC
四、先後端分離
五、前端 MV* 框架
六、前端 VIrtual DOM,MNV*,先後端同構

image.png | center | 827x308.0575

全部變化,都是圍繞提高前端開發的效率和質量。

瀏覽器基礎

前端大部分時間都是在和瀏覽器打交道,因此咱們先從瀏覽器提及。

從一個常見的前端面試題提及:

從咱們打開瀏覽器輸入一個網址到頁面展現網頁內容這段時間內,瀏覽器和服務端都發生了什麼事情?

這個問題也有一種發散性更強的說法是:從咱們打開瀏覽器輸入一個網址到頁面展現網頁內容這段時間內,都發生了什麼事情?好比下面是百度FEX(Web 前端研發部)的面試題:

image.png | center | 827x435

https://github.com/fex-team/interview-questions

越詳細越好,有人可能從移動光電鼠標提及:發光二極管發出的光線照亮鼠標底部表面,而後將鼠標底部表面反射回的一部分光線,通過一組光學透鏡,傳輸到一個光感應器件內成像,當鼠標移動時,其移動軌跡便會被記錄爲一組高速拍攝的連貫圖像,經過DSP分析圖像,就能夠判斷鼠標的移動方向和移動距離,從而完成光標的定位。。。從鼠標鍵盤屏幕計算機、輸入輸出、操做系統、編譯原理啥的提及,能夠說一天,因此這裏只關注瀏覽器和服務端主要的過程。

一個簡化的過程是這樣的:

  1. 在接收到用戶輸入的網址後,瀏覽器會開啓一個線程來處理這個請求,對用戶輸入的URL地址進行分析判斷,若是是HTTP協議就按照HTTP方式來處理。
  2. 調用瀏覽器引擎中的對應方法,好比WebView中的loadUrl方法,分析並加載這個URL地址。
  3. 經過DNS解析獲取該網站地址對應的IP地址,查詢完成後連同瀏覽器的Cookie、userAgent等信息向網站目的IP發出請求。
  4. 進行HTTP協議會話,瀏覽器客戶端向Web服務器發送報文。
  5. 進入網站後臺上的Web服務器處理請求,如Apache、Tomcat、Nginx、Node.js 等服務器。
  6. 進入部署好的後端應用,如PHP、Java、 JavaScript、 Python 等後端程序,找到對應的請求處理邏輯,這期間可能會讀取服務器緩存或查詢數據庫等。
  7. 服務器處理請求並返回響應報文,此時若是瀏覽器訪問過該頁面,緩存上有對應資源,會與服務器最後修改記錄對比,一致則返回304,不然返回200和對應的內容。
  8. 瀏覽器開始下載HTML文檔(響應報頭狀態碼爲200時)或者從本地緩存讀取文件內容(瀏覽器緩存有效或響應報頭狀態碼爲304時)。
  9. 瀏覽器根據下載接收到的HTML文件解析結構創建DOM文檔樹,並根據HTML中的標記請求下載指定的MIME類型文件(如CSS、JavaScript 腳本等),同時設置緩存等內容。
  10. 頁面開始解析渲染DOM、CSS根據規則解析並結合DOM文檔樹進行網頁內容佈局和繪製渲染,JavaScript 根據DOM API操做DOM,並讀取瀏覽器緩存、執行事件綁定等,頁面整個展現過程完成。

下圖是在服務端的一些展開:

image.png | center | 827x551.3333333333333

做爲前端,重點會關注這個過程當中地址欄輸入、網絡請求、瀏覽器文檔解析、渲染引擎、Javascript執行引擎,客戶端存儲等部分。因此咱們先了解一下瀏覽器:

瀏覽器一般由以下七個部分組成:

image.png | center | 500x339

  1. 用戶界面(User Interface): 包括地址欄、前進/後退按鈕、書籤菜單等。除了瀏覽器主窗口顯示請求的頁面外,其餘顯示的各個部分都屬於用戶界面。
  2. 瀏覽器引擎(Browser engine): 在用戶界面和呈現引擎之間傳送指令,或者在客戶端本地緩存中讀寫數據等,是瀏覽器中各個部分之間相互通訊的核心。
  3. 呈現(渲染)引擎(Rendering engine): 負責顯示請求的內容,並將內容排版到瀏覽器中顯示成有樣式的界面。若是請求的內容是 HTML,它就負責解析 HTML 和 CSS 內容,並將解析後的內容顯示在屏幕上,也叫排版引擎,常說的瀏覽器內核通常也主要是指呈現引擎。
  4. 網絡功能模塊(Networking): 用於網絡調用,好比 HTTP 請求。它的接口與平臺無關,併爲全部平臺提供底層實現。
  5. 用戶界面後端(UI Backend): 用於繪製基本的窗口小部件,好比組合框和窗口。它公開了與平臺無關的通用接口,而在底層使用操做系統的用戶界面方法。
  6. JavaScript 解釋器(Javascript Interpreter): 用於解析和執行 JavaScript 代碼。
  7. 數據存儲(Data Persistence): 持久層。瀏覽器須要在硬盤上保存各類數據,例如 Cookie、localStorage。新的 HTML 規範 (HTML5) 定義了「網絡數據庫」,這是一個完整(可是輕便)的瀏覽器內數據庫。

瀏覽器呈現引擎簡介

呈現引擎的做用嘛...固然就是「呈現」了,也就是在瀏覽器的屏幕上顯示請求的內容。

目前,主流的瀏覽器內核有4類:

  • Trident:IE、360、搜狗等;
  • Gecko:Netscape、Firefox等;
  • Presto:Opera(新的 Opera 使用了 Blink 內核,是 Webkit 的一個分支,添加了一些優化特性);
  • Webkit:Safari、Chrome

呈現引擎一開始會從網絡層獲取請求文檔的內容(內容的大小通常限制在 8000 個塊之內)。

而後進行以下所示的基本流程:

image.png | center | 600x66

  1. 解析HTML構建DOM樹時呈現引擎會先將HTML元素標籤解析成由多個DOM元素對象節點組成的且具備節點父子關係的DOM樹結構(DOM tree)
  2. 而後根據DOM樹結構的每一個節點順序提取計算使用的CSS規則,並從新計算DOM樹結構的樣式數據,生成一個帶樣式描述的DOM渲染樹(render tree)對象。
  3. DOM渲染樹生成結束後,進入渲染樹的佈局(Layout)階段,即根據每一個渲染樹節點在頁面中的大小和位置,將節點固定到頁面的對應位置上,這個階段主要是元素的佈局屬性(例如position、float、margin 等屬性)生效,即在瀏覽器中繪製頁面上元素節點的位置。
  4. 接下來就是繪製階段,將渲染樹節點的背景、顏色、文本等樣式信息應用到每一個節點上,這個階段主要是元素的內部顯示樣式(例如color、background. text-shadow 等屬性)生效,最終完成整個DOM在頁面上的繪製(Painting)顯示。

這是一個漸進的過程。爲達到更好的用戶體驗,呈現引擎會力求儘快將內容顯示在屏幕上。它沒必要等到整個 HTML 文檔解析完畢以後,就會開始構建呈現樹和設置佈局。在不斷接收和處理來自網絡的其他內容的同時,呈現引擎會將部份內容解析並顯示出來。

image.png | center | 624x289

Webkit主流程

image.png | center | 624x290

Gecko主流程

兩種呈現引擎工做流程的主要區別在於解析HTML或CSS文檔生成呈現樹的過程:

  • Webkit 內核中的HTML和CSS解析能夠認爲是並行的;
  • Gecko 則是先解析HTML,生成內容槽 (Content Sink)後再開始解析CSS。

這兩種呈現引擎工做過程當中使用的描述術語也不同:

  • Webkit 內核解析後的渲染對象被稱爲呈現樹(Render Tree),由「呈現對象」組成;
  • Gecko 內核解析後的渲染對象則稱爲Frame樹(Frame Tree),每一個元素都是一個框架。

對於元素的放置:

  • WebKit 使用的術語是「佈局(Layout)」;
  • Gecko 使用的術語是「重排(Reflow)」。

可是它們主要的流程是類似的,都通過HTML DOM解析、CSS樣式解析、呈現樹生成和呈現樹繪製顯示階段。通常呈現引擎的解析過程當中都包含了HTML解析和CSS解析階段,這也是呈現引擎解析流程中最重要的兩個部分。

什麼是解析

解析文檔是指將文檔轉化成爲有意義的結構,也就是可以讓代碼理解和使用的結構。解析獲得的結果一般是表明了文檔結構的節點樹,它稱做解析樹或者語法樹。

好比:2 + 3 - 1 解析後會變成下面的樹:

image.png | center | 400x155

解析的過程能夠分紅兩個子過程:詞法分析(lexer)和語法分析(parser)。簡單來講,一個是拆分標記,一個是匹配規則。

image.png | center | 101x300

通常都會用一些工具來生成解析器,Webkit 用了兩個知名的解析器生成器:詞法分析器 Flex ,語法分析器 Bison (Lex/Yacc)。

HTML文檔解析

<html>
  <body>
    <p>
      Hello World
    </p>
    <div> <img src="example.png"/></div>
  </body>
</html>

會被翻譯成以下的DOM樹:

image.png | center | 400x219

HTML的解析規則比較複雜,由於HTML有很高的容錯性,好比:

</br><br><br /> 都要解析成空行;

<table>
    <table>
        <tr><td>inner table</td></tr>
    </table>
    <tr><td>outer table</td></tr>
</table>

<!-- 離散表格會被解析成 -->

<table>
    <tr><td>outer table</td></tr>
</table>
<table>
    <tr><td>inner table</td></tr>
</table>

CSS解析

Webkit會把CSS文件解析成 StyleSheet 對象,每一個對象都包含CSS規則,CSS 規則對象則包含選擇器和聲明對象,以及其餘與 CSS 語法對應的對象。

image.png | center | 500x393

一個節點上若是有多條不一樣的樣式規則,會經過權重的方式來計算。通常認爲是:

!important > 內聯樣式規則 > id選擇器 > 類選擇器 > 元素選擇器

在 DOM 樹構建的同時,瀏覽器還會構建另外一個樹結構:呈現樹。這是由可視化元素按照其顯示順序而組成的樹,也是文檔的可視化表示。它的做用是按照正確的順序繪製內容。

image.png | center | 731x396

佈局

呈現器在建立完成並添加到呈現樹時,並不包含位置和大小信息。計算這些值的過程稱爲佈局(layout)或重排(reflow)。

佈局是一個遞歸的過程。它從根呈現器(對應於 HTML 文檔的 <html> 元素)開始,而後遞歸遍歷部分或全部的框架層次結構,爲每個須要計算的呈現器計算幾何信息。

佈局分爲全局佈局和增量佈局。全局佈局是指觸發了整個呈現樹範圍的佈局,觸發緣由可能包括:

  • 影響全部呈現器的全局樣式更改,例如字體大小更改。
  • 屏幕大小調整。

增量佈局是隻對改變的部分(dirty呈現器)進行佈局。

繪製

在繪製階段,系統會遍歷呈現樹,並調用呈現器的「paint」方法,將呈現器的內容顯示在屏幕上。

和佈局同樣,繪製也分爲全局(繪製整個呈現樹)和增量兩種。

在發生變化時,瀏覽器會盡量作出最小的響應。所以,元素的顏色改變後,只會對該元素進行重繪(repaint)。元素的位置改變後,只會對該元素及其子元素(可能還有同級元素)進行佈局(layout)和重繪(repaint)。添加 DOM 節點後,會對該節點進行佈局(layout)和重繪(repaint)。一些重大變化(例如增大「html」元素的字體)會致使緩存無效,使得整個呈現樹都會進行從新佈局(relayout)和繪製(repaint)。

瀏覽器數據持久化存儲

瀏覽器緩存(Browser Caching)是瀏覽器端用於在本地保存數據並進行快速讀取,以免重複資源請求的傳輸機制的統稱。有效的緩存能夠避免重複的網絡資源請求並讓瀏覽器快速地響應用戶操做,提升頁面內容的加載速度。瀏覽器端緩存的實現機制種類較多,通常能夠分爲九種:

  • HTTP文件緩存
  • LocalStorage
  • SessionStorage
  • indexDB
  • Web SQL
  • Cookie
  • CacheStorage
  • Application Cache
  • Flash緩存

圖片描述

HTTP文件緩存

HTTP文件緩存是基於HTTP協議的瀏覽器端文件級緩存機制。在文件重複請求的狀況下,瀏覽器能夠根據HTTP響應的協議頭信息判斷是從服務器端請求文件仍是從本地讀取文件,Chrome控制檯下的Frames就能夠查看瀏覽器的HTTP文件資源緩存列表內容。

HTTP文件緩存處理的流程圖以下:

image.png | center | 747x464

好比:

image.png | center | 400x528.8000000000001

若是同時設置了 Expires 和 Cache-Control,則只有 Cache-Control 生效。

image.png | center | 500x553.5279805352799

localStorage

localStorage 是HTML5的一種本地緩存方案。支持目前的主流瀏覽器,在不一樣瀏覽器中的長度限制各不相同,好比 Chrome 是 2.6MB,IE 是 5MB,這個長度限制是指單個域名下的 localStorage 大小限制。

image.png | left | 827x291

localStorage 不適合存放太多的數據,它遵循同源策略,可是它是持續存在的。

當瀏覽器進入隱私瀏覽模式,會建立一個新的、臨時的數據庫來存儲localStorage的數據;當關閉隱私瀏覽模式時,該數據庫將被清空並丟棄。

sessionStorage

sessionStorage 和 localStorage 相似,不過 sessionStorage 在瀏覽器關閉時會自動清空。用到的比較少,好比能夠自動保存表單輸入框的內容,若是瀏覽器因偶然因素被刷新了,輸入框裏面的內容會被恢復,所以寫入的內容不會丟失。

Cookie

Cookie是服務器發送到用戶瀏覽器並保存在本地的一小塊數據,它會在瀏覽器下次向同一服務器再發起請求時被攜帶併發送到服務器上。一條Cookie記錄主要由鍵、值、域、過時時間和大小組成,通常用於保存用戶網站認證信息或個性化設置。Cookie 最大長度限制通常爲 4KB。

持久型Cookie會保存在用戶的硬盤上。

image.png | center | 827x264.6714150047483

WebSQL

WebSQL是獨立於HTML5的單獨規範,如今支持的瀏覽器不多,因此用的很少。

WebSQL容許用SQL語句進行查詢,至關於集成在瀏覽器裏的小型數據庫。

image.png | center | 827x404.0266253869969

IndexDB

IndexDB支持的瀏覽器比較普遍,通常推薦使用IndexDB來進行大量數據的存儲。瀏覽器對IndexDB的大小限制一般約爲50MB。

DEMO:https://girliemac.com/stickies/

Application Cache

Application Cache 是一種容許瀏覽器經過manifest 配置文件在本地有選擇性地存儲JavaScript、CSS、圖片等靜態資源的文件級緩存機制。當頁面不是首次打開時,經過一個特定的manifest文件配置描述來選擇讀取本地Application Cache裏面的文件。
.
使用Application Cache來實現瀏覽器應用具備如下三個優點。

  1. 離線瀏覽:經過manifest配置描述來讀取本地文件,用戶可在離線時瀏覽完整的頁面內容。
  2. 快速加載:因爲緩存資源爲本地資源,所以頁面加載速度較快。
  3. 服務器負載小:只有在文件資源更新時,瀏覽器纔會從服務器端下載,這樣就減少了服務器資源請求的壓力。

image.png | center | 827x327.6083995459705

Application Cache 已經開始慢慢被棄用,被 Service Worker 取代。

cacheStorage

cacheStorage是在ServiceWorker規範中定義的,可用於保存每一個ServiceWorker聲明的Cache對象,是將來可能用來代替Application Cache的離線方案。

示例代碼:

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open('mysite-static-v3').then(function(cache) {
      return cache.addAll([
        '/css/whatever-v3.css',
        '/css/imgs/sprites-v6.png',
        '/css/fonts/whatever-v8.woff',
        '/js/all-min-v4.js'
        // etc
      ]);
    })
  );
});

演示:https://fed.renren.com/

具體使用能夠參考:https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/

前端調試工具——Chrome 開發者工具

Chrome 開發者工具是一套內置於Google Chrome中的Web開發和調試工具,可用來對網站進行迭代、調試和分析,是前端開發人員最經常使用的調試工具之一。

元素面板(Elements)

使用 Chrome DevTools 的 Elements 面板檢查和實時編輯頁面的 HTML 與 CSS。

image.png | center | 747x433

🖥 演示:

  • 實時編輯DOM節點;
  • 查看元素事件偵聽器;
  • 實時編輯樣式;
  • 檢查和編輯盒模型參數;
  • 查看本地更改;
  • 切換 Device Mode
  • 模擬傳感器

控制檯面板(Console)

控制檯主要是用來查看動態信息和執行Javascript代碼。

使用 Console API 能夠向控制檯寫入信息、建立 JavaScript 配置文件,以及啓動調試會話。

  • console.log
  • console.info
  • console.warn
  • console.error
  • console.assert
  • console.count
  • console.time
  • console.timeEnd
  • console.timeStamp
  • console.group
  • console.groupEnd
  • console.profile
  • console.profileEnd
  • console.trace
  • console.clear

🖥 演示:

console.time("Array initialize");
var array= new Array(1000000);
for (var i = array.length - 1; i >= 0; i--) {
    array[i] = new Object();
};
console.timeEnd("Array initialize");
var user = "jsmith", authenticated = false;
console.group("Authentication phase");
console.log("Authenticating user '%s'", user);
// authentication code here...
if (!authenticated) {
    console.log("User '%s' not authenticated.", user)
}
console.groupEnd();
function add(num) {
    if(num > 0) {
        console.trace('num:', num);
        return num + add(num - 1);
    } else {
        return 0;
    }
}
add(5);

便捷函數:

  • $_ 返回最近評估的表達式的值。
  • $(selector) <span data-type="color" style="color:rgb(33, 33, 33)">返回帶有指定的 CSS 選擇器的第一個 DOM 元素的引用。</span>
  • $$(selector) 返回與給定 CSS 選擇器匹配的元素數組。

一些有趣的console:
https://www.zhihu.com/
https://www.tmall.com/
https://www.baidu.com/
http://www.iqiyi.com/

源代碼面板(Sources)

源代碼面板主要是用來查看和調試代碼。

image.png | center | 827x394

🖥 演示:https://googlechrome.github.io/devtools-samples/debug-js/get-started

網絡面板(Network)

咱們的開發不少都是基於HTTP接口的調試,因此網絡面板很是重要。

Network 面板記錄頁面上每一個網絡操做的相關信息,包括詳細的耗時數據、HTTP 請求與響應標頭和 Cookie等等。

Network 面板由五個窗格組成:

image.png | center | 827x423

  1. Controls。使用這些選項能夠控制 Network 面板的外觀和功能。
  2. Filters。 使用這些選項能夠控制在 Requests Table 中顯示哪些資源。按住 Cmd (Mac) 或 Ctrl (Windows/Linux) 並點擊過濾器能夠同時選擇多個過濾器。
  3. Overview。 此圖表顯示了資源檢索時間的時間線。若是看到多條豎線堆疊在一塊兒,則說明這些資源被同時檢索。
  4. Requests Table。 此表格列出了檢索的每個資源。 默認狀況下,此表格按時間順序排序,最先的資源在頂部。點擊資源的名稱能夠顯示更多信息。 提示:右鍵點擊 Timeline 之外的任何一個表格標題能夠添加或移除信息列。
  5. Summary。 此窗格能夠一目瞭然地查看請求總數、傳輸的數據量和加載時間。

Network 面板能夠在頁面加載期間捕捉屏幕截圖。此功能稱爲幻燈片。

Network 面板突出顯示兩種事件:DOMContentLoaded 和 load。解析頁面的初始標記時會觸發 DOMContentLoaded。頁面徹底加載時將觸發 load。

🖥 演示:面板、幻燈片

Filter 文本字段還支持各類關鍵詞,Ctrl+空格能夠查看全部命令:

  • domain。僅顯示來自指定域的資源。可使用通配符字符 (*) 來包含多個域。 例如,*.com 將顯示來自以 .com 結尾的全部域名的資源。 DevTools 會使用它遇到的全部域填充自動填充下拉菜單。
  • has-response-header。顯示包含指定 HTTP 響應標頭的資源。 DevTools 會使用它遇到的全部響應標頭填充自動填充下拉菜單。
  • is。使用 is:running 能夠查找 WebSocket 資源。
  • larger-than。顯示大於指定大小的資源(以字節爲單位)。 將值設爲 1000 等同於設置爲 1k。
  • method。顯示經過指定 HTTP 方法類型檢索的資源。 DevTools 會使用它遇到的全部 HTTP 方法填充下拉菜單。
  • mime-type。顯示指定 MIME 類型的資源。DevTools 會使用它遇到的全部 MIME 類型填充下拉菜單。
  • mixed-content。顯示全部混合內容資源 (mixed-content:all),或者僅顯示當前顯示的資源 (mixed-content:displayed)。
    scheme。顯示經過未保護 HTTP (scheme:http) 或受保護 HTTPS (scheme:https) 檢索的資源。
  • set-cookie-domain。顯示具備 Set-Cookie 標頭並帶有與指定值匹配的 Domain 屬性的資源。 DevTools 會使用它遇到的全部 Cookie 域填充自動填充下拉菜單。
  • set-cookie-name。顯示具備 Set-Cookie 標頭而且名稱與指定值匹配的資源。 DevTools 會使用它遇到的全部 Cookie 名稱填充自動填充下拉菜單。
  • set-cookie-value。顯示具備 Set-Cookie 標頭而且值與指定值匹配的資源。 DevTools 會使用它遇到的全部 Cookie 值填充自動填充下拉菜單。
  • status-code。僅顯示 HTTP 狀態代碼與指定代碼匹配的資源。 DevTools 會使用它遇到的全部狀態代碼填充自動填充下拉菜單。

🖥 演示:Filter、複製、保存和清除網絡信息

一個請求生命週期的主要階段包括:

image.png | center | 827x347

  • 重定向

    • 當即開始 startTime。
    • 若是正在發生重定向,redirectStart 也會開始。
    • 若是重定向在本階段末發生,將採集 redirectEnd。
  • 應用緩存

    • 若是是應用緩存在實現請求,將採集 fetchStart 時間。
  • DNS

    • domainLookupStart 時間在 DNS 請求開始時採集。
    • domainLookupEnd 時間在 DNS 請求結束時採集。
  • TCP

    • connectStart 在初始鏈接到服務器時採集。
    • 若是正在使用 TLS 或 SSL,secureConnectionStart 將在握手(確保鏈接安全)開始時開始。
    • connectEnd 將在到服務器的鏈接完成時採集。
  • 請求

    • requestStart 會在對某個資源的請求被髮送到服務器後當即採集。
  • 響應

    • responseStart 是服務器初始響應請求的時間。
    • responseEnd 是請求結束而且數據完成檢索的時間。

Timing 標籤能夠查看網絡請求完整的耗時信息:

image.png | center | 500x433.2688588007737

  • Queuing:請求排隊時間,通常排隊是由於請求優先級低,或者被暫停(在 HTTP 1 上,瀏覽器僅容許每一個源擁有六個 TCP 鏈接)等。
  • Stalled/Blocking:請求等待發送所用的時間。
  • Proxy Negotiation:與代理服務器鏈接協商所用的時間。
  • DNS Lookup:執行 DNS 查詢所用的時間。
  • Initial Connection / Connecting:創建鏈接所用的時間,包括 TCP 握手/重試和協商 SSL 的時間。
  • SSL:完成 SSL 握手所用的時間。
  • Request Sent / Sending:發出網絡請求所用的時間。 一般不到一毫秒。
  • Waiting (TTFB):等待初始響應所用的時間,也稱爲至第一字節的時間。 此時間將捕捉到服務器往返的延遲時間,以及等待服務器傳送響應所用的時間。
  • Content Download / Downloading:接收響應數據所用的時間。

經過 Network 面板能夠發現大量可能的問題,好比:

有不少被中止的條目:
代表正在從單個域檢索太多的資源。在 HTTP 1.0/1.1 鏈接上,Chrome 會將每一個主機強制設置爲最多六個 TCP 鏈接。要解決此問題,須要實現域分片。也就是在應用上設置多個子域,以便提供資源。好比京東的首頁,就有不少的子域名來加載圖片:

image.png | center | 500x750

至第一字節的時間很長:
又稱:大片綠色,通常是由於:客戶端與服務器之間的網絡條件較差或者服務器應用的響應慢。若是本地託管後 TTFB 仍然漫長,那麼問題通常出在客戶端與服務器之間的網絡上。

image.png | center | 257x247

達到吞吐量能力:
又稱:大片藍色。通常是返回的報文太大了,首要的解決辦法是減小發送的字節數。

image.png | center | 410x243

🖥 演示:京東首頁 https://www.jd.com/;使用 DevTools 能夠模擬不一樣的網絡條件,解決加載時間問題。

性能面板(Performance)

性能面板以前叫 Timeline,在 Chrome 57 以後改名爲性能面板。主要用來記錄和分析應用在運行時的全部活動。

Performance 面板包含如下四個窗格:

  1. Controls。開始記錄,中止記錄和配置記錄期間捕獲的信息。
  2. Overview。 頁面性能的高級彙總。
  3. 火焰圖。 CPU 堆疊追蹤的可視化。能夠在火焰圖上看到一到三條垂直的虛線。藍線表明 DOMContentLoaded 事件。 綠線表明首次繪製的時間。 紅線表明 load 事件。
  4. Details。選擇事件後,此窗格會顯示與該事件有關的更多信息。 未選擇事件時,此窗格會顯示選定時間範圍的相關信息。

image.png | center | 827x649

Overview 窗格包含如下三個圖表:

image.png | center | 827x150

  1. FPS。每秒幀數。綠色豎線越高,FPS 越高。 FPS 圖表上的紅色塊表示長時間幀,極可能會出現卡頓。
  2. CPU。 CPU 資源。此面積圖指示消耗 CPU 資源的事件類型。
  3. NET。每條彩色橫槓表示一種資源。橫槓越長,檢索資源所需的時間越長。 每一個橫槓的淺色部分表示等待時間(從請求資源到第一個字節下載完成的時間)。橫槓按照如下方式進行彩色編碼:

    • HTML 文件爲<span data-type="color" style="color:rgb(110, 161, 226)">藍色</span>
    • 腳本爲<span data-type="color" style="color:rgb(239, 196, 87)">黃色</span>
    • 樣式表爲<span data-type="color" style="color:rgb(155, 127, 230)">紫色</span>
    • 媒體文件爲<span data-type="color" style="color:rgb(116, 178, 102)">綠色</span>
    • 其餘資源爲<span data-type="color" style="color:rgb(179, 179, 179)">灰色</span>

通常性能面板主要用於優化頁面的加載時間,提升頁面的流暢度,對於用戶量很大的頁面調優很是有用。好比:

  • 經過找出較長的Evaluate Script 事件,經過 JS 分析器獲取究竟調用了哪些 JS 函數以及調用每一個函數須要多長時間的更詳細信息。
  • 樣式更改開銷較大,在這些更改會影響 DOM 中的多個元素時更是如此。經過檢查大型 Recalculate Style 事件的記錄(以紫色顯示),若是樣式更改須要較長時間,對性能的影響會很是大。
  • 「佈局抖動」是指反覆出現強制同步佈局狀況。 這種狀況會在 JavaScript 從 DOM 反覆地寫入和讀取時出現,將會強制瀏覽器反覆從新計算佈局。經過觀察紅色豎線標記的 Layout 事件,能夠發現佈局方面的問題。
  • 繪製是填充像素的過程。這常常是渲染流程開銷最大的部分。 在任何狀況下注意到頁面出現卡頓現象,頗有可能存在繪製問題。

🖥 演示:快速肯定繪製瓶頸,Paint flashing(在Rendering面板中),打開此選項後,每次發生繪製時,Chrome 將讓屏幕閃爍綠色。https://www.jd.com/

內存面板(Memory)

內存面板以前叫 Profile,在 Chrome 57 以後改名爲內存面板。主要用於查找影響頁面性能的內存問題,包括內存泄漏、內存膨脹和頻繁的垃圾回收。

用戶通常會經過如下方式察覺到有內存問題:

  • 頁面的性能隨着時間的延長愈來愈差。 這多是內存泄漏的症狀。 內存泄漏是指,頁面中的錯誤致使頁面隨着時間的延長使用的內存愈來愈多。
  • 頁面的性能一直很糟糕。 這多是內存膨脹的症狀。 內存膨脹是指,頁面爲達到最佳速度而使用的內存比本應使用的內存多。
  • 頁面出現延遲或者常常暫停。 這多是頻繁垃圾回收的症狀。 垃圾回收是指瀏覽器收回內存。 瀏覽器決定什麼時候進行垃圾回收。 回收期間,全部腳本執行都將暫停。所以,若是瀏覽器常常進行垃圾回收,腳本執行就會被頻繁暫停。

內存泄漏很容易肯定。若是網站使用的內存愈來愈多,則說明發生內存泄漏。內存膨脹比較難以界定,通常會考慮網站常常訪問的設備的配置,說到這裏,插播一下RAIL模型。

使用 RAIL 模型評估性能

RAIL 是一種以用戶爲中心的性能模型。每一個網絡應用均具備與其生命週期有關的四個不一樣方面,且這些方面以不一樣的方式影響着性能:

image.png | center | 827x300

讓用戶成爲性能工做的中心。用戶花在網站上的大多數時間不是等待加載,而是在使用時等待響應。

延遲與用戶反應:

0 - 16 毫秒 用戶能夠感知每秒渲染 60 幀的平滑動畫轉場。也就是每幀 16 毫秒
0 - 100 毫秒 在此時間窗口內響應用戶操做,他們會以爲能夠當即得到結果。時間再長,操做與反應之間的鏈接就會中斷。
100 - 300 毫秒 用戶會遇到輕微可覺察的延遲。
300 - 1000 毫秒 對於網絡上的大多數用戶,這個時間段表明任務還在繼續,是合理的延遲。
1000+ 毫秒 超過 1 秒,用戶的注意力將離開他們正在執行的任務。
10,000+ 毫秒 用戶感到失望,可能會放棄任務;以後他們或許不會再回來。

響應:儘可能在 100 毫秒之內響應,對於須要超過 500 毫秒才能完成的操做,要始終提供反饋。

動畫:儘可能在 10 毫秒內生成一幀,由於瀏覽器須要花費時間將新幀繪製到屏幕上,因此只有 10 毫秒來執行代碼。

空閒:最大程度增長空閒時間,利用空閒時間完成推遲的工做。例如,儘量減小預加載數據,以便應用快速加載,並利用空閒時間加載剩餘數據。

加載:儘可能在 1000 毫秒之內呈現內容。

使用 Chrome 任務管理器實時監視內存使用,打開任務管理器,右鍵點擊任務管理器的表格標題並啓用 JavaScript memory。

內存能夠表示爲一個由多個互連的點組成的圖表:

image.png | center | 538x339

對象可經過如下兩種方式佔用內存:

  • 直接經過對象自身佔用。
  • 經過保持對其餘對象的引用隱式佔用,這種方式能夠阻止這些對象被垃圾回收器(GC)自動處置。

堆分析器中:

  • Shallow Size(淺層大小),這是對象自身佔用內存的大小。
  • Retained Size(保留大小),這是將對象自己連同其相關對象一塊兒刪除後釋放的內存大小。

image.png | center | 775x257

內存圖從根開始,根能夠是瀏覽器的 window 對象或 Node.js 模塊的 Global 對象。距離(Distance)字段,表示與 GC 根之間的距離。

image.png | center | 478x295

任何沒法從根到達的對象都會被 GC 回收。

🖥 演示:按函數調查內存分配 Allocation sampling

應用面板(Application)

應用面板用來檢查加載的全部資源,包括IndexedDB與Web SQL數據庫,本地和會話存儲,cookie,應用程序緩存,圖像,字體和樣式表。在持久化存儲已經聊過。

🖥 演示:查看和編輯本地存儲。

安全面板(Security)

安全面板主要是用來查看頁面的總體安全性。

🖥 演示:

非安全頁面會經過消息 This page is not secure. 提示

比較:https://www.google.com/

其餘面板

🖥 演示:Audit 基於 Lighthouse,能夠用於分析頁面性能。

Chrome 的高性能網絡(High Performance Networking)

Chrome 從2008年推出以來,如今已經在全世界瀏覽器市場中佔了第一的份額,並且不斷的在增加。

image.png | center | 827x136

驅動 Chrome 瀏覽器發展的主要是這幾個原則:

  • Speed: 作最快的瀏覽器。
  • Security: 給用戶提供最安全的上網環境。
  • Stability: 提供一個健壯且穩定的Web應用平臺。
  • Simplicity: 提供簡潔的用戶體驗。

這裏所說的高性能網絡,就是遵循了第一個原則:Speed。

以前說過一個網絡請求的生命週期中間有不少步驟:

image.png | center | 635x348

這中間DNS查找、TCP三次握手、SSL握手等等,都會耗費必定的時間,對於響應比較快的請求,可能80%以上的開銷都在網絡上。

Chrome 的多進程架構爲瀏覽器的網絡請求處理帶來了重要意義,它目前支持四種不一樣的執行模式:

  • Process-per-site-instance:就是打開一個網站,而後從這個網站開的每個Tab屬於一個進程。優勢:隔離性很強;缺點:內存開銷大,實現複雜。
  • Process-per-site:同域名的網站Tab放在一個進程。
  • Process-per-tab:一個Tab一個進程。
  • Single process:傳統模式,只有一個進程。

默認狀況下,桌面的 Chrome 瀏覽器使用 process-per-site 模式, 將不一樣的網站頁面隔離起來, 相同網站的頁面組織在一塊兒。

Chrome Predictor 預測功能優化:

Chrome會隨着使用變得更快。Predictor 會觀察和學習當前網絡活動方式,提早預估用戶下一步的操做。好比:

  • 用戶將鼠標停留在一個連接上,就預示着一個用戶的偏好以及下一步的瀏覽行爲。這時 Chrome 就能夠提早進行 DNS Lookup 及 TCP 握手。用戶的點擊操做平均須要將近 200ms,在這個時間就可能處理完 DNS 和 TCP 相關的操做, 也就是省去幾百毫秒的延遲時間。
  • 當在地址欄觸發高可能性選項時,就一樣會觸發一個 DNS lookup 和 TCP 預鏈接(pre-connect),甚至在一個不可見的頁籤中進行預渲染(pre-render)。
  • 咱們每一個人都一串每天會訪問的網站, Chrome 會研究在這些頁面上的子資源, 而且嘗試進行預解析(pre-resolve), 甚至可能會進行預加載(pre-fetch)以優化瀏覽體驗。

Chrome採用了四種核心優化技術:

  • DNS pre-resolve:DNS 預解析,提早解析主機地址,以減小 DNS 延遲。
  • TCP pre-connect:TCP 預鏈接,提早鏈接到目標服務器,以減小 TCP 握手延遲。
  • Resource prefetching:資源預加載,提早加載頁面的核心資源,以加快頁面顯示。
  • Page prerendering:頁面預渲染,提早獲取整個頁面和相關子資源。

🖥 演示:chrome://predictors/

Chrome會維護用戶輸入的前綴的歷史記錄,建議的操做以及每一個前綴的命中率。好比我平時輸入了 appl,那麼 100% 是要訪問蘋果官網。

TL;DR

此次主要聊了前端大概的演變,瀏覽器的一些基礎,以後有時間會聊聊協議、安全、框架、實踐、跨棧之類的,你們辛苦!

相關文章
相關標籤/搜索