前端經常使用的緩存技術

CDN緩存

CDN(Content DeliveryNetwork),即內容分發網絡。CDN是構建在網絡之上的內容分發網絡,依靠部署在各地的邊緣服務器,經過中心平臺的負載均衡、內容分發、調度等功能模塊,使用戶就近獲取所需內容,下降網絡擁塞,提升用戶訪問響應速度和命中率javascript

具體是什麼意思呢? 當咱們使用CDN時,CDN會優先調度離咱們最近的邊緣服務器並檢測是否有該請求的緩存數據,若是有則返回緩存數據;若是沒有則向中心服務器請求並返回。css

優勢:html

  1. 減小帶寬的佔用,減輕網絡擁堵,提升訪問速度
  2. 減輕本地服務器負擔

DNS緩存

DNS(Domin Name System)是域名和IP相互映射的分佈式數據庫,可將域名解析成供計算機識別的IP地址html5

DNS查詢耗時大約20ms,在DNS查詢過程當中,瀏覽器不進行任何活動,會致使瀏覽器出現空白頁;若是DNS查詢不少,會致使網頁加載性能受到影響java

DNS緩存機制: 當首次訪問一個域名,經過DNS解析獲取其IP,並將域名及對應的IP緩存下來,當下次訪問該域名時,則再也不進行DNS查詢,直接使用緩存下來的IP數據庫

緩存時間: 不一樣的瀏覽器DNS緩存時間也不一樣,IE默認的DNS緩存時間爲30min,Firfox、Chrome默認的DNS緩存時間爲1min瀏覽器

若域名對應的ip已更改,則須要清除DNS緩存(ipconfig/flushdns)緩存

HTTP緩存

當客戶端第一次完成數據請求後,瀏覽器會緩存本次請求的數據,當下次執行相同請求,則直接在緩存數據庫中返回;但HTTP緩存有多種規則,根據是否向服務器發送請求分爲 「強制緩存」「對比緩存」 兩種bash

強制緩存

當客戶端發送請求時,若瀏覽器中有該請求的緩存數據,則直接返回緩存數據;服務器

若瀏覽器中未有本次請求的緩存數據或緩存數據過時,則本次請求會抵達服務器去請求數據;

那麼如何去判斷緩存數據是否已經失效(過時)呢?

當客戶端與服務器完成一次請求後,服務器會在Response Headers 報文中返回緩存規則信息;在Response Body報文中返回響應的數據;緩存規則有 ExpiresCache-Control 兩種

Expires

Expires表示緩存數據的到期時間,若下次請求的日期小於到期時間,則直接從緩存數據中讀取;若大於到期時間,則直接請求服務器

  • 因爲到期時間是有服務器端生成的,這與客戶端的時間會有誤差,因此從HTTP 1.1 版本後此方案由 Cache-Control 代替

Cache-Control

目前HTTP標準的緩存規則,包含「private」、「public」,「max-age=」、「no-cache」、「no-store」

  • private:客戶端能夠緩存
  • public:客戶端和服務端均可以緩存
  • max-age=xxx:緩存的總時長,單位爲秒
  • no-cache:使用對比緩存驗證緩存數據
  • no-store:不適用強制緩存和對比緩存

此例子中,緩存時間爲3153600秒(1年),在1年內請求這條數據,都只會從緩存中返回

對比緩存

瀏覽器完成一次完整請求後,服務器返回數據和緩存規則,客戶端收到並緩存在緩存數據庫中;

對比緩存顧名思義就是每次請求,客戶端都會拿緩存標識去服務器判斷該緩存是否可用,若可用,服務器返回304並通知客戶端從緩存中讀取,若不可用則服務器返回200和最新的數據和緩存規則

緩存標識分爲如下兩種

Last-Modified / If-Modified-Since

服務器返回資源最後一次修改的時間

再次請求時,客戶端在請求頭攜帶If-Modified-Since;服務器拿If-Modified-Since與資源最後修改時間作對比,若大於或等於,則命中對比緩存,返回304,從緩存中讀取;反之,則服務器返回最新的數據和緩存規則,並返回200

Etag / If-None-Match(優先級高於Last-Modified / If-Modified-Since)

第一次請求,瀏覽器返回資源惟一標識(通常都是hash生成的)

服務器存儲着文件的Etag字段,能夠在與每次客戶端傳送If-no-match的字段進行比較。若是相等,則表示未修改,響應304;反之,則表示已修改,響應200狀態碼,返回數據。

Service Worker 離線緩存

Service Worker可以充當網絡代理服務器的功能,能攔截網絡請求(fetch)、離線緩存

  • Service Worker是運行在worker上下文,因此不能訪問DOM
  • 運行在其餘線程中,不會形成擁堵,徹底異步,所以同步API不可以使用
  • 只能在https或本地localhost上運行
  1. 註冊serviceWorker
<!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>serviceWorker</title>
  <script type="text/javascript">
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('./serviceWorker.js', {scope: './'})
        .then(registration => {
          console.log('註冊成功', registration.scope)
        })
        .catch(err => {
          console.log('註冊失敗', err)
        })
    }
  </script>
</head>
<body>
</body>
複製代碼
  1. ServiceWorker.js
let self = this;
// 完成serviceWorker的註冊與緩存文件
self.addEventListener('install', function (event) {
  event.waitUntil(
    caches.open('v1').then(function (cache) {
      return cache.addAll([
        './index.html' //緩存文件
      ])
    })
  )
})

// 監聽攔截http請求,作資源緩存
self.addEventListener('fetch', function (event) {
  event.responseWith(
    // 在緩存中匹配請求
    caches.match(event.request)
      .then(function (response) {
        // 若緩存存在,則直接返回
        if (response) {
          return response
        }
        // 拷貝request副本
        let fetchRequest = event.request.clone()
        // 未命中緩存,發起網絡請求
        return fetch(fetchRequest).then(function (response) {
          // 判斷是否請求成功
          if (!response || response.status != 200 || response.type != 'basic') {
            return response
          }
          // 緩存請求和響應數據
          let fetchResponse = response.clone()
          caches.open('v1').then(function (cache) {
            cache.put(event.request, fetchResponse) 
          })
          // 返回真實的網絡請求數據
          return response
        })
      })
  )
})
複製代碼

mainfest

html5引入的新標準,能夠離線緩存靜態文件

優勢

  • 離線瀏覽
  • 已緩存資源加載速度更快
  • 減輕服務器負載 - 只需從服務器中獲取更新或修改過的資源

步驟

  1. 新建一個後綴爲'manifest.appcache'的文件,文件內容以下
    CACHE MANIFEST // 首次完成請求後進行緩存,離線可訪問
    manifest.css
    
    NETWORK: // 每次請求都須要網絡,不緩存
    network.css
    
    FALLBACK: // 頁面沒法鏈接網絡時顯示的頁面
    404.html
    複製代碼
  2. 在中加入manifest屬性並指定文件所在地址
    <html manifest="manifest.appcache">
    複製代碼

首次訪問,請求靜態文件

再次訪問,manifest.css已被緩存

當離線後,network.css沒法訪問,但仍能從緩存中讀取manifest.css

相關文章
相關標籤/搜索