国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Service Worker學(xué)習(xí)與實(shí)踐(一)——離線緩存

xiaochao / 1857人閱讀

摘要:的本質(zhì)是一個(gè),它獨(dú)立于主線程,因此它不能直接訪問,也不能直接訪問對(duì)象,但是,可以訪問對(duì)象,也可以通過消息傳遞的方式與主線程進(jìn)行通信。的最佳用法其實(shí)就是配合做離線緩存。

什么是Service Worker

Service Worker本質(zhì)上充當(dāng)Web應(yīng)用程序與瀏覽器之間的代理服務(wù)器,也可以在網(wǎng)絡(luò)可用時(shí)作為瀏覽器和網(wǎng)絡(luò)間的代理。它們旨在(除其他之外)使得能夠創(chuàng)建有效的離線體驗(yàn),攔截網(wǎng)絡(luò)請(qǐng)求并基于網(wǎng)絡(luò)是否可用以及更新的資源是否駐留在服務(wù)器上來采取適當(dāng)?shù)膭?dòng)作。他們還允許訪問推送通知和后臺(tái)同步API

Service Worker的本質(zhì)是一個(gè)Web Worker,它獨(dú)立于JavaScript主線程,因此它不能直接訪問DOM,也不能直接訪問window對(duì)象,但是,Service Worker可以訪問navigator對(duì)象,也可以通過消息傳遞的方式(postMessage)與JavaScript主線程進(jìn)行通信。

Service Worker是一個(gè)網(wǎng)絡(luò)代理,它可以控制Web頁面的所有網(wǎng)絡(luò)請(qǐng)求。

Service Worker具有自身的生命周期,使用好Service Worker的關(guān)鍵是靈活控制其生命周期。

Service Worker的作用

用于瀏覽器緩存

實(shí)現(xiàn)離線Web APP

消息推送

Service Worker兼容性

Service Worker是現(xiàn)代瀏覽器的一個(gè)高級(jí)特性,它依賴于fetch APICache StoragePromise等,其中,Cache提供了Request / Response對(duì)象對(duì)的存儲(chǔ)機(jī)制,Cache Storage存儲(chǔ)多個(gè)Cache

示例

在了解Service Worker的原理之前,先來看一段Service Worker的示例:

self.importScripts("./serviceworker-cache-polyfill.js");

var urlsToCache = [
  "/",
  "/index.js",
  "/style.css",
  "/favicon.ico",
];

var CACHE_NAME = "counterxing";

self.addEventListener("install", function(event) {
  self.skipWaiting();
  event.waitUntil(
    caches.open(CACHE_NAME)
    .then(function(cache) {
      return cache.addAll(urlsToCache);
    })
  );
});

self.addEventListener("fetch", function(event) {
  event.respondWith(
    caches.match(event.request)
    .then(function(response) {
      if (response) {
        return response;
      }
      return fetch(event.request);
    })
  );
});


self.addEventListener("activate", function(event) {
  var cacheWhitelist = ["counterxing"];

  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.map(function(cacheName) {
          if (cacheWhitelist.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

下面開始逐段逐段地分析,揭開Service Worker的神秘面紗:

polyfill

首先看第一行:self.importScripts("./serviceworker-cache-polyfill.js");,這里引入了Cache API的一個(gè)polyfill,這個(gè)polyfill支持使得在較低版本的瀏覽器下也可以使用Cache Storage API。想要實(shí)現(xiàn)Service Worker的功能,一般都需要搭配Cache API代理網(wǎng)絡(luò)請(qǐng)求到緩存中。

Service Worker線程中,使用importScripts引入polyfill腳本,目的是對(duì)低版本瀏覽器的兼容。

Cache Resources List And Cache Name

之后,使用一個(gè)urlsToCache列表來聲明需要緩存的靜態(tài)資源,再使用一個(gè)變量CACHE_NAME來確定當(dāng)前緩存的Cache Storage Name,這里可以理解成Cache Storage是一個(gè)DB,而CACHE_NAME則是DB名:

var urlsToCache = [
  "/",
  "/index.js",
  "/style.css",
  "/favicon.ico",
];

var CACHE_NAME = "counterxing";
Lifecycle

Service Worker獨(dú)立于瀏覽器JavaScript主線程,有它自己獨(dú)立的生命周期。

如果需要在網(wǎng)站上安裝Service Worker,則需要在JavaScript主線程中使用以下代碼引入Service Worker

if ("serviceWorker" in navigator) {
  navigator.serviceWorker.register("/sw.js").then(function(registration) {
    console.log("成功安裝", registration.scope);
  }).catch(function(err) {
    console.log(err);
  });
}

此處,一定要注意sw.js文件的路徑,在我的示例中,處于當(dāng)前域根目錄下,這意味著,Service Worker和網(wǎng)站是同源的,可以為當(dāng)前網(wǎng)站的所有請(qǐng)求做代理,如果Service Worker被注冊(cè)到/imaging/sw.js下,那只能代理/imaging下的網(wǎng)絡(luò)請(qǐng)求。

可以使用Chrome控制臺(tái),查看當(dāng)前頁面的Service Worker情況:

安裝完成后,Service Worker會(huì)經(jīng)歷以下生命周期:

下載(download

安裝(install

激活(activate

用戶首次訪問Service Worker控制的網(wǎng)站或頁面時(shí),Service Worker會(huì)立刻被下載。之后至少每24小時(shí)它會(huì)被下載一次。它可能被更頻繁地下載,不過每24小時(shí)一定會(huì)被下載一次,以避免不良腳本長時(shí)間生效。

在下載完成后,開始安裝Service Worker,在安裝階段,通常需要緩存一些我們預(yù)先聲明的靜態(tài)資源,在我們的示例中,通過urlsToCache預(yù)先聲明。

在安裝完成后,會(huì)開始進(jìn)行激活,瀏覽器會(huì)嘗試下載Service Worker腳本文件,下載成功后,會(huì)與前一次已緩存的Service Worker腳本文件做對(duì)比,如果與前一次的Service Worker腳本文件不同,證明Service Worker已經(jīng)更新,會(huì)觸發(fā)activate事件。完成激活。

如圖所示,為Service Worker大致的生命周期:

install

在安裝完成后,嘗試緩存一些靜態(tài)資源:

self.addEventListener("install", function(event) {
  self.skipWaiting();
  event.waitUntil(
    caches.open(CACHE_NAME)
    .then(function(cache) {
      return cache.addAll(urlsToCache);
    })
  );
});

首先,self.skipWaiting()執(zhí)行,告知瀏覽器直接跳過等待階段,淘汰過期的sw.jsService Worker腳本,直接開始嘗試激活新的Service Worker

然后使用caches.open打開一個(gè)Cache,打開后,通過cache.addAll嘗試緩存我們預(yù)先聲明的靜態(tài)文件。

監(jiān)聽fetch,代理網(wǎng)絡(luò)請(qǐng)求

頁面的所有網(wǎng)絡(luò)請(qǐng)求,都會(huì)通過Service Workerfetch事件觸發(fā),Service Worker通過caches.match嘗試從Cache中查找緩存,緩存如果命中,則直接返回緩存中的response,否則,創(chuàng)建一個(gè)真實(shí)的網(wǎng)絡(luò)請(qǐng)求。

self.addEventListener("fetch", function(event) {
  event.respondWith(
    caches.match(event.request)
    .then(function(response) {
      if (response) {
        return response;
      }
      return fetch(event.request);
    })
  );
});

如果我們需要在請(qǐng)求過程中,再向Cache Storage中添加新的緩存,可以通過cache.put方法添加,看以下例子:

self.addEventListener("fetch", function(event) {
  event.respondWith(
    caches.match(event.request)
    .then(function(response) {
      // 緩存命中
      if (response) {
        return response;
      }

      // 注意,這里必須使用clone方法克隆這個(gè)請(qǐng)求
      // 原因是response是一個(gè)Stream,為了讓瀏覽器跟緩存都使用這個(gè)response
      // 必須克隆這個(gè)response,一份到瀏覽器,一份到緩存中緩存。
      // 只能被消費(fèi)一次,想要再次消費(fèi),必須clone一次
      var fetchRequest = event.request.clone();

      return fetch(fetchRequest).then(
        function(response) {
          // 必須是有效請(qǐng)求,必須是同源響應(yīng),第三方的請(qǐng)求,因?yàn)椴豢煽兀詈貌灰彺?          if (!response || response.status !== 200 || response.type !== "basic") {
            return response;
          }

          // 消費(fèi)過一次,又需要再克隆一次
          var responseToCache = response.clone();
          caches.open(CACHE_NAME)
            .then(function(cache) {
              cache.put(event.request, responseToCache);
            });
          return response;
        }
      );
    })
  );
});
在項(xiàng)目中,一定要注意控制緩存,接口請(qǐng)求一般是不推薦緩存的。所以在我自己的項(xiàng)目中,并沒有在這里做動(dòng)態(tài)的緩存方案。
activate

Service Worker總有需要更新的一天,隨著版本迭代,某一天,我們需要把新版本的功能發(fā)布上線,此時(shí)需要淘汰掉舊的緩存,舊的Service WorkerCache Storage如何淘汰呢?

self.addEventListener("activate", function(event) {
  var cacheWhitelist = ["counterxing"];

  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.map(function(cacheName) {
          if (cacheWhitelist.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

首先有一個(gè)白名單,白名單中的Cache是不被淘汰的。

之后通過caches.keys()拿到所有的Cache Storage,把不在白名單中的Cache淘汰。

淘汰使用caches.delete()方法。它接收cacheName作為參數(shù),刪除該cacheName所有緩存。

sw-precache-webpack-plugin

sw-precache-webpack-plugin是一個(gè)webpack plugin,可以通過配置的方式在webpack打包時(shí)生成我們想要的sw.jsService Worker腳本。

一個(gè)最簡(jiǎn)單的配置如下:

var path = require("path");
var SWPrecacheWebpackPlugin = require("sw-precache-webpack-plugin");

const PUBLIC_PATH = "https://www.my-project-name.com/";  // webpack needs the trailing slash for output.publicPath

module.exports = {

  entry: {
    main: path.resolve(__dirname, "src/index"),
  },

  output: {
    path: path.resolve(__dirname, "src/bundles/"),
    filename: "[name]-[hash].js",
    publicPath: PUBLIC_PATH,
  },

  plugins: [
    new SWPrecacheWebpackPlugin(
      {
        cacheId: "my-project-name",
        dontCacheBustUrlsMatching: /.w{8}./,
        filename: "service-worker.js",
        minify: true,
        navigateFallback: PUBLIC_PATH + "index.html",
        staticFileGlobsIgnorePatterns: [/.map$/, /asset-manifest.json$/],
      }
    ),
  ],
}

在執(zhí)行webpack打包后,會(huì)生成一個(gè)名為service-worker.js文件,用于緩存webpack打包后的靜態(tài)文件。

一個(gè)最簡(jiǎn)單的示例。

Service Worker Cache VS Http Cache

對(duì)比起Http Header緩存,Service Worker配合Cache Storage也有自己的優(yōu)勢(shì):

緩存與更新并存:每次更新版本,借助Service Worker可以立馬使用緩存返回,但與此同時(shí)可以發(fā)起請(qǐng)求,校驗(yàn)是否有新版本更新。

無侵入式:hash值實(shí)在是太難看了。

不易被沖掉:Http緩存容易被沖掉,也容易過期,而Cache Storage則不容易被沖掉。也沒有過期時(shí)間的說法。

離線:借助Service Worker可以實(shí)現(xiàn)離線訪問應(yīng)用。

但是缺點(diǎn)是,由于Service Worker依賴于fetch API、依賴于PromiseCache Storage等,兼容性不太好。

后話

本文只是簡(jiǎn)單總結(jié)了Service Worker的基本使用和使用Service Worker做客戶端緩存的簡(jiǎn)單方式,然而,Service Worker的作用遠(yuǎn)不止于此,例如:借助Service Worker做離線應(yīng)用、用于做網(wǎng)絡(luò)應(yīng)用的推送(可參考push-notifications)等。

甚至可以借助Service Worker,對(duì)接口進(jìn)行緩存,在我所在的項(xiàng)目中,其實(shí)并不會(huì)做的這么復(fù)雜。不過做接口緩存的好處是支持離線訪問,對(duì)離線狀態(tài)下也能正常訪問我們的Web應(yīng)用。

Cache StorageService Worker總是分不開的。Service Worker的最佳用法其實(shí)就是配合Cache Storage做離線緩存。借助于Service Worker,可以輕松實(shí)現(xiàn)對(duì)網(wǎng)絡(luò)請(qǐng)求的控制,對(duì)于不同的網(wǎng)絡(luò)請(qǐng)求,采取不同的策略。例如對(duì)于Cache的策略,其實(shí)也是存在多種情況。例如可以優(yōu)先使用網(wǎng)絡(luò)請(qǐng)求,在網(wǎng)絡(luò)請(qǐng)求失敗時(shí)再使用緩存、亦可以同時(shí)使用緩存和網(wǎng)絡(luò)請(qǐng)求,一方面檢查請(qǐng)求,一方面有檢查緩存,然后看兩個(gè)誰快,就用誰。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/97897.html

相關(guān)文章

  • 【PWA學(xué)習(xí)實(shí)踐】(3) 讓你的WebApp離線可用

    摘要:學(xué)習(xí)與實(shí)踐系列文章已整理至學(xué)習(xí)手冊(cè),文字內(nèi)容已同步至。本文是學(xué)習(xí)與實(shí)踐系列的第三篇文章。引言其中一個(gè)令人著迷的能力就是離線可用。但是,如果你注意到文章開頭的圖片就會(huì)發(fā)現(xiàn),離線時(shí)我們不僅可以訪問,還可以使用搜索功能。 《PWA學(xué)習(xí)與實(shí)踐》系列文章已整理至gitbook - PWA學(xué)習(xí)手冊(cè),文字內(nèi)容已同步至learning-pwa-ebook。轉(zhuǎn)載請(qǐng)注明作者與出處。 本文是《PWA學(xué)習(xí)與實(shí)...

    since1986 評(píng)論0 收藏0
  • Service Worker學(xué)習(xí)實(shí)踐(二)——PWA簡(jiǎn)介

    摘要:簡(jiǎn)稱,是提升的體驗(yàn)的一種新方法,能給用戶原生應(yīng)用的體驗(yàn)。當(dāng)網(wǎng)站以這種方式啟動(dòng)時(shí)它具有唯一的圖標(biāo)和名稱,以便用戶將其與其他網(wǎng)站區(qū)分開來。表示啟動(dòng)時(shí)的方向,橫屏豎屏等,具體參數(shù)值可參考文檔。下一篇文章中,主要講述在實(shí)踐中的重要能力。 這周,Chrome 70正式版本發(fā)布,Progressive Web Apps(PWA)已經(jīng)正式支持到Windows 10平臺(tái),然而,早在前幾個(gè)版本之前,Ch...

    KavenFan 評(píng)論0 收藏0
  • 【PWA學(xué)習(xí)實(shí)踐】(5)在Web中進(jìn)行服務(wù)端消息推送

    摘要:本文是學(xué)習(xí)與實(shí)踐系列的第五篇文章。實(shí)際上,消息推送與提醒是兩個(gè)功能和。在這一篇里,我們先來學(xué)習(xí)如何使用進(jìn)行消息推送。而當(dāng)服務(wù)端要推送消息時(shí),會(huì)使用私鑰對(duì)發(fā)送的數(shù)據(jù)進(jìn)行數(shù)字簽名,并根據(jù)數(shù)字簽名生成一個(gè)叫請(qǐng)求頭。 《PWA學(xué)習(xí)與實(shí)踐》系列文章已整理至gitbook - PWA學(xué)習(xí)手冊(cè),文字內(nèi)容已同步至learning-pwa-ebook。轉(zhuǎn)載請(qǐng)注明作者與出處。 本文是《PWA學(xué)習(xí)與實(shí)踐》系...

    suemi 評(píng)論0 收藏0
  • [譯]介紹下漸進(jìn)式 Web App(離線) - Part 1

    摘要:基本上是使用現(xiàn)代技術(shù)構(gòu)建的網(wǎng)站但是體驗(yàn)上卻像一個(gè)移動(dòng),在年,谷歌工程師和創(chuàng)造了。此后谷歌就一直致力于讓能給用戶像原生一般的體驗(yàn)。檢查谷歌瀏覽器的和現(xiàn)在重載你的并且打開,到選項(xiàng)去查看面板,確保這個(gè)選項(xiàng)是勾選的。 Web開發(fā)多年來有了顯著的發(fā)展。它允許開發(fā)人員部署網(wǎng)站或Web應(yīng)用程序并在數(shù)分鐘內(nèi)為全球數(shù)百萬人服務(wù)。只需一個(gè)瀏覽器,用戶可以輸入U(xiǎn)RL就可以訪問Web應(yīng)用程序了。隨著 Prog...

    Wildcard 評(píng)論0 收藏0
  • [譯]介紹下漸進(jìn)式 Web App(離線) - Part 1

    摘要:基本上是使用現(xiàn)代技術(shù)構(gòu)建的網(wǎng)站但是體驗(yàn)上卻像一個(gè)移動(dòng),在年,谷歌工程師和創(chuàng)造了。此后谷歌就一直致力于讓能給用戶像原生一般的體驗(yàn)。檢查谷歌瀏覽器的和現(xiàn)在重載你的并且打開,到選項(xiàng)去查看面板,確保這個(gè)選項(xiàng)是勾選的。 Web開發(fā)多年來有了顯著的發(fā)展。它允許開發(fā)人員部署網(wǎng)站或Web應(yīng)用程序并在數(shù)分鐘內(nèi)為全球數(shù)百萬人服務(wù)。只需一個(gè)瀏覽器,用戶可以輸入U(xiǎn)RL就可以訪問Web應(yīng)用程序了。隨著 Prog...

    gaara 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

xiaochao

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<