【前端優化】常見前端性能優化

資源壓縮 減小HTTP請求

靜態資源壓縮

  • html:壓縮空格、換行、註釋等字符 Webapack — html-webpack-plugin
  • css:無效代碼刪除,語義合併(相一樣式代碼) Webpack css-loader
  • js:無效字符刪除、剔除註釋代碼語義的縮減和優化 Webpack — UglifyJSPlugin
  • 圖片優化方案:css

    • 雪碧圖
    • 小文件 使用base64 webpack base64-inline-loader
    • 圖片壓縮網站
    • svg

資源合併

  • 弊端:html

    • 首屏渲染問題,合併文件太大,形成慢。
    • 緩存失效問題 標記 md5戳 只要有一個變更 則失效 a,b,c三個js合併
  • 規則:公共庫合併,不一樣頁面的各自合併。異步加載組件,不一樣頁面單獨打包,監聽路由變化,自動下載
  • 實現:gulp插件梳理工做流/webpack配置loader和plugin

非核心代碼異步加載

正常網頁的加載流程:java

  1. 瀏覽器一邊下載 HTML 網頁,一邊開始解析。也就是說,不等到下載完,就開始解析。
  2. 解析過程當中,瀏覽器發現<script>元素,就暫停解析,把網頁渲染的控制權轉交給 JavaScript 引擎。
  3. 若是<script>元素引用了外部腳本,就下載該腳本再執行,不然就直接執行代碼。
  4. JavaScript 引擎執行完畢,控制權交還渲染引擎,恢復解析 HTML 網頁。

上述加載方式爲同步加載,會阻塞瀏覽器的解析html文檔。故而咱們常將script元素放置於body的底部webpack

三種實現方式:動態腳本、async、deferweb

動態腳本

動態建立script標籤gulp

var scriptEle = document.createElement("script");
scriptEle.type = "text/javasctipt";
scriptEle.async = true;
scriptEle.src = "http://xxxxxxx";
var x = document.getElementsByTagName("head")[0];
x.insertBefore(scriptEle, x.firstChild);

async

async屬性和defer屬性相似,也是會開啓一個線程去下載js文件,但和defer不一樣的時,它會在下載完成後馬上執行,而不是會等到DOM加載完成以後再執行,因此仍是有可能會形成阻塞。後端

且不會按照順序執行,哪一個js文件先下載完就先執行哪一個瀏覽器

對於內聯腳本無做用 (即沒有src屬性的腳本)。緩存

defer

當瀏覽器遇到帶有defer屬性的<script>標籤時,再開啓一個線程去下載js文件,同時繼續解析HTML文檔,等等HTML所有解析完畢DOM加載完成以後,再按照出現順序依次執行加載好的js文件。服務器

對於內聯腳本無做用 (即沒有src屬性的腳本)。

使用場景

通常來講,是看腳本之間是否有依賴關係,有依賴的話應當要保證執行順序,應當使用defer沒有依賴的話使用async,同時使用的話defer失效。要注意的是二者都不該該使用document.write,這個致使整個頁面被清除。

利用瀏覽器緩存

https://juejin.im/post/5c4179...

優勢:

  • 減小了冗餘的數據傳輸,節省網費
  • 減小服務器的負擔,提高網站性能
  • 加快了客戶端加載網頁的速度

瀏覽器緩存分爲強緩存和協商緩存

強緩存

若是資源沒過時,就取緩存,若是過時了,則請求服務器。

  • cache-control:max-age = xxx

    聲明該資源在加載後的xxx秒內都直接使用緩存 使用的是相對時間 即加載文件本機的時間

    • Cache-Control 的幾個取值含義:

      • private:僅瀏覽器能夠緩存
      • public:瀏覽器和代理服務器均可以緩存
      • max-age=xxx:過時時間
      • no-cache:不進行強緩存
      • no-store:不強緩存,也不協商緩存
    • 規則能夠同時多個 cache-control:public,max-age=0
  • expires: 絕對時間,服務器基於本身的時間返回一個文件過時時間

    若是在Cache-Control響應頭設置了 "max-age" 或者 "s-max-age" 指令,那麼 Expires 頭會被忽略。

強緩存步驟

  1. 第一次請求 a.js ,緩存表中沒該信息,直接請求後端服務器。
  2. 後端服務器返回了 a.js ,且 http response header 中 cache-control 爲 max-age=xxxx,因此是強緩存規則,存入緩存表中。
  3. 第二次請求 a.js ,緩存表中是 max-age, 那麼命中強緩存,而後判斷是否過時,若是沒過時,直接讀緩存的a.js,若是過時了,則執行協商緩存的步驟了。

協商緩存

觸發條件

  1. Cache-Control 的值爲 no-cache (不強緩存)
  2. 或者 max-age 過時了 (強緩存,但總有過時的時候)

也就是說,無論怎樣,均可能最後要進行協商緩存(no-store除外)

ETag:每一個文件有一個,改動文件了就變了,能夠看似md5

Last-Modified:文件的修改時間

每次http返回來 responseheader 中的 ETag和 Last-Modified,在下次請求時在 requestheader 就把這兩個帶上(可是名字變了ETag-->If-None-Match,Last-Modified-->If-Modified-Since ),服務端把你帶過來的標識,資源目前的標識,進行對比,而後判斷資源是否更改了。

協商緩存步驟總結

  1. 請求資源時,把用戶本地該資源的 ETag 同時帶到服務端,服務端和最新資源作對比。
  2. 若是資源沒更改,返回304,瀏覽器讀取本地緩存。
  3. 若是資源有更改,返回200,返回最新的資源。

DNS預解析

預解析的實現:

  1. 用meta信息來告知瀏覽器, 當前頁面要作DNS預解析:

    <meta http-equiv="x-dns-prefetch-control" content="on" />
  2. 在頁面header中使用link標籤來強制對DNS預解析:

    <link rel="dns-prefetch" href="http://bdimg.share.baidu.com" />

注:dns-prefetch需慎用,多頁面重複DNS預解析會增長重複DNS查詢次數。

若是須要禁止隱式的 DNS Prefetch,可使用如下的標籤:

<meta http-equiv="x-dns-prefetch-control" content="off">

在瀏覽器中a標籤默認打開DNS預解析,可是在HTTPS中默認關閉

CDN 內容分發網絡

img

網絡請求的過程走最近的網絡環境,解決網絡擁堵。

相關文章
相關標籤/搜索