前端经常使用的缓存技术

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

相关文章
相关标签/搜索