前端性能優化

網絡層面的優化
1.webpack 性能調化與 Gzip 原理。
webpack 的優化的瓶頸:構建時間長,打包體積大。
構建時間長的 方案
不要讓loader作太多事情,用include或exclude避免不須要的轉譯(node_modules);開啓緩存將轉譯結果緩存至文件系統 loader: 'babel-loader? cacheDirectory =true' )。
不要放過第三方庫, DllPlugin這個插件會把第三方庫單獨打包到一個單純的依賴庫的文件中。這個依賴庫不會跟着你的業務代碼一塊兒被從新打包,只有當依賴自身發生版本變化時纔會從新打包。
將loader由單進程轉爲多進程, Happypack 把任務分解給多個子進程去併發執行。 手動建立進程池,問號後面的查詢參數指定了處理這類文件的HappyPack實例的名字, new HappyPack id 和 threadPool指定進程池
打包體積大的 方案
webpack-bundle-analyzer 文件結構可視化,找到致使體積大的緣由。
刪除冗餘代碼,webpack4中配置 optimization.minimize 和 minimizer 字定義壓縮刪除相關操做。
按需加載 require .ensure(dependencies, callback, chunkName)
Gzip 壓縮
開啓 Gzip,在 request hheaders中加上: accept-encoding:gzip
原理:找出重複出現的字符串、臨時替換它們從而使整個文件變小。
2.圖片優化
不一樣場景 選擇不一樣類型的圖片
JPEG/JPG - 有損壓縮,背景圖、輪播圖、Banner圖。
PNG - 支持透明,體積大。色彩表現力強,對線條的處理更加細膩。小Logo、顏色簡單對比度強的透明小圖。
SVG - 文本文件、不失真、體積小。寫入HTML、寫入獨立文件引入HTML。
Base64 - 文本文件、依賴編碼、小圖標解決方案。很是小的Logo。
CSS Sprites - 將小圖標和背景合併到一張圖片上,利用背景定位顯示其中的部分。
WebP - 旨在加快圖片加載速度的圖片格式。 .jpg_.webp 格式來匹配不支持的狀況。
3.瀏覽器緩存
瀏覽器緩存機制由四個方面,按照獲取資源請求的優先級一次排列:
1. Memory Cache
內存中的緩存。Base64 格式的圖片。幾乎永遠能夠被塞進去。可視做瀏覽器爲了節省開銷的「自保行爲」。
2. Service Worker Cache
獨立於主線程以外的js線程。有install、active、working 三個階段。一旦Service Worker被install,它將始終存在,只會在active與working之間切換,除非咱們主動終止它。
必須以 https 協議爲前提。
3. HTTP Cache
強緩存在緩存時間內不向服務器發起請求,過時以後纔會發起請求。
cache-control :max-age=31536000
max-age 控制資源的有效期,時間長度內是有效的,單位是秒。
Cache-Control 的 max-age 比 expires 優先級更高。
no-cache 繞開瀏覽器,直接去向服務器確認該資源是否過時。
no-store 不使用任何緩存策略,只容許你直接向服務器發送請求、並下載完整的響應。
協商緩存:瀏覽器和服務器合做之下的緩存策略
若是服務器端提示緩存資源未改動(Not Modified),資源會被重定向到瀏覽器緩存,這種狀況下網絡請求對應的狀態碼是 304。
首次請求隨着 Response Headers返回Last-Modified,隨後請求會帶上 If-Moodified-Since 的時間戳字段,比較二者的時間去執行對應的操做。變了會發起一個完整的響應內容,並在Response Headers返回新的Last-Modified值;不然返回304響應,不添加Last-Modified字段。弊端:內容沒變也會從新請求;修改文件過快沒發起請求。
Etag是由服務器未每一個資源生成的惟一的 標識字符串(基於文件內容編碼的),Etag可以精準感知文件的變化。
首次請求能夠在Response Headers得到一個最初的標識符字符串,下次請求在請求頭帶上值相同的、名爲 if-None-Match 的字符串供服務端對比。
4. Push Cache
HTTP2 在 server push 階段存在的緩存。
在以上都沒有命中才會去詢問 Push Cache;
它存在於會話階段的緩存,當session終止時,緩存也隨之釋放;
不一樣頁面只要共享了同一個 HTTP2 鏈接,那麼他們就能夠共享一個 Push Cache
4.本地儲存
Cookie
爲了維持狀態;附着在 HTTP 請求上,在瀏覽器和服務器之間傳輸。
劣勢:Cookie 不夠大,只有 4KB;過量的 Cookie 會帶來巨大的性能浪費,同一域名下的全部請求,都會寫到Cookie。
Local Storage
持久化的本地儲存,使其消失的惟一辦法手動刪除。
儲存 Base64 格式的圖片字符串;不常更新的 CSS、JS 等資源。
Session Storage
會話結束時,內存內容被釋放。
儲存上次訪問的 URL 地址。
Web Storage
特性:
存儲量5-10M。
位於瀏覽器端,不與服務端發生通訊。
API:
儲存:setItem()
讀取:getItem()
刪除:removeItem()
清空:clear()
IndexedDB
一個運行在瀏覽器上的非關係型數據庫。>250M 能夠存儲字符串、二進制數據。
能夠看作是LocalStorage的一個升級。
5.CDN 緩存與回源
CDN 指的是一組分佈在各個地區的服務器。這些服務器儲存着數據的副本,所以服務器能夠根據哪些服務器與用戶距離最近,來知足數據的請求。CDN 提供快速服務,較少受高流量影響。
核心: 緩存 回源。 「緩存」就是咱們把資源 copy 一份到 CDN 服務器上這個過程,「回源」就是CDN發現本身沒有這個資源(通常是緩存數據過時了),轉頭向根服務器去要這個資源的過程。
CDN 每每被用來存放靜態資源。(CSS、JS、Image)
CDN 域名和服務器域名不一樣。
渲染層面
1.服務端渲染
SSR 主要用於解決單頁應用首屏渲染慢以及SEO問題,但同時:提升了服務器壓力,吃CPU,內存等資源,優化很差提升成本。
Vue是如何實現 服務端渲染 的呢?
一是這個 renderToString () 方法(把Vue實例轉化爲真實DOM的關鍵方法);
二是把轉化結果「塞」進模板裏。(res.end 把渲染出來的真實DOM字符串插入HTML模板中)
2.瀏覽器渲染 - CSS、JS性能方案
每一個頁面首次渲染都經歷了 解析HTML - 計算樣式 - 計算圖層佈局 - 繪製圖層 - 整合圖層獲得頁面。HTML構建DOM樹,CSS構建CSSOM樹,CSSOM與DOM結合獲得渲染樹,最後瀏覽器以佈局渲染樹去計算佈局,繪製圖像。
CSS 選擇器是從右到左進行匹配的。(避免使用通配符;用類選擇器代替標籤選擇器;不要多此一舉用id和class選擇器;減小嵌套)。
CSS 的阻塞 ,須要儘早(放在 head 標籤裏)和儘快(啓用 CDN 實現靜態資源加載速度優化)地下載到客戶端,以便縮短首次渲染的實踐。
JS 的阻塞 ,JS 引擎搶走了渲染引擎的控制權。 async defer 模式加載都是異步的,async 是當即執行的(用於DOM和腳本依賴不強),defer 是推遲執行的(等整個文檔解析完成時,用於腳本依賴DOM和其餘腳本的執行結果)。
3.DOM優化原理與基本思路
當咱們用JS操做DOM時,本質上時JS引擎和渲染引擎之間進行了「跨界交流」,依賴了橋接接口做爲「橋樑」。減小DOM操做。
咱們對DOM修改會引起它外觀上的改變時,就會出發回流(幾何尺寸變化)或重繪(樣式變化)。
減小DOM操做 :緩存變量;DOM Fragment。
4.事件循環和異步更新策略
事件循環優化:當咱們須要在異步任務中實現 DOM修改 時,把它包裝成 micro 任務時相對明智的選擇(不須要多消耗一次渲染,不須要等待下一事件循環)。macro - mincro - render。
異步更新:把任務塞到異步任務隊列裏,在JS層面被批量執行完畢。到渲染時,它僅僅須要針對有意義的計算結果操做一次DOM。( 避免過分渲染
使用Vue.nextTick()是爲了能夠獲取更新後的DOM。在同一事件循環中的數據變化後,DOM完成更新,就會執行Vue.nextTick()的回調。過程是同一事件循環中的代碼執行完畢 -> DOM 更新 -> nextTick callback觸發。
5.迴流和重繪
觸發迴流:改變DOM元素的幾何屬性;改變DOM樹的結構;獲取特定的值(即時計算獲得)。
JS變量的形式緩存起來。
避免逐條改變樣式,使用類名去合併樣式( el.classList.add( 'basic_style' ) )。
將DOM離線( display = 'none' ..添加樣式.. display = 'block' )
Flush隊列(本身緩存一個flush隊列,把任務塞進去,到必定時間再出隊)。
應用篇
1.優化首屏體驗 - Lazy-Load
圖片懶加載
<img class="pic" alt="加載中" data-src="./images/1.png"> // 當前可視區域的高度 window.innerHeight || document.documentElement.clientHeight // 元素距離可視區域頂部的高度 getBoundingClientRect().top // 若是可視區域高度大於等於元素頂部距離可視區域頂部的高度,說明元素露出 imgs[i].src = imgs[i].getAttribute('data-src') num = i + 1
2.事件的節流和防抖
這兩個東西都以 閉包 的形式存在。
它們經過對事件對應的回調函數進行包裹、以自由變量的形式緩存時間信息,最後用 setTimeout 來控制事件的觸發頻率。
節流的中心思想:在某段時間內,無論你觸發了多少次回調,我都只認第一次,並在計時結束時給予響應。( 本次觸發的時間-上次觸發的時間 >= 設定的時間間隔閾值則執行回調
防抖的中心思想:我會等你到底。在某段時間內,無論你觸發了多少次回調,我都只認最後一次。( 每次事件被觸發時,都去清除以前的舊定時器,設立新定時器
性能檢測
Performance
LightHouse
W3C性能API
 
 
緩存解決方案
強緩存
協商緩存
http緩存流程圖
當咱們的資源內容不可複用時,直接爲 Cache-Control 設置 no-store,拒絕一切形式的緩存;不然考慮是否每次都須要向服務器進行緩存有效確認,若是須要,那麼設 Cache-control 的值爲 no-cache;

不然考慮該資源是否能夠被代理服務器緩存,根據其結果決定時設置爲 private 仍是 public;而後考慮該資源的過時時間,設置對應的 max-age 和 s-maxage 值;最後,配置協商緩存須要用到的 Etag、Last-Modified 等參數。
相關文章
相關標籤/搜索