深度講解:web前端效能優化
課程目標
- 理解
減少http請求數量
和減少請求資源大小
兩個優化要點 - 掌握壓縮與合併的原理
- 掌握通過
線上網站
和fis3
兩種實現壓縮與合併的方法 ####瀏覽器的一個請求從傳送到返回都經歷了什麼 動態的載入靜態的資源

1、dns是否可以通過快取減少dns查詢時間 2、 網路請求的過程走最近的網路環境 3、 相同的靜態資源是否可以快取 4、 能否減少http請求大小 5、 能否減少http請求數量 6、 服務端渲染 複製程式碼
2、html壓縮
資源的合併與壓縮設計到的效能點:
1、減少http請求的數量 2、減少請求的大小 複製程式碼
google首頁案例分析
1、html壓縮 2、css壓縮 3、js的壓縮與混亂 4、檔案合併 5、 開啟gzip 複製程式碼
如何進行html的壓縮
1、使用線上網站進行壓縮 2、node.js提供了html-minifier工具 3、後端模板引擎渲染壓縮 複製程式碼
3、css及js壓縮
css的壓縮
1、無效程式碼刪除 2、css語義合併 複製程式碼
css壓縮的方式
1、使用線上網站進行壓縮 2、使用html-minifier對html中的css進行壓縮 3、使用clean-css對css進行壓縮 複製程式碼
js的壓縮語混亂
1、無效字元的刪除 2、剔除註釋 3、程式碼語意的縮減和優化 4、程式碼保護 複製程式碼
js壓縮的方式
1、使用線上網站進行壓縮 2、使用html-minifier對html中的js進行壓縮 3、使用uglifyjs2對js進行壓縮 複製程式碼
4、檔案合併優點
1、檔案與檔案有插入之間的上行請求,又增加了N-1個網路延遲 2、受丟包問題影響更嚴重 3、經過代理伺服器時可能會被斷開 複製程式碼
檔案合併缺點
1、首屏渲染問題 2、快取失效問題 複製程式碼
檔案合併對應缺點的處理
1、公共庫合併 2、不同頁面的合併 3、見機行事,隨機應變 複製程式碼
檔案合併對應方法
1、使用線上網站進行合併 2、使用nodejs進行檔案合併 複製程式碼
三、圖片相關優化
課程目標
- 理解圖片相關的優化的核心概念
- 結合facebook和淘寶移動首頁案例分析
- 掌握通過線上網站和fis3兩種實現圖片相關的一些優化
1、一張JPG的解析過程

jpg有失真壓縮:雖然損失一些資訊,但是肉眼可見影響並不大
2、png8/png24/png32之間的區別

png32是在png24上支援了透明,針對不同的業務場景選擇不同的圖片格式很重要
3、不同的格式圖片常用的業務場景
不同格式圖片的特點
1、jpg有失真壓縮,壓縮率高,不支援透明 2、png支援透明,瀏覽器相容性好 3、webp壓縮程度更好,在ios webview中有相容性問題 4、svg向量圖,程式碼內嵌,相對較小,圖片樣式相對簡單的場景(儘量使用,繪製能力有限,圖片簡單用的比較多) 複製程式碼
不同格式圖片的使用場景
1、jpg:大部分不需要透明圖片的業務場景 2、png:大部分需要透明圖片的業務場景 3、webp:android全部(解碼速度和壓縮率高於jpg和png,但是ios safari還沒支援) 4、svg:圖片樣式相對簡單的業務場景 複製程式碼
4、圖片壓縮的幾種情況
1、針對真實圖片情況,捨棄一些相對無關緊要的色彩資訊 2、CSS雪碧圖:把你的網站用到的一些圖片整合到一張單獨的圖片中 //優點:減少HTTP請求的數量(通過backgroundPosition定位所需圖片) //缺點:整合圖片比較大時,載入比較慢(如果這張圖片沒有載入成功,整個頁面會失去圖片資訊)facebook官網任然在用,主要pc用的比較多,相對效能比較強 3、Image-inline:將圖片的內容嵌到html中//base64資訊,減少網站的HTTP請求,如果圖片比較小比較多,時間損耗主要在請求的骨幹網路 4、使用向量圖:使用SVG進行向量圖的繪製,使用icon-font解決icon問題 5、在android下使用webp:webp的優勢主要體現在它具有更優的影象資料壓縮演算法,能帶來更小的圖片體積,而且擁有肉眼識別無差異的影象質量;同時具備了無損和有損的壓縮模式、Alpha透明以及動畫的特性,在JPEG和PNG上的轉化效果都非常優秀、穩定和統一 複製程式碼
四、css和js的裝載與執行
課程目標
- 理解瀏覽器端html、css、js的裝載過程
- 結合chrome的能力學習掌握css、js載入過程中的優化點
- 通過案例分析和實戰演練深入理解學習的優化點
1、HTML頁面載入渲染的過程
一個網站在瀏覽器端是如何進行渲染的

2、HTML渲染過程中的一些特點
- 順序執行,併發載入
- 是否阻塞
- 依賴關係
- 引入方式
阻塞的幾種方式: css的載入是否會阻塞js的載入 css的載入是否會阻塞js的執行 css的載入是否會影響頁面的渲染 js的執行是否會阻塞js的執行和js的載入 依賴: 如果我們把css程式碼放在head中去引入的話,那麼我們整個頁面的渲染實際上就會等待head中css載入並生成css樹,最終和DOM整合生成RanderTree之後才會進行渲染 js async非同步載入 引入: script src引入有相關阻塞頁面行為 js資源是否需要動態載入 複製程式碼
3、順序執行,併發載入
- 詞法分析
- 併發載入
- 併發上限
4、css阻塞和js阻塞
css阻塞
- css head中阻塞頁面的渲染
- css阻塞js的執行
- css不阻塞外部腳步的載入
css head中通過 link方式引入,避免頁面閃動,因為這樣只有等css載入完才會渲染 js的執行很可能要操作DOM 複製程式碼
js阻塞
- 直接引入的js阻塞頁面的渲染
- js 不阻塞資源的載入
- js順序執行,阻塞後續js的執行
直接通過script src在head中引入,html parse 認為js會動態修改文件結構,沒有進行後面文件的分析
五、懶載入與預載入
- 理解懶載入和預載入的原理
- 懶載入和預載入的案例分析
- 懶載入與預載入的案例實戰
1、懶載入原理
- 圖片進入可視區域之後請求圖片資源
- 對於電商等圖片很多,頁面很長的業務場景適用
- 減少無效資源的載入
- 併發載入的資源過多會會阻塞js的載入,影響網站的正常使用
img src被設定之後,webkit解析到之後才去請求這個資源。所以我們希望圖片到達可視區域之後,img src才會被設定進來,沒有到達可視區域前並不現實真正的src,而是類似一個1px的佔位符。
2、預載入原理
- 圖片等靜態資源在使用之前的提前請求
- 資源使用到時能從快取中載入,提升使用者體驗
- 頁面展示的依賴關係維護
3、懶載入原生js和zepto.lazyload
1、原理:先將img標籤中的src連結設為同一張圖片(空白圖片),將其真正的圖片地址儲存再img標籤的自定義屬性中(比如data-src)。當js監聽到該圖片元素進入可視視窗時,即將自定義屬性中的地址儲存到src屬性中,達到懶載入的效果。
注意問題: 1、關注首屏處理,因為還沒滑動 2、佔位,圖片大小首先需要預設高度,如果沒有設定的話,會全部顯示出來


4、預載入原生js和preloadJS實現
預載入實現的幾種方式
第一種方式:直接請求下來
<img src="www.pic27.com/sadfafd/dafdsa.jpg" style="display: none"/> <img src="www.pic27.com/sadfafd/dsaf.jpg" style="display: none"/> <img src="www.pic27.com/sadfafd/dasfd.jpg" style="display: none"/> <img src="www.pic27.com/sadfafd/fdsa.jpg" style="display: none"/> 複製程式碼
第二種方式:image物件
var image = new Image(); image.src = "www.pic26.com/dafdafd/safdas.jpg"; 複製程式碼
第三種方式:xmlhttprequest

缺點:存在跨域問題 優點:好控制 複製程式碼
本質:平衡瀏覽器載入能力,讓它儘可能飽和起來
六、重繪與迴流
- 理解瀏覽器重繪與迴流的機制
- 對於一些經典的案例進行分析
- 重繪與迴流的案例分析
1、css效能讓javascript變慢
要把css相關的外部檔案引入放進head中,載入css時,整個頁面的渲染是阻塞的,同樣的執行javascript程式碼的時候也是阻塞的,例如javascript死迴圈。
一個執行緒=>javascript解析 一個執行緒=>UI渲染 複製程式碼
這兩個執行緒是互斥的,當UI渲染的時候,javascript的程式碼被終止。當javascript程式碼執行,UI執行緒被凍結。所以css的效能讓javascript變慢。
頻繁觸發重繪與迴流,會導致UI頻繁渲染,最終導致js變慢
2、什麼是重繪和迴流
迴流
- 當render tree中的一部分(或全部)因為元素的規模尺寸,佈局,隱藏等改變而需要重新構建。這就成為迴流(reflow)
- 當頁面佈局和幾何屬性改變時,就需要回流
重繪
- 當render tree中的一些元素需要更新屬性,而這些屬性只是影響元素的外觀,風格,而不影響佈局,比如background-color。就稱重繪
關係
迴流必將引起重繪,但是重繪不一定會引起迴流
3、避免重繪、迴流的兩種方法
觸發頁面重佈局的一些css屬性
- 盒子模型相關屬性會觸發重佈局
width、height、padding、margin、display、border-width、border、min-height 複製程式碼
- 定位屬性及浮動也會觸發重佈局
top、bottom、left、right、position、float、clear 複製程式碼
- 改變節點內部文字結構也會觸發重佈局
text-align、overflow-y、font-weight、overflow、font-family、line-height、vertical-align、white-space、font-size 複製程式碼
優化點:使用不觸發迴流的方案替代觸發迴流的方案
只觸發重繪不觸發迴流
color、 border-style、border-radius、 visibility、 text-decoration、 background、background-image、background-position、background-repeat、background-size、 outline、outline-color、outline-style、outline-width box-shadow 複製程式碼
新建DOM的過程
1、獲取DOM後分割為多個圖層 2、對每個圖層的節點計算樣式結果(Recalculate style 樣式重計算) 3、為每個節點生成圖形和位置(Layout 迴流和重佈局) 4、將每個節點繪製填充到圖層點陣圖中(Paint Setup和Paint重繪) 5、圖層作為紋理上傳至gpu 6、符合多個圖層到頁面上生成最終螢幕影象(Composite Layers 圖層重組) 複製程式碼
chrome建立圖層的條件
將頻繁重繪迴流的DOM元素單獨作為一個獨立圖層,那麼這個DOM元素的重繪和迴流的影響只會在這個圖層中
1、3D或透視變換CSS屬性(perspective transform) 2、使用加速視訊解碼的<video>節點 3、擁有3D(webGl)上下文或加速的2D上下文的<canvas>節點 4、混合外掛(如Flash) 5、對自己的opacity做css動畫或使用一個動畫webkit變換的元素 6、擁有加速css過濾器的元素 7、元素有一個包含複合層的後代節點(一個元素擁有一個子元素,該子元素在自己的層裡) 8、元素有一個z-index較低且包含一個複合層的兄弟元素(換句話說,就是該元素在複合層上層渲染) 複製程式碼
gif圖
總結
1、避免使用觸發迴流、重繪的CSS屬性 2、將重繪、迴流的影響範圍限制在單獨的圖層(layers)之內 3、圖層合成過程中消耗很大頁面效能,這時候需要平衡考慮重繪迴流的效能消耗
4、實戰優化點總結
1、用translate替代top屬性 2、用opacity代替visibility //opacity不會觸發重繪也不會觸發迴流,只是改變圖層alpha值,但是必須要將這個圖片獨立出一個圖層 //visibility會觸發重繪 3、不要一條一條的修改DOM的樣式,預先定義好class,然後修改DOM的className 4、把DOM離線後修改,比如:先把DOM給`display:none`(有一次reflow),然後你修改100次,然後再把它顯示出來 5、不要把DOM節點的屬性值放在一個迴圈裡當成迴圈的變數 6、不要使用table佈局,可能很小的一個小改動會造成整個table的重新佈局 //div只會影響後續樣式的佈局 7、動畫實現的速度的選擇 //根據performance量化效能優化 8、對於動畫新建圖層 9、啟用gpu硬體加速(並行運算),gpu加速意味著資料需要從cpu走匯流排到gpu傳輸,需要考慮傳輸損耗 //transform:translateZ(0) //transform:translate#d(0) 複製程式碼
七、瀏覽器儲存
- 連結localstorage、cookie、sessionstorage、indexedDB的概念和使用
- 學習理解pwa和service worker的應用
- 案例分析和實戰
1、cookies
多種瀏覽器儲存方式並存,如何選擇?

1、因為http請求無狀態,所以需要cookie去維持客戶端狀態 2、cookie的生成方式:1.httpresponseheader set-cookie 2.js中可以通過document.cookie可以讀寫cookie 3、cookie的使用用處:1.用於瀏覽器端和伺服器端的互動(使用者狀態) 2.客戶端自身資料的儲存 4、expire:過期時間 5、cookie的限制:1.作為瀏覽器儲存,大小4kb左右 2.需要設定過期時間 expire 6、重要屬性:httponly 不支援js讀寫(防止收到模擬請求攻擊) 7、不太作為儲存方案而是用於維護客戶關係 8、優化點:cookie中在相關域名下面-cdn的流量損耗 解決方案:cdn的域名和主站域名要分開 複製程式碼
2、localStorage
localstorage
- 1、HTML5設計出來專門用於瀏覽器儲存的
- 2、大小為5M左右
- 3、僅在客戶端使用,不和服務端進行通訊
- 4、介面封裝較好
- 5、瀏覽器本地快取方案
sessionstorage
- 會話級別的瀏覽器儲存
- 大小為5M左右
- 僅在客戶端使用,不和伺服器端進行通訊
- 介面封裝較好
- 對於表單資訊的維護
3、indexedDB
- IndexedDB是一種低階API,用於客戶端儲存大量結構化資料。該API使用索引來實現對該資料的高效能搜尋。雖然Web Storage對於儲存叫少量的資料很管用,但對於儲存更大量的結構化資料來說,這種方法不太有用。IndexedDB提供了一個解決方案。
- 為應用建立離線版本。
cdn域名不要帶cookie localstorage存庫、圖片 複製程式碼
4、Service Worker產生的意義
5、PWA與Service Worker
PWA(Progressive Web Apps)是一種Web App新模型,並不是具體指某一種前言的技術或者某一個單一的知識點,我們從英文縮寫來看就能看出來,這是一個漸進式的Web App,是通過一系列新的Web特性,配合優秀的UI互動設計,逐步增強Web App的使用者體驗
6、PWA與Service worker
chrome 外掛 lighthouse
檢測是不是一個漸進式web app 1、當前手機在弱網環境下能不能加載出來 2、離線環境下能不能加載出來 ... 複製程式碼
1、可靠:沒有網路的環境中也能提供基本的頁面訪問,而不會出現“未連線到網際網路”的頁面 2、快速:針對網頁渲染及網路資料訪問有較好的優化 3、融入(Engaging):應用可以被增加到手機桌面,並且和普通應用一樣有全屏、推送等特性 複製程式碼
####service worker
service worker是一個指令碼,瀏覽器獨立於當前頁面,將其在後臺執行,為實現一些不依賴頁面的或者使用者互動的特性打開了一扇大門。在未來這些特性將包括訊息推送,背景後臺同步,geofencing(地理圍欄定位),但他將推出的第一個首要的特性,就是攔截和處理網路請求的能力,包括以程式設計方式來管理被快取的響應。 複製程式碼

案例分析
chrome://serviceworker-internals/ chrome://inspect/#service-worker/ 複製程式碼
service worker網路攔截能力,儲存Cache Storage,實現離線應用
indexedDB

callback && callback()寫法 相當於 if(callback){ callback(); } 複製程式碼
7、cookie、session、localStorage、sessionStorage基本操作
8、indexedDB基本操作
object store:物件儲存 本身就是結構化儲存 複製程式碼
function openDB(name, callback) { //建立開啟indexdbindexedDB.open var request = window.indexedDB.open(name) request.onerror = function(e) { console.log('on indexedDB error') } request.onsuccess = function(e) { myDB.db = e.target.result callback && callback() } //from no database to first version,first version to second version... request.onupgradeneeded = function() { console.log('created') var store = request.result.createObjectStore('books', { keyPath: 'isbn' }) console.log(store) var titleIndex = store.createIndex('by_title', 'title', { unique: true }) var authorIndex = store.createIndex('by_author', 'author') store.put({ title: 'quarry memories', author: 'fred', isbn: 123456 }) store.put({ title: 'dafd memories', author: 'frdfaded', isbn: 12345 }) store.put({ title: 'dafd medafdadmories', author: 'frdfdsafdafded', isbn: 12345434 }) } } var myDB = { name: 'tesDB', version: '2.0.1', db: null } function addData(db, storeName) { } openDB(myDB.name, function() { // myDB.db = e.target.result // window.indexedDB.deleteDatabase(myDB.name) }); //刪除indexedDB 複製程式碼
9、indexDB事務
transcation 與object store建立關聯關係來操作object store 建立之初可以配置 複製程式碼
var transcation = db.transcation('books', 'readwrite') var store = transcation.objectStore('books') var data =store.get(34314) store.delete(2334) store.add({ title: 'dafd medafdadmories', author: 'frdfdsafdafded', isbn: 12345434 }) 複製程式碼
10、Service Worker離線應用
serviceworker需要https協議
11、如何實現ServiceWorker與主頁面之間的通訊
詳細學習 https://lavas.baidu.com/guide/v1/foundation/lavas-start
八、快取
期望大規模資料能自動化快取,而不是手動進行快取,需要瀏覽器端和伺服器端協商一種快取機制
- 理解Cache-Control所控制的快取策略
- 學習理解last-modified 和 etage以及整個服務端瀏覽器端的快取流程
- 案例分析和實戰,基於node實踐以上快取方式
1、httpheader
可快取性
1、 public:表明響應可以被任何物件(包括:傳送請求的客戶端,代理伺服器,等等)快取。 2、 private:表明響應只能被單個使用者快取,不能作為共享快取(即代理伺服器不能快取它)。 3、 no-cache:強制所有快取了該響應的快取使用者,在使用已儲存的快取資料前,傳送帶驗證器的請求到原始伺服器 4、 only-if-cached:表明如果快取存在,只使用快取,無論原始伺服器資料是否有更新 複製程式碼
到期
1、 max-age=<seconds>:設定快取儲存的最大週期,超過這個時間快取被認為過期(單位秒)。與Expires相反,時間是相對於請求的時間。 2、 s-maxage=<seconds>:覆蓋max-age 或者 Expires 頭,但是僅適用於共享快取(比如各個代理),並且私有快取中它被忽略。cdn快取 3、 max-stale[=<seconds>] 表明客戶端願意接收一個已經過期的資源。 可選的設定一個時間(單位秒),表示響應不能超過的過時時間。 4、 min-fresh=<seconds> 表示客戶端希望在指定的時間內獲取最新的響應。 複製程式碼
重新驗證和重新載入
1、must-revalidate:快取必須在使用之前驗證舊資源的狀態,並且不可使用過期資源。 2、proxy-revalidate:與must-revalidate作用相同,但它僅適用於共享快取(例如代理),並被私有快取忽略。 3、immutable :表示響應正文不會隨時間而改變。資源(如果未過期)在伺服器上不發生改變,因此客戶端不應傳送重新驗證請求頭(例如If-None-Match或If-Modified-Since)來檢查更新,即使使用者顯式地重新整理頁面。在Firefox中,immutable只能被用在 https:// transactions. 複製程式碼
1、no-store:快取不應儲存有關客戶端請求或伺服器響應的任何內容。 2、no-transform:不得對資源進行轉換或轉變。Content-Encoding, Content-Range, Content-Type等HTTP頭不能由代理修改。例如,非透明代理可以對影象格式進行轉換,以便節省快取空間或者減少緩慢鏈路上的流量。 no-transform指令不允許這樣做。 複製程式碼
2、Expires
Expires
1、快取過期時間,用來指定資源到期的時間,是伺服器端的時間點 2、告訴瀏覽器在過期時間前瀏覽器可以直接從瀏覽器快取中存取資料,而無需再次請求 複製程式碼
1、expires是http1.0的時候的 2、http1.1時候,我們希望cache的管理統一進行,max-age優先順序高於expires,當有max-age在的時候expires可能就會被忽略。 3、如果沒有設定cache-control時候會使用expires 複製程式碼
3、Last-modified和If-Modified-since
1、基於客戶端和伺服器端協商的快取機制 2、 last-modified-->response header if-modified-since-->request header 3、需要與cache-control共同使用 複製程式碼
304: 200: 複製程式碼
last-modified有什麼缺點
?
1、某些服務端不能獲取精確的修改時間 2、檔案修改時間改了,但檔案的內容卻沒有變 複製程式碼
4、Etag 和 If-none-match
1、檔案內容的hash值 2、etag-->reponse header if-none-match-->request header 3、需要與cache-control共同使用 複製程式碼
好處:
比if-modified-since更加準確 優先順序比etage更高 複製程式碼

4、流程圖


九、服務端效能優化
服務端用的node.js因為和前端用的同一種語言,可以利用服務端運算能力來進行相關的運算而減少前端的運算
課程目標
- 理解vue渲染遇到的問題
- 學習理解vue-ssr和原理和引用
- 按理分析和實戰
vue渲染面臨的問題
先載入vue.js =>執行vue.js程式碼 =>生成html 複製程式碼
以前沒有前端框架時, 用jsp/php`在服務端進行資料的填充`,傳送給客戶端就是已經`填充好資料`的html 複製程式碼
使用jQuery非同步載入資料 使用React和Vue前端框架 複製程式碼
怎麼在vue這個層面對效能進行提升
1、構建層的模板編譯(runtime,compile拆開),構建層做模板編譯工作。webpack構建時候,統一,直接編譯成runtime可以執行的程式碼 2、資料無關的prerender的方式 3、服務端渲染 複製程式碼
