成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

借助 workbox 將網(wǎng)站升級(jí)成 PWA

shaonbean / 1143人閱讀

摘要:是谷歌近幾年一直在推進(jìn)的應(yīng)用新模型。既然如此,我們最好是站在巨人的肩膀上,這個(gè)巨人就是谷歌。是由谷歌瀏覽器團(tuán)隊(duì)發(fā)布,用來(lái)協(xié)助創(chuàng)建應(yīng)用的庫(kù)。當(dāng)然直接用還是太復(fù)雜了,谷歌還很貼心的發(fā)布了一個(gè)插件,能夠自動(dòng)生成和靜態(tài)資源列表。

PWA(Progressive Web Apps)是谷歌近幾年一直在推進(jìn)的 web 應(yīng)用新模型。PWA 借助 Service Worker 緩存網(wǎng)站的靜態(tài)資源,甚至是網(wǎng)絡(luò)請(qǐng)求,使網(wǎng)站在離線時(shí)也能訪問(wèn)。并且我們能夠?yàn)榫W(wǎng)站指定一個(gè)圖標(biāo)添加在手機(jī)桌面,實(shí)現(xiàn)點(diǎn)擊桌面圖標(biāo)即可訪問(wèn)網(wǎng)站。

Web App Manifest

Web App Manifest 是一個(gè) JSON 文件,它用來(lái)定義網(wǎng)站添加到桌面的圖標(biāo)以及從桌面圖標(biāo)進(jìn)入網(wǎng)站時(shí)的一系列行為,如:?jiǎn)?dòng)樣式,全屏主題等。

先創(chuàng)建 manifest.json

{
  "name": "blog-pwa",
  "short_name": "blog-pwa",
  "icons": [
    {
      "src": "/img/icons/android-chrome-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/img/icons/android-chrome-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "start_url": "/index.html",
  "display": "standalone",
  "background_color": "#000000",
  "theme_color": "#4DBA87"
}

將文件引入:

我們可以從開(kāi)發(fā)者工具上看我們的配置:

icons 屬性定義了添加到桌面的圖標(biāo), display: standalone 表示我們要從桌面全屏啟動(dòng),theme_color": "#4DBA87 是全屏啟動(dòng)時(shí)手機(jī)頂部狀態(tài)欄的背景色,background_color": "#000000 是啟動(dòng)頁(yè)的背景色,啟動(dòng)頁(yè)目前不能定制,默認(rèn)由 background_coloriconname 組合而成。

Web App Manifest很簡(jiǎn)單,只要照著文檔每個(gè)屬性看一遍就行。

Service Worker

Service Worker 是瀏覽器在后臺(tái)獨(dú)立于網(wǎng)頁(yè)運(yùn)行的腳本。是它讓 PWA 擁有極快的訪問(wèn)速度和離線運(yùn)行能力。

那它是如何做到的呢?我們一步步來(lái)看。

注冊(cè) Service Worker
if ("serviceWorker" in navigator) {
  navigator.serviceWorker
    .register("/service-worker.js")
    .then(registration => {
      console.log(
        "ServiceWorker registration successful with scope: ",
        registration.scope
      )
    })
    .catch(err => {
      console.log("ServiceWorker registration failed: ", err)
    })
}

需要注意的是,Service Worker 腳本除了域名為 localhost 時(shí)能運(yùn)行在 http 協(xié)議下以外,只能運(yùn)行 https 協(xié)議下。

安裝
const CACHE_NAME = "cache-v1"
const DATA_CACHE_NAME = "data-cache-v1"

const PRE_CACHE = ["/index.html", "/css/app.css", "/js/app.js"]

self.addEventListener("install", e => {
  console.log("[ServiceWorker] Install")
  e.waitUntil(
    caches.open(CACHE_NAME).then(cache => {
      return cache.addAll(PRE_CACHE)
    })
  )
})

在安裝的時(shí)候預(yù)緩存網(wǎng)站的靜態(tài)資源,任何資源路徑出錯(cuò)都會(huì)造成 Service Worker 安裝失敗。

代理請(qǐng)求
self.addEventListener("fetch", e => {
  e.respondWith(
    caches.match(e.request).then(response => {
      if (response) {
        return response
      }

      const fetchRequest = e.request.clone()

      return fetch(fetchRequest).then(response => {
        // Check if we received a valid response
        if (!response || response.status !== 200) {
          return response
        }

        const responseToCache = response.clone()

        caches.open(DATA_CACHE_NAME).then(cache => {
          cache.put(e.request, responseToCache)
        })

        return response
      })
    })
  )
})

安裝成功后,Service Worker 就可以監(jiān)聽(tīng)網(wǎng)站的所有請(qǐng)求,匹配到緩存時(shí)直接返回,未匹配到時(shí)請(qǐng)求服務(wù)器,服務(wù)器成功返回時(shí)添加到緩存。

更新

現(xiàn)在網(wǎng)站的 Service Worker 已經(jīng)可以正常工作了,那如何更新它呢?

我們只需要修改 Service Worker 文件就可以更新它。當(dāng)我們每次訪問(wèn)網(wǎng)站時(shí)都會(huì)去下載這個(gè)文件,當(dāng)發(fā)現(xiàn)文件不一致時(shí),就會(huì)安裝這個(gè)新 Service Worker ,安裝成功后,它將進(jìn)入等待階段。當(dāng)我們關(guān)閉窗口重新導(dǎo)航到網(wǎng)站時(shí)(刷新網(wǎng)頁(yè)不行),新 Service Worker 將開(kāi)始控制網(wǎng)站。舊 Service Worker 終止工作并觸發(fā) activate 事件:

self.addEventListener("activate", e => {
  e.waitUntil(
    caches.keys().then(keyList => {
      return Promise.all(
        keyList.map(key => {
          if (key !== CACHE_NAME && key !== DATA_CACHE_NAME) {
            console.log("[ServiceWorker] Removing old cache", key)
            return caches.delete(key)
          }
        })
      )
    })
  )
})

在其卸載時(shí)一定要?jiǎng)h除舊緩存,不然我們的網(wǎng)站永遠(yuǎn)無(wú)法更新。

上面只簡(jiǎn)單講了 Service Worker 如何工作。我們會(huì)發(fā)現(xiàn)有很多問(wèn)題需要我們進(jìn)一步解決:

預(yù)緩存的靜態(tài)資源修改后在下一次發(fā)版本時(shí)的文件名都不一樣,手動(dòng)寫(xiě)死太低效,最好每次都自動(dòng)生成資源文件名。

緩存資源是以硬編碼字符串判斷是否有效,這樣每次發(fā)版本都需要手動(dòng)修改,才能更新緩存。并且每次都是全量更新。能否以文件的粒度進(jìn)行資源緩存呢?

請(qǐng)求代理沒(méi)有區(qū)分靜態(tài)資源和動(dòng)態(tài)接口。已經(jīng)緩存的動(dòng)態(tài)接口也會(huì)一直返回緩存,無(wú)法請(qǐng)求新數(shù)據(jù)。

上面只列出了三個(gè)明顯的問(wèn)題,還有很多問(wèn)題是沒(méi)有考慮到的。如果讓我們自己來(lái)解決這些問(wèn)題,不僅是工作量很大,而且也很難寫(xiě)出生產(chǎn)環(huán)境可用的 Service Worker

workbox

既然如此,我們最好是站在巨人的肩膀上,這個(gè)巨人就是谷歌。workbox 是由谷歌瀏覽器團(tuán)隊(duì)發(fā)布,用來(lái)協(xié)助創(chuàng)建 PWA 應(yīng)用的 JavaScript 庫(kù)。當(dāng)然直接用 workbox 還是太復(fù)雜了,谷歌還很貼心的發(fā)布了一個(gè) webpack 插件,能夠自動(dòng)生成 Service Worker 和 靜態(tài)資源列表 - workbox-webpack-plugin。

只需簡(jiǎn)單一步就能生成生產(chǎn)環(huán)境可用的 Service Worker

const { GenerateSW } = require("workbox-webpack-plugin")

new GenerateSW()

打包一下:

還能說(shuō)什么呢?谷歌大法好!當(dāng)然這只是最簡(jiǎn)單的可用版本,其實(shí)這里有一個(gè)最嚴(yán)重的問(wèn)題不知道有沒(méi)人發(fā)現(xiàn),那就是 importScripts 引用的是谷歌域名下的 cdn ,這讓我們墻內(nèi)的網(wǎng)站怎么用,所以我們需要把這個(gè)問(wèn)題解決并自定義一些配置增強(qiáng) Service Worker 的能力:

new GenerateSW({
  importWorkboxFrom: "local",
  skipWaiting: true,
  clientsClaim: true,
  runtimeCaching: [
    {
      // To match cross-origin requests, use a RegExp that matches
      // the start of the origin:
      urlPattern: new RegExp("^https://api"),
      handler: "staleWhileRevalidate",
      options: {
        // Configure which responses are considered cacheable.
        cacheableResponse: {
          statuses: [200]
        }
      }
    },
    {
      urlPattern: new RegExp("^https://cdn"),
      // Apply a network-first strategy.
      handler: "networkFirst",
      options: {
        // Fall back to the cache after 2 seconds.
        networkTimeoutSeconds: 2,
        cacheableResponse: {
          statuses: [200]
        }
      }
    }
  ]
})

首先 importWorkboxFrom 我們指定從本地引入,這樣插件就會(huì)將 workbox 所有源文件下載到本地,墻內(nèi)開(kāi)發(fā)者的福音。上面提到過(guò)新 Service Worker 安裝成功后需要進(jìn)入等待階段,skipWaiting: true 將使其跳過(guò)等待,安裝成功后立即接管網(wǎng)站,注意這個(gè)要和 clientsClaim 一起設(shè)置為 true。runtimeCaching 顧名思義是配置運(yùn)行時(shí)如何緩存請(qǐng)求的,這里只說(shuō)一點(diǎn),緩存跨域請(qǐng)求時(shí) urlPattern 的值必須為 ^ 開(kāi)頭的正則表達(dá)式,其它的配置看文檔都能得到詳細(xì)的介紹。

再打包一次:

現(xiàn)在我們就可以將打包好的代碼部署到網(wǎng)站上了,源碼在這,最后再上幾張圖:

參考

Web App Manifest

服務(wù)工作線程:簡(jiǎn)介

服務(wù)工作線程生命周期

workbox-webpack-plugin

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/95318.html

相關(guān)文章

  • 用vue從零開(kāi)發(fā)和部署一款移動(dòng)端pwa單頁(yè)應(yīng)用

    摘要:另外,單頁(yè)應(yīng)用因?yàn)閿?shù)據(jù)前置到了前端,不利于搜索引擎的抓取。所以我們需要對(duì)自己的單頁(yè)應(yīng)用進(jìn)行一些優(yōu)化。 前言 最近秋招之余空出時(shí)間來(lái)按自己的興趣動(dòng)手做了一個(gè)項(xiàng)目,一個(gè)基于vue-cli3.0, vue,typescript的移動(dòng)端pwa,現(xiàn)在趁熱打鐵,將這個(gè)項(xiàng)目從開(kāi)發(fā)到部署整個(gè)過(guò)程記錄下來(lái),并將從這個(gè)項(xiàng)目中學(xué)習(xí)到的東西分享出來(lái),如果大家有什么意見(jiàn)或補(bǔ)充也可以在評(píng)論區(qū)提出。先介紹一下這個(gè)項(xiàng)...

    Channe 評(píng)論0 收藏0
  • Service worker (@nuxtjs/workbox) 采坑記

    摘要:實(shí)際上是指的為簡(jiǎn)化開(kāi)發(fā)而開(kāi)源的第三方庫(kù)。首先安裝依賴然后再配置文件中啟用就完成了使用采坑官網(wǎng)上線后發(fā)現(xiàn),啟用后不能播放視頻了。把當(dāng)成了失敗請(qǐng)求,導(dǎo)致請(qǐng)求視頻文件失敗。 PWA(Progressive Web App)是前端的大趨勢(shì),它能極大的加快前端頁(yè)面的加載速度,得到近乎原生 app 的展示效果(其實(shí)難說(shuō))。PWA 其實(shí)是多種前端技術(shù)的組合,其中最重要的一個(gè)技術(shù)就是 service ...

    ISherry 評(píng)論0 收藏0
  • hexo博客簡(jiǎn)單支持PWA

    摘要:文章首次發(fā)表在博客支持了前言使用插件使博客支持功能,目前我所知道的有兩種插件均可實(shí)現(xiàn)該功能前提全站支持目前本人使用的是騰訊云的免費(fèi)證書(shū)網(wǎng)站配置已經(jīng)有很多文章寫(xiě)了配置過(guò)程本篇文章不在贅述使用安裝修改配置文件的配置文件采用語(yǔ)言想要 文章首次發(fā)表在: 博客支持PWA了~ 前言 使用hexo插件使博客支持pwa功能,目前我所知道的有兩種插件均可實(shí)現(xiàn)該功能 hexo-pwa hexo-off...

    nicercode 評(píng)論0 收藏0
  • 記一次基于react、cra2、typescript的pwa項(xiàng)目由開(kāi)發(fā)到部署(二)

    摘要:在上一篇文章記一次基于的項(xiàng)目由開(kāi)發(fā)到部署一中,我們了解到了給我們提供了哪些支持,也了解到了有哪些不足。項(xiàng)目回顧這是一個(gè)移動(dòng)端的應(yīng)用,使用,,,,基于開(kāi)發(fā)。可以添加到主屏幕,可以斷網(wǎng)條件下正常打開(kāi)和訪問(wèn)數(shù)據(jù)。 在上一篇文章記一次基于react、cra2、typescript的pwa項(xiàng)目由開(kāi)發(fā)到部署(一)中,我們了解到了create-react-app 給我們提供了哪些pwa支持,也了解到...

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

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

0條評(píng)論

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