前端頁面性能優化的幾種方式

来源:https://www.cnblogs.com/smyhvae/archive/2018/03/12/8550195.html
-Advertisement-
Play Games

本文最初發表於 "博客園" ,併在 "GitHub" 上持續更新 前端的系列文章 。歡迎在GitHub上關註我,一起入門和進階前端。 以下是正文。 前言 提升頁面性能優化的常見方式: 1、資源壓縮合併,減少http請求 2、 非核心代碼非同步載入 非同步載入的方式 非同步載入的區別 3、利用瀏覽器緩存 緩 ...


本文最初發表於博客園,併在GitHub上持續更新前端的系列文章。歡迎在GitHub上關註我,一起入門和進階前端。

以下是正文。

前言

提升頁面性能優化的常見方式:

  • 1、資源壓縮合併,減少http請求

  • 2、非核心代碼非同步載入 --> 非同步載入的方式 --> 非同步載入的區別

  • 3、利用瀏覽器緩存 --> 緩存的分類 --> 緩存的原理

緩存是所有性能優化的方式中最重要的一步【重要】

有的人可能會回答local storage 和session storage,其實不是這個。瀏覽器緩存和存儲不是一回事。

  • 4、使用CDN

瀏覽器第一次打開頁面時,緩存是起不了作用的。這個時候,CDN就上場了。

  • 5、DNS預解析

一、資源壓縮合併,減少http請求

  • 合併圖片(css sprites)、CSS和JS文件合併、CSS和JS文件壓縮

  • 圖片較多的頁面也可以使用 lazyLoad 等技術進行優化。

  • 精靈圖等

二、非核心代碼非同步載入

非同步載入的方式:(這裡不說框架,只說原理)

  • 動態腳本載入

  • defer

  • async

動態腳本載入

使用document.createElement創建一個script標簽,即document.createElement('script'),然後把這個標簽載入到body上面去。

參考鏈接:

defer

通過非同步的方式載入defer1.js文件:

    <script src="./defer1.js" defer></script>

async

HTmL5新增特性。

通過非同步的方式載入async1.js文件:

    <script src="./async1.js" async></script>

defer和async的區別

  • defer:在HTML解析完之後才會執行。如果是多個,則按照載入的順序依次執行。

  • async:在載入完之後立即執行。如果是多個,執行順序和載入順序無關。

代碼舉例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <!--通過非同步的方式引入兩個外部的js文件-->
    <script src="./defer1.js" defer></script>
    <script src="./defer2.js" defer></script>
</head>

<body>
<script>
    console.log('同步任務');
</script>
</body>

</html>

上方列印的結果是:

同步任務
defer1
defer2

因為defer的載入是有順序的,所以兩個引入defer文件按順序執行。如果把引入的文件改為async的方式載入,列印的結果可能是:

同步任務
async2
async1

參考鏈接:

三、利用瀏覽器緩存

緩存:資源文件(比如圖片)在本地存有副本,瀏覽器下次請求的時候,可能直接從本地磁碟里讀取,而不會重新請求圖片的url。

緩存分為:

  • 強緩存

  • 協商緩存

強緩存

強緩存:不用請求伺服器,直接使用本地的緩存。

強緩存是利用 http 響應頭中的ExpiresCache-Control實現的。【重要】

瀏覽器第一次請求一個資源時,伺服器在返回該資源的同時,會把上面這兩個屬性放在response header中。比如:

註意:這兩個response header屬性可以只啟用一個,也可以同時啟用。當response header中,Expires和Cache-Control同時存在時,Cache-Control的優先順序高於Expires

下麵講一下二者的區別。

1、Expires:伺服器返回的絕對時間

是較老的強緩存管理 response header。瀏覽器再次請求這個資源時,先從緩存中尋找,找到這個資源後,拿出它的Expires跟當前的請求時間比較,如果請求時間在Expires的時間之前,就能命中緩存,否則就不行。

如果緩存沒有命中,瀏覽器直接從伺服器請求資源時,Expires Header在重新請求的時候會被更新。

缺點:

由於Expires是伺服器返回的一個絕對時間,存在的問題是:伺服器的事件和客戶端的事件可能不一致。在伺服器時間與客戶端時間相差較大時,緩存管理容易出現問題,比如隨意修改客戶端時間,就能影響緩存命中的結果。所以,在http1.1中,提出了一個新的response header,就是Cache-Control。

2、Cache-Control:伺服器返回的相對時間

http1.1中新增的 response header。瀏覽器第一次請求資源之後,在接下來的相對時間之內,都可以利用本地緩存。超出這個時間之後,則不能命中緩存。重新請求時,Cache-Control會被更新。

協商緩存

協商緩存:瀏覽器發現本地有資源的副本,但是不太確定要不要使用,於是去問問伺服器。

當瀏覽器對某個資源的請求沒有命中強緩存(也就是說超出時間了),就會發一個請求到伺服器,驗證協商緩存是否命中。

協商緩存是利用的是兩對Header:

  • 第一對:Last-ModifiedIf-Modified-Since

  • 第二對:ETagIf-None-Match

1、Last-ModifiedIf-Modified-Since。過程如下:

(1)瀏覽器第一次請求一個資源,伺服器在返回這個資源的同時,會加上Last-Modified這個 response header,這個header表示這該資源在伺服器上的最後修改時間:

(2)瀏覽器再次請求這個資源時,會加上If-Modified-Since這個 request header,這個header的值就是上一次返回的Last-Modified的值:

(3)伺服器收到第二次請求時,會比對瀏覽器傳過來的If-Modified-Since和資源在伺服器上的最後修改時間Last-Modified,判斷資源是否有變化。如果沒有變化則返回304 Not Modified,但不返回資源內容(此時,伺服器不會返回 Last-Modified 這個 response header);如果有變化,就正常返回資源內容(繼續重覆整個流程)。這是伺服器返回304時的response header:

(4)瀏覽器如果收到304的響應,就會從緩存中載入資源。

缺點:

Last-ModifiedIf-Modified-Since一般來說都是非常可靠的,但有可能出現的問題是:伺服器上的資源變化了,但是最後的修改時間卻沒有變化。這一對header就無法解決這種情況。於是,下麵這一對header出場了。

2、ETagIf-None-Match。過程如下:

(1)瀏覽器第一次請求一個資源,伺服器在返回這個資源的同時,會加上ETag這個 response header,這個header是伺服器根據當前請求的資源生成的唯一標識。這個唯一標識是一個字元串,只要資源有變化這個串就不同,跟最後修改時間無關,所以也就很好地補充了Last-Modified的不足。如下:

(2)瀏覽器再次請求這個資源時,會加上If-None-Match這個 request header,這個header的值就是上一次返回的ETag的值:

3)伺服器第二次請求時,會對比瀏覽器傳過來的If-None-Match和伺服器重新生成的一個新的ETag,判斷資源是否有變化。如果沒有變化則返回304 Not Modified,但不返回資源內容(此時,由於ETag重新生成過,response header中還會把這個ETag返回,即使這個ETag並無變化)。如果有變化,就正常返回資源內容(繼續重覆整個流程)。這是伺服器返回304時的response header:

(4)瀏覽器如果收到304的響應,就會從緩存中載入資源。

提示:如果面試官問你:與瀏覽器緩存相關的http header有哪些?你能寫出來嗎?這是一個亮點。

參考鏈接:

四、使用CDN

怎麼最快地讓用戶請求資源。一方面是讓資源在傳輸的過程中變小,另外就是CDN。

要註意,瀏覽器第一次打開頁面的時候,瀏覽器緩存是起不了作任何用的,使用CDN,效果就很明顯。

五、DNS預解析(dns-prefetch)

通過 DNS 預解析來告訴瀏覽器未來我們可能從某個特定的 URL 獲取資源,當瀏覽器真正使用到該域中的某個資源時就可以儘快地完成 DNS 解析。

第一步:打開或關閉DNS預解析

你可以通過在伺服器端發送 X-DNS-Prefetch-Control 報頭。或是在文檔中使用值為 http-equiv 的meta標簽:

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

需要說明的是,在一些高級瀏覽器中,頁面中所有的超鏈接(<a>標簽),預設打開了DNS預解析。但是,如果頁面中採用的https協議,很多瀏覽器是預設關閉了超鏈接的DNS預解析。如果加了上面這行代碼,則表明強制打開瀏覽器的預解析。(如果你能在面試中把這句話說出來,則一定是你出彩的地方)

第二步:對指定的功能變數名稱進行DNS預解析

如果我們將來可能從 smyhvae.com 獲取圖片或音頻資源,那麼可以在文檔頂部的 標簽中加入以下內容:

    <link rel="dns-prefetch" href="http://www.smyhvae.com/">

當我們從該 URL 請求一個資源時,就不再需要等待 DNS 解析的過程。該技術對使用第三方資源特別有用。

參考鏈接:

我的公眾號

想學習代碼之外的軟技能?不妨關註我的微信公眾號:生命團隊(id:vitateam)。

掃一掃,你將發現另一個全新的世界,而這將是一場美麗的意外:


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 同源策略 首先基於安全的原因,瀏覽器是存在同源策略這個機制的,同源策略阻止從一個域載入的腳本去獲取另一個域上的文檔屬性。也就是說,受到請求的 URL 的域必須與當前 Web 頁面的域相同。這意味著瀏覽器隔離來自不同源的內容,以防止它們之間的操作。 js跨域是指通過js在不同的域之間進行數據傳輸或通信 ...
  • Css 層疊樣式表 美化頁面的小工具 分類: 內聯 (行內)在標簽內部以屬性的形式呈現,屬性名style 內嵌 head標簽內以標簽形式呈現,標簽名style 外部 head標簽內 加link標簽 引入外部文件 *.css <link rel="stylesheet" type="text/css" ...
  • 閱讀目錄 介紹 CSS 的基本語法格式 介紹 基礎選擇器 介紹 組合選擇器 介紹 偽選擇器 介紹 其他 一、CSS 的基本語法格式 代碼: 運行結果為: 段落是紅色的。 註意: 上面是一個簡單的演示示例 重點看 <style> 元素 CSS 語法的一般形式是 selector{ property: ...
  • 用戶註冊頁面以及js特效:1、表單聯動;2、正則表達式驗證。 一、html和css代碼(用table進行佈局,div也可以達到一樣的效果) 1 <html> 2 <head> 3 <meta charset="utf-8"> 4 <style> 5 table{ 6 border-collapse: ...
  • 彈窗製作: 優化 css用模板字元串(裡面需要加一個style 標簽)插入的 ${'head'}.append(css) append()插入末尾prepend ()在 p 元素的開頭插入內容 $(".btn1").click(function(){ $("p").prepend("<b>Hello ...
  • 一,js的引入方式 1,script標簽內寫代碼 2,引入額外的js文件 二,js語言規範 1,註釋 2,結束符 JavaScript中的語句要以分號(;)為結束符。 三,js語言基礎 1,變數聲明 註意: 變數名是區分大小寫的。 推薦使用駝峰式命名規則。 保留字不能用做變數名。 四,Js數據類型 ...
  • 寫在前面的話:之前一直以為定時器的返回值是Object類型,所以timer初始化也是寫null,今天發現返回值是number,進而發覺這個返回值代表的是定時器的索引,指代這是第幾個定時器 個人覺得只用set/clearInterval方法就好,他可以實現另外的一個方法的所有功能 啟用定時器的方法有兩 ...
  • 一,css介紹 CSS(Cascading Style Sheet,層疊樣式表)定義如何顯示HTML元素。 當瀏覽器讀到一個樣式表,它就會按照這個樣式表來對文檔進行格式化(渲染)。 二,CSS語法 1,每個CSS樣式由兩個組成部分:選擇器和聲明。聲明又包括屬性和屬性值。每個聲明之後用分號結束。 2, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...