這是學習後的總結和記錄javascript
但從網絡層面分析, 影響性能的點有哪幾部分呢?
DNS 域名解析時間太長? 能夠經過瀏覽器DNS緩存和DNS預加載解決, TCP每次都要創建三次握手,屬實沒有必要怎麼辦呢?能夠經過TCP長連接,預連接等。HTTP層面的優化能夠分爲 減小HTTP請求說起
和 減小HTTP請求次數
等方面優化css
# 請求過程的優化 - 構建工具Webpack調優 - 生產環境: 主要提高構建速度 - 開發環境: 主要優化打包體積 - Gzip壓縮原理 - 前端圖片的選型 # 減小HTTP請求次數 - 本地存儲技術 - 瀏覽器緩存 - 離線存儲技術 - CDN緩存和回源機制
Webpack優化能夠從開發和生產做爲切入點,在開發環境下注重構建速度的提高,不然你修改一行代碼command
+ s
保存,從新編譯等待一分鐘,閣誰誰都受不了。生產環境也就是直接面向用戶的,主要注重打包的說起。你一個js包20多兆,能給用戶卡死還費用戶的流量。html
DllPlugin
和DllReferencePlugin
建立動態連接庫optimization.splitChunks
提取公用代碼以上的調優方案主要是構建工具的壓縮與合併前端
開始 Gzip壓縮,只須要在請求頭添加一句 accept-encoding:gzip
。html5
HTTP壓縮是一種內置到網頁服務器和網頁客戶端中以改進傳輸速度和帶寬利用率的方式, 在使用HTTP壓縮的狀況下 HTTP數據在服務器發送前就已壓縮,兼容的瀏覽器將在下載所需的格式前宣告支持何種方法給服務器。 不支持壓縮方法的瀏覽器將下載未經壓縮的數據。最多見的壓縮方案包括 Gzip 和 Deflate。
HTTP壓縮就以縮小說起爲目的,對HTTP內容進行從新編碼的過程。
Gzip壓縮的原理是在一個文本文件中找出一些重複出現的字符串,進而替換他們,從而使文件體積變小。java
不一樣的業務場景下使用合適的圖片類型,從而達到在壓縮圖片體積實現優化的同時儘可能保證質量webpack
時下應用較爲普遍的 Web 圖片格式有JPEG/JPG、PNG、SVG、Webp以及Base6四、精靈圖等。web
特色: 有損壓縮, 體積小, 加載快,不支持透明
應用場景: 一些網站的大圖,如背景圖, 輪播圖和banner圖等
缺點: 不支持透明,如需使用透明圖則用 PNG瀏覽器
PNG分爲 PNG-8和PNG-24。8位的PNG支持 256種顏色, 而24位的PNG支持1600萬種顏色。
特色: 無損壓縮, 質量高,體積大,支持透明
應用場景: 適用與更強的色彩表現力圖片, 如 網站logo
,網站上的一些小圖標等。緩存
特色: 文本文件, 體積小, 不失真,兼容性好
SVG和上面的 JPG和PNG比較,具備更小的體積,可壓縮性更強。
SVG使用:
(使用居多)
圖像精靈(sprite,意爲精靈),被運用於衆多使用大量小圖標的網頁應用之上。它可取圖像的一部分來使用,使得使用一個圖像文件替代多個小文件成爲可能。相較於一個小圖標一個圖像文件,單獨一張圖片所需的 HTTP 請求更少,對內存和帶寬更加友好。
Base64對出現也是爲了減小HTTP的請求數量, 從而提高網頁性能。Base64是做爲精靈圖的補充而存在的。
特色: 文本文件、依賴編碼、小圖標解決方案
Base64是一種用於傳輸8Bit字節碼的編碼方式, 對小圖標進行Base64進行編碼,咱們能夠直接將編碼的結果插入到HTML文件和Css中,從而減小HTTP請求數
Base64編碼工具, 能夠藉助於構建工具 Webpack,使用 url-loader和file-loader進行編碼
module.exports = { // ... module: { rules: [ { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000 // 小於 10000 } } ] } }
以上代碼配置小於10000字節的圖片都將爲Base64編碼。
WebP是Google開發的一種無損壓縮圖像格式。 它支持有損壓縮和無損壓縮,能夠說它集成了 JPG、PNG等優勢。 惟一缺點就是兼容性很差。
緩存能夠減小網絡 IO 消耗,提升訪問速度。瀏覽器緩存是一種操做簡單、效果顯著的前端性能優化手段。
經過網絡獲取內容既速度緩慢又開銷巨大。較大的響應須要在客戶端與服務器之間進行屢次往返通訊,這會延遲瀏覽器得到和處理內容的時間,還會增長訪問者的流量費用。所以,緩存並重複利用以前獲取的資源的能力成爲性能優化的一個關鍵方面。
按照獲取資源時請求的優先級排序:
HTTP緩存能夠分爲 強緩存 和 協商緩存
強緩存
強緩存是利用 HTTP頭部的 Expires
和 Cache-Control
兩個字段來控制的。當請求再次發送時,瀏覽器會根據其中的 Expires
和Cache-Control
來判斷是否命中強緩存,若是命中則直接返回緩存中的資源,不會和服務器發生通信。
強緩存的標記: form dist cache
Expires
和Cache-Control
有什麼關係呢?
Cache-Control
是 Expires
的替代品。以前都是使用 Expires,在響應頭中返回 Expires強緩存字段值。類型以下:
expires: Wed, 11 Sep 2019 16:12:18 GMT
Expires是一個時間戳,當咱們再次向服務器發送請求,瀏覽器會先對比 expires時間戳和客戶端時間,若是小於客戶端時間,說明緩存沒有過時,直接去緩存中取資源。
可是 Expires有一個缺陷, 對比依賴客戶端時間。若是服務器和客戶端時間不一致,咱們手動修改客戶端時間,那麼 expires是沒法達到咱們的預期。
HTTP1.1
新增了 Cache-Control
來替代 Expires。它和Expires的做用相同, Expires能作的事情它均可以作, Expires不能作的事情它還能夠作。
Cache-Control字段以下
cache-control: max-age=31536000
Cache-Control是經過 max-age
來控制緩存資源的有效期, 它並非時間戳,而是一個時間長度。表示該資源在多少秒內是有效的。
Cache-Control比Expires更加準確, 它的優先級更高。當 Cache-Contorl和Expires同時存在時,會優先使用 Cache-Control。
no-cache 繞開了瀏覽器: 當咱們爲資源設置了 no-cache時,每一次發送的請求都不會去詢問瀏覽器的緩存狀況, 而是直接去服務端確認該資源是否過時。
no-store表示不使用任何緩存,也不會去服務端確認資源是否過時,只容許你向服務端發送請求,並下載完整的響應
協商緩存
協商緩存依賴於客戶端與服務端的通信。
客戶端會向服務端詢問緩存的相關信息,進而判斷是從新發送請求,下載完整的資源。仍是從本地獲取緩存的資源。
若是服務端資源不曾改動(last-Modified),資源會被重定向到瀏覽器緩存,這種狀況下網絡請求的狀態碼爲 304
協商緩存的字段: Last-Modified 和 Etag
Last-Modified是一個時間戳, 第一次請求時會隨着響應頭返回。
Last-Modified: Fri, 27 Oct 2017 06:35:57 GMT
當咱們再次請求時, 請求頭會攜帶一個 If-Modified-Since
資源,其對應的時間戳就是 Last-Modified返回的時間戳。
If-Modified-Since: Fri, 27 Oct 2017 06:35:57 GMT
當服務端拿到請求中的 If-Modified-Since, 會對比該時間戳和資源在服務器上最後修改的時間是否一隻,從而判斷資源是否改動。若是發生了變化就返回一個完整的響應內容, 而且更新響應頭(respones headers)中的 Last-Modified爲最新值。 不然就返回304響應, 且響應頭不會攜帶 Last-Modified字段。
Last-Modified字段存在一些缺點, 有時服務器沒法感知文件是否發生變化。爲了解決這以問題, Etag來彌補 Last-Modified的不足。
Etag是服務器爲每一個資源生成的惟一的 標示字符串, 生成的方式是根據文件的內容進行編碼的,當文件內容改變時,Etag的值也會發生變化,反之依然。因此Etag能夠精確的感知文件的變更。
Etag和Last-Modified同樣,首次請求時,響應頭裏獲取一個最初的標示字符串。以下:
ETag: W/"2a3b-1602480f459"
當下一次的請求時, 請求頭中會攜帶相同的、名爲 if-None-Match
的字符串和服務器的標示對比。更精確的判斷文件是否改動。
If-None-Match: W/"2a3b-1602480f459"
Etag在感知文件的變更比Last-Modified更精確,因此Etag的優先級更高。Etag和Last-Modified同時存在,以 Etag爲準。
MemoryCache,是指存在內存中的緩存。從優先級上來講,它是瀏覽器最早嘗試去命中的一種緩存。從效率上來講,它是響應速度最快的一種緩存。
內存緩存是快的,也是短命的。它和渲染進程生死相依。當進程結束後,內存緩存的數據也將不復存在。
內存緩存資源存放的位置具備必定的隨機性。
Service Worker 是一種獨立於主線程以外的 Javascript 線程。它脫離於瀏覽器窗體,所以沒法直接訪問 DOM。這樣獨立的個性使得 Service Worker 的「我的行爲」沒法干擾頁面的性能,這個「幕後工做者」能夠幫咱們實現離線緩存、消息推送和網絡代理等功能。咱們藉助 Service worker 實現的離線緩存就稱爲 Service Worker Cache。
Service Worker 的生命週期包括 install、active、working 三個階段。一旦 Service Worker 被 install,它將始終存在,只會在 active 與 working 之間切換,除非咱們主動終止它。這是它能夠用來實現離線存儲的重要先決條件。
Push Cache 是指 HTTP2 在 server push 階段存在的緩存。這塊的知識比較新,應用也還處於萌芽階段。
HTTP Cookie(也叫Web Cookie或瀏覽器Cookie)是服務器發送到用戶瀏覽器並保存在本地的一小塊數據,它會在瀏覽器下次向同一服務器再發起請求時被攜帶併發送到服務器上。一般,它用於告知服務端兩個請求是否來自同一瀏覽器,如保持用戶的登陸狀態。Cookie使基於無狀態的HTTP協議記錄穩定的狀態信息成爲了可能。
因爲Cookie的大小有限,根據不一樣的瀏覽器大小各不相同。最大能存儲 5kb。通常多應用於:
若是讓Cookie存儲一些大量的數據顯然是不合理的,由於Cookie每次都會攜帶在請求頭部發送給服務器,因此也會形成HTTP請求頭過大。
Web Storage是HTML5爲了解決客戶端存儲而誕生的。容許你在一個特定的域中設置、檢索和刪除數據和存儲類型。
Web Storage分爲:
sessionStorage: 給每個給定的源,維持一個獨立的存儲區域,該存儲區域在頁面回話期間可用,也就是當瀏覽器關閉了,這個保存的數據也隨之銷燬。
const data = [1,2,3] sessionStorage.setItem('arr', data) // 存儲 arr爲鍵名, data是要存儲的數據 let getData = sessionStorage.getItem('arr') // 根據鍵名去對應的數據 console.log(typeof getData) // string // 取出的是字符串類型
當關閉瀏覽器再從新開啓這個頁面, 存儲的數據會不復存在,由於它是 會話存儲。
localStorage: 和 sessionStorage同樣, 只不過它是持久化存儲,除非你手動刪除存儲的數據,不然關閉瀏覽器後數據仍然存在。
const data = [1,2,3] localStorage.setItem('arr', data) // 存儲 arr爲鍵名, data是要存儲的數據 let getData = localStorage.getItem('arr') // 根據鍵名去對應的數據 console.log(typeof getData) // string // 取出的是字符串類型 localStorage.removeItem('arr') // 根據指定的鍵名清楚緩存
當你存儲完數據以後, 關閉瀏覽器再打開數據仍是存在的。由於它是 持久存儲
localStorage和sessionStorage存儲的數據都不會被請求頭所攜帶, 而Cookie是每次都會被請求頭攜帶
CDN(內容分發網絡
) 是將源站內容分發至最接近用戶的節點, 使用戶可就近取得所需的內容,提升用戶訪問的響應的速度和成功率。解決因分佈、帶寬、服務器性能帶來的訪問延遲問題。
CND是如何工做的:
假設個人根服務器在杭州, 同時北京、上海、成都、山東都有個人機房。 此時身在山東的你向我請求資源,在網絡帶寬小、用戶訪問量大的狀況下,杭州的根服務器不能給用戶很是快的響應速度。那麼我能夠把這些資源複製一份放到距離用戶最近的機房呀。當你請求資源時,山東這臺服務器低頭一看,這個資源我存了,何況離得這麼近響應速度那是槓槓的。若是山東這臺服務器沒有存你要的資源,它就會向杭州的根服務器要資源。此刻, 山東的這臺服務器就扮演着 CND
的角色。
CDN的兩個核心點就是 緩存
和回源
。緩存就至關於把根服務器的資源複製一份放到山東的機房中。而回源就是 山東機房發現沒有你要的資源,它就向根服務器或者上級服務器去要資源。
根服務器也就是業務服務器,須要對業務進行大量的計算。而CDN服務器能夠理解爲一個 倉庫
,只負責存放和轉運一些東西,特別是靜態的資源。如 js、css、image等。
前端性能優化網絡篇咱們分別從HTTP請求優化
和 減小HTTP請求次數
入手。實踐了 webpack調優、Gzip壓縮、前端圖片選型、瀏覽器緩存、本地存儲、CDN的緩存等幾方面入手。