亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

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

since1986 / 3678人閱讀

摘要:學(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í)踐》系列的第三篇文章。文中的代碼都可以在learning-pwa的sw-cache分支上找到(git clone后注意切換到sw-cache分支)。

PWA作為時(shí)下最火熱的技術(shù)概念之一,對(duì)提升Web應(yīng)用的安全、性能和體驗(yàn)有著很大的意義,非常值得我們?nèi)チ私馀c學(xué)習(xí)。對(duì)PWA感興趣的朋友歡迎關(guān)注《PWA學(xué)習(xí)與實(shí)踐》系列文章。

1. 引言

PWA其中一個(gè)令人著迷的能力就是離線(offline)可用。

離線只是它的一種功能表現(xiàn)而已,具體說來,它可以:

讓我們的Web App在無網(wǎng)(offline)情況下可以訪問,甚至使用部分功能,而不是展示“無網(wǎng)絡(luò)連接”的錯(cuò)誤頁;

讓我們?cè)谌蹙W(wǎng)的情況下,能使用緩存快速訪問我們的應(yīng)用,提升體驗(yàn);

在正常的網(wǎng)絡(luò)情況下,也可以通過各種自發(fā)控制的緩存方式來節(jié)省部分請(qǐng)求帶寬;

……

而這一切,其實(shí)都要?dú)w功于PWA背后的英雄 —— Service Worker。

那么,Service Worker是什么呢?你可以把Service Worker簡(jiǎn)單理解為一個(gè)獨(dú)立于前端頁面,在后臺(tái)運(yùn)行的進(jìn)程。因此,它不會(huì)阻塞瀏覽器腳本的運(yùn)行,同時(shí)也無法直接訪問瀏覽器相關(guān)的API(例如:DOM、localStorage等)。此外,即使在離開你的Web App,甚至是關(guān)閉瀏覽器后,它仍然可以運(yùn)行。它就像是一個(gè)在Web應(yīng)用背后默默工作的勤勞小蜜蜂,處理著緩存、推送、通知與同步等工作。所以,要學(xué)習(xí)PWA,繞不開的就是Service Worker。

在接下來的幾篇文章里,我會(huì)從如何使用Service Worker來實(shí)現(xiàn)資源的緩存、消息的推送、消息的通知以及后臺(tái)同步這幾個(gè)角度,來介紹相關(guān)原理與技術(shù)實(shí)現(xiàn)。這些部分會(huì)是PWA技術(shù)的重點(diǎn)。需要特別注意的是,由于Service Worker所具有的強(qiáng)大能力,因此規(guī)范規(guī)定,Service Worker只能運(yùn)行在HTTPS域下。然而我們開發(fā)時(shí)候沒有HTTPS怎么辦?別著急,還有一個(gè)貼心的地方——為方便本地開發(fā),Service Worker也可以運(yùn)行在localhost(127.0.0.1)域下。

好了,簡(jiǎn)單了解了Service Worker與它能實(shí)現(xiàn)的功能后,我們還是要回到這一篇的主題,也就是Service Worker的第一部分——如何利用Service Worker來實(shí)現(xiàn)前端資源的緩存,從而提升產(chǎn)品的訪問速度,做到離線可用。

2. Service Worker是如何實(shí)現(xiàn)離線可用的?

這一小節(jié)會(huì)告訴大家,Service Worker是如何讓我們?cè)陔x線的情況下也能訪問Web App的。當(dāng)然,離線訪問只是其中一種表現(xiàn)。

首先,我們想一下,當(dāng)訪問一個(gè)web網(wǎng)站時(shí),我們實(shí)際上做了什么呢?總體上來說,我們通過與與服務(wù)器建立連接,獲取資源,然后獲取到的部分資源還會(huì)去請(qǐng)求新的資源(例如html中使用的css、js等)。所以,粗粒度來說,我們?cè)L問一個(gè)網(wǎng)站,就是在獲取/訪問這些資源。

可想而知,當(dāng)處于離線或弱網(wǎng)環(huán)境時(shí),我們無法有效訪問這些資源,這就是制約我們的關(guān)鍵因素。因此,一個(gè)最直觀的思路就是:如果我們把這些資源緩存起來,在某些情況下,將網(wǎng)絡(luò)請(qǐng)求變?yōu)楸镜卦L問,這樣是否能解決這一問題?是的。但這就需要我們有一個(gè)本地的cache,可以靈活地將各類資源進(jìn)行本地存取。

有了本地的cache還不夠,我們還需要能夠有效地使用緩存、更新緩存與清除緩存,進(jìn)一步應(yīng)用各種個(gè)性化的緩存策略。而這就需要我們有個(gè)能夠控制緩存的“worker”——這也就是Service Worker的部分工作之一。順便多說一句,可能有人還記得 ApplicationCache 這個(gè)API。當(dāng)初它的設(shè)計(jì)同樣也是為了實(shí)現(xiàn)Web資源的緩存,然而就是因?yàn)椴粔蜢`活等各種缺陷,如今已被Service Worker與cache API所取代了。

Service Worker有一個(gè)非常重要的特性:你可以在Service Worker中監(jiān)聽所有客戶端(Web)發(fā)出的請(qǐng)求,然后通過Service Worker來代理,向后端服務(wù)發(fā)起請(qǐng)求。通過監(jiān)聽用戶請(qǐng)求信息,Service Worker可以決定是否使用緩存來作為Web請(qǐng)求的返回。

下圖展示普通Web App與添加了Service Worker的Web App在網(wǎng)絡(luò)請(qǐng)求上的差異:

這里需要強(qiáng)調(diào)一下,雖然圖中好像將瀏覽器、SW(Service Worker)與后端服務(wù)三者并列放置了,但實(shí)際上瀏覽器(你的Web應(yīng)用)和SW都是運(yùn)行在你的本機(jī)上的,所以這個(gè)場(chǎng)景下的SW類似一個(gè)“客戶端代理”。

了解了基本概念之后,就可以具體來看下,我們?nèi)绾螒?yīng)用這個(gè)技術(shù)來實(shí)現(xiàn)一個(gè)離線可用的Web應(yīng)用。

3. 如何使用Service Worker實(shí)現(xiàn)離線可用的“秒開”應(yīng)用

還記得我們之前的那個(gè)圖書搜索的demo Web App么?不了解的朋友可以看下本系列的第一篇文章,當(dāng)然你可以忽略細(xì)節(jié),繼續(xù)往下了解技術(shù)原理。

沒錯(cuò),這次我仍然會(huì)基于它進(jìn)行改造。在上一篇添加了manifest后,它已經(jīng)擁有了自己的桌面圖標(biāo),并有一個(gè)很像Native App的外殼;而今天,我會(huì)讓它變得更酷。

如果想要跟著文章內(nèi)容一起實(shí)踐,可以在這里下載到所需的全部代碼。
記得切換到manifest分支,因?yàn)楸酒獌?nèi)容,是基于上一篇的最終代碼進(jìn)行相應(yīng)的開發(fā)與升級(jí)。畢竟我們的最終目標(biāo)是將這個(gè)普通的“圖書搜索”demo升級(jí)為PWA。
3.1. 注冊(cè)Service Worker

注意,我們的應(yīng)用始終應(yīng)該是漸進(jìn)可用的,在不支持Service Worker的環(huán)境下,也需要保證其可用性。要實(shí)現(xiàn)這點(diǎn),可以通過特性檢測(cè),在index.js中來注冊(cè)我們的Service Worker(sw.js):

// index.js
// 注冊(cè)service worker,service worker腳本文件為sw.js
if ("serviceWorker" in navigator) {
    navigator.serviceWorker.register("./sw.js").then(function () {
        console.log("Service Worker 注冊(cè)成功");
    });
}

這里我們將sw.js文件注冊(cè)為一個(gè)Service Worker,注意文件的路徑不要寫錯(cuò)了。

值得一提的是,Service Worker的各類操作都被設(shè)計(jì)為異步,用以避免一些長時(shí)間的阻塞操作。這些API都是以Promise的形式來調(diào)用的。所以你會(huì)在接下來的各段代碼中不斷看到Promise的使用。如果你完全不了解Promise,可以先在這里了解基本的Promise概念:Promise(MDN)和JavaScript Promise:簡(jiǎn)介。

3.2. Service Worker的生命周期

當(dāng)我們注冊(cè)了Service Worker后,它會(huì)經(jīng)歷生命周期的各個(gè)階段,同時(shí)會(huì)觸發(fā)相應(yīng)的事件。整個(gè)生命周期包括了:installing --> installed --> activating --> activated --> redundant。當(dāng)Service Worker安裝(installed)完畢后,會(huì)觸發(fā)install事件;而激活(activated)后,則會(huì)觸發(fā)activate事件。

下面的例子監(jiān)聽了install事件:

// 監(jiān)聽install事件
self.addEventListener("install", function (e) {
    console.log("Service Worker 狀態(tài): install");
});

self是Service Worker中一個(gè)特殊的全局變量,類似于我們最常見的window對(duì)象。self引用了當(dāng)前這個(gè)Service Worker。

3.3. 緩存靜態(tài)資源

通過上一節(jié),我們已經(jīng)學(xué)會(huì)了如何添加事件監(jiān)聽,來在合適的時(shí)機(jī)觸發(fā)Service Worker的相應(yīng)操作?,F(xiàn)在,要使我們的Web App離線可用,就需要將所需資源緩存下來。我們需要一個(gè)資源列表,當(dāng)Service Worker被激活時(shí),會(huì)將該列表內(nèi)的資源緩存進(jìn)cache。

// sw.js
var cacheName = "bs-0-2-0";
var cacheFiles = [
    "/",
    "./index.html",
    "./index.js",
    "./style.css",
    "./img/book.png",
    "./img/loading.svg"
];

// 監(jiān)聽install事件,安裝完成后,進(jìn)行文件緩存
self.addEventListener("install", function (e) {
    console.log("Service Worker 狀態(tài): install");
    var cacheOpenPromise = caches.open(cacheName).then(function (cache) {
        return cache.addAll(cacheFiles);
    });
    e.waitUntil(cacheOpenPromise);
});

可以看到,首先在cacheFiles中我們列出了所有的靜態(tài)資源依賴。注意其中的"/",由于根路徑也可以訪問我們的應(yīng)用,因此不要忘了將其也緩存下來。當(dāng)Service Worker install時(shí),我們就會(huì)通過caches.open()cache.addAll()方法將資源緩存起來。這里我們給緩存起了一個(gè)cacheName,這個(gè)值會(huì)成為這些緩存的key。

上面這段代碼中,caches是一個(gè)全局變量,通過它我們可以操作Cache相關(guān)接口。

Cache 接口提供緩存的 Request / Response 對(duì)象對(duì)的存儲(chǔ)機(jī)制。Cache 接口像 workers 一樣, 是暴露在 window 作用域下的。盡管它被定義在 service worker 的標(biāo)準(zhǔn)中,  但是它不必一定要配合 service worker 使用?!狹DN
3.4 使用緩存的靜態(tài)資源

到目前為止,我們僅僅是注冊(cè)了一個(gè)Service Worker,并在其install時(shí)緩存了一些靜態(tài)資源。然而,如果這時(shí)運(yùn)行這個(gè)demo你會(huì)發(fā)現(xiàn)——“圖書搜索”這個(gè)Web App依然無法離線使用。

為什么呢?因?yàn)槲覀儍H僅緩存了這些資源,然而瀏覽器并不知道需要如何使用它們;換言之,瀏覽器仍然會(huì)通過向服務(wù)器發(fā)送請(qǐng)求來等待并使用這些資源。那怎么辦?

聰明的你應(yīng)該想起來了,我們?cè)谖恼虑鞍氩糠纸榻BService Worker時(shí)提到了“客戶端代理”——用Service Worker來幫我們決定如何使用緩存。

下圖是一個(gè)簡(jiǎn)單的策略:

瀏覽器發(fā)起請(qǐng)求,請(qǐng)求各類靜態(tài)資源(html/js/css/img);

Service Worker攔截瀏覽器請(qǐng)求,并查詢當(dāng)前cache;

若存在cache則直接返回,結(jié)束;

若不存在cache,則通過fetch方法向服務(wù)端發(fā)起請(qǐng)求,并返回請(qǐng)求結(jié)果給瀏覽器

// sw.js
self.addEventListener("fetch", function (e) {
    // 如果有cache則直接返回,否則通過fetch請(qǐng)求
    e.respondWith(
        caches.match(e.request).then(function (cache) {
            return cache || fetch(e.request);
        }).catch(function (err) {
            console.log(err);
            return fetch(e.request);
        })
    );
});

fetch事件會(huì)監(jiān)聽所有瀏覽器的請(qǐng)求。e.respondWith()方法接受Promise作為參數(shù),通過它讓Service Worker向?yàn)g覽器返回?cái)?shù)據(jù)。caches.match(e.request)則可以查看當(dāng)前的請(qǐng)求是否有一份本地緩存:如果有緩存,則直接向?yàn)g覽器返回cache;否則Service Worker會(huì)向后端服務(wù)發(fā)起一個(gè)fetch(e.request)的請(qǐng)求,并將請(qǐng)求結(jié)果返回給瀏覽器。

到目前為止,運(yùn)行我們的demo:當(dāng)?shù)谝宦?lián)網(wǎng)打開“圖書搜索”Web App后,所依賴的靜態(tài)資源就會(huì)被緩存在本地;以后再訪問時(shí),就會(huì)使用這些緩存而不發(fā)起網(wǎng)絡(luò)請(qǐng)求。因此,即使在無網(wǎng)情況下,我們似乎依舊能“訪問”該應(yīng)用。

3.5. 更新靜態(tài)緩存資源

然而,如果你細(xì)心的話,會(huì)發(fā)現(xiàn)一個(gè)小問題:當(dāng)我們將資源緩存后,除非注銷(unregister)sw.js、手動(dòng)清除緩存,否則新的靜態(tài)資源將無法緩存。

解決這個(gè)問題的一個(gè)簡(jiǎn)單方法就是修改cacheName。由于瀏覽器判斷sw.js是否更新是通過字節(jié)方式,因此修改cacheName會(huì)重新觸發(fā)install并緩存資源。此外,在activate事件中,我們需要檢查cacheName是否變化,如果變化則表示有了新的緩存資源,原有緩存需要?jiǎng)h除。

// sw.js
// 監(jiān)聽activate事件,激活后通過cache的key來判斷是否更新cache中的靜態(tài)資源
self.addEventListener("activate", function (e) {
    console.log("Service Worker 狀態(tài): activate");
    var cachePromise = caches.keys().then(function (keys) {
        return Promise.all(keys.map(function (key) {
            if (key !== cacheName) {
                return caches.delete(key);
            }
        }));
    })
    e.waitUntil(cachePromise);
    return self.clients.claim();
});
3.6. 緩存API數(shù)據(jù)的“離線搜索”

到這里,我們的應(yīng)用基本已經(jīng)完成了離線訪問的改造。但是,如果你注意到文章開頭的圖片就會(huì)發(fā)現(xiàn),離線時(shí)我們不僅可以訪問,還可以使用搜索功能。

這是怎么回事呢?其實(shí)這背后的秘密就在于,這個(gè)Web App也會(huì)把XHR請(qǐng)求的數(shù)據(jù)緩存一份。而再次請(qǐng)求時(shí),我們會(huì)優(yōu)先使用本地緩存(如果有緩存的話);然后向服務(wù)端請(qǐng)求數(shù)據(jù),服務(wù)端返回?cái)?shù)據(jù)后,基于該數(shù)據(jù)替換展示。大致過程如下:

首先我們改造一下前一節(jié)的代碼在sw.js的fetch事件里進(jìn)行API數(shù)據(jù)的緩存

// sw.js
var apiCacheName = "api-0-1-1";
self.addEventListener("fetch", function (e) {
    // 需要緩存的xhr請(qǐng)求
    var cacheRequestUrls = [
        "/book?"
    ];
    console.log("現(xiàn)在正在請(qǐng)求:" + e.request.url);

    // 判斷當(dāng)前請(qǐng)求是否需要緩存
    var needCache = cacheRequestUrls.some(function (url) {
        return e.request.url.indexOf(url) > -1;
    });

    /**** 這里是對(duì)XHR數(shù)據(jù)緩存的相關(guān)操作 ****/
    if (needCache) {
        // 需要緩存
        // 使用fetch請(qǐng)求數(shù)據(jù),并將請(qǐng)求結(jié)果clone一份緩存到cache
        // 此部分緩存后在browser中使用全局變量caches獲取
        caches.open(apiCacheName).then(function (cache) {
            return fetch(e.request).then(function (response) {
                cache.put(e.request.url, response.clone());
                return response;
            });
        });
    }
    /* ******************************* */

    else {
        // 非api請(qǐng)求,直接查詢cache
        // 如果有cache則直接返回,否則通過fetch請(qǐng)求
        e.respondWith(
            caches.match(e.request).then(function (cache) {
                return cache || fetch(e.request);
            }).catch(function (err) {
                console.log(err);
                return fetch(e.request);
            })
        );
    }
});

這里,我們也為API緩存的數(shù)據(jù)創(chuàng)建一個(gè)專門的緩存位置,key值為變量apiCacheName。在fetch事件中,我們首先通過對(duì)比當(dāng)前請(qǐng)求與cacheRequestUrls來判斷是否是需要緩存的XHR請(qǐng)求數(shù)據(jù),如果是的話,就會(huì)使用fetch方法向后端發(fā)起請(qǐng)求。

fetch.then中我們以請(qǐng)求的URL為key,向cache中更新了一份當(dāng)前請(qǐng)求所返回?cái)?shù)據(jù)的緩存:cache.put(e.request.url, response.clone())。這里使用.clone()方法拷貝一份響應(yīng)數(shù)據(jù),這樣我們就可以對(duì)響應(yīng)緩存進(jìn)行各類操作而不用擔(dān)心原響應(yīng)信息被修改了。

3.7. 應(yīng)用離線XHR數(shù)據(jù),完成“離線搜索”,提升響應(yīng)速度

如果你跟著做到了這一步,那么恭喜你,距離我們酷酷的離線應(yīng)用還差最后一步了!

目前為止,我們對(duì)Service Worker(sw.js)的改造已經(jīng)完畢了。最后只剩下如何在XHR請(qǐng)求時(shí)有策略的使用緩存了,這一部分的改造全部集中于index.js,也就是我們的前端腳本。

還是回到上一節(jié)的這張圖:

和普通情況不同,這里我們的前端瀏覽器會(huì)首先去嘗試獲取緩存數(shù)據(jù)并使用其來渲染界面;同時(shí),瀏覽器也會(huì)發(fā)起一個(gè)XHR請(qǐng)求,Service Worker通過將請(qǐng)求返回的數(shù)據(jù)更新到存儲(chǔ)中的同時(shí)向前端Web應(yīng)用返回?cái)?shù)據(jù)(這一步分就是上一節(jié)提到的緩存策略);最終,如果判斷返回的數(shù)據(jù)與最開始取到的cache不一致,則重新渲染界面,否則忽略。

為了是代碼更清晰,我們將原本的XHR請(qǐng)求部分多帶帶剝離出來,作為一個(gè)方法getApiDataRemote()以供調(diào)用,同時(shí)將其改造為了Promise。為了節(jié)省篇幅,我部分的代碼比較簡(jiǎn)單,就不多帶帶貼出了。

這一節(jié)最重要的部分其實(shí)是讀取緩存。我們知道,在Service Worker中是可以通過caches變量來訪問到緩存對(duì)象的。令人高興的是,在我們的前端應(yīng)用中,也仍然可以通過caches來訪問緩存。當(dāng)然,為了保證漸進(jìn)可用,我們需要先進(jìn)行判斷"caches" in window。為了代碼的統(tǒng)一,我將獲取該請(qǐng)求的緩存數(shù)據(jù)也封裝成了一個(gè)Promise方法:

function getApiDataFromCache(url) {
    if ("caches" in window) {
        return caches.match(url).then(function (cache) {
            if (!cache) {
                return;
            }
            return cache.json();
        });
    }
    else {
        return Promise.resolve();
    }
}

而原本我們?cè)?b>queryBook()方法中,我們會(huì)請(qǐng)求后端數(shù)據(jù),然后渲染頁面;而現(xiàn)在,我們加上基于緩存的渲染:

function queryBook() {
    // ……
    // 遠(yuǎn)程請(qǐng)求
    var remotePromise = getApiDataRemote(url);
    var cacheData;
    // 首先使用緩存數(shù)據(jù)渲染
    getApiDataFromCache(url).then(function (data) {
        if (data) {
            loading(false);
            input.blur();            
            fillList(data.books);
            document.querySelector("#js-thanks").style = "display: block";
        }
        cacheData = data || {};
        return remotePromise;
    }).then(function (data) {
        if (JSON.stringify(data) !== JSON.stringify(cacheData)) {
            loading(false);                
            input.blur();
            fillList(data.books);
            document.querySelector("#js-thanks").style = "display: block";
        }
    });
    // ……
}

如果getApiDataFromCache(url).then返回緩存數(shù)據(jù),則使用它先進(jìn)行渲染。而當(dāng)remotePromise的數(shù)據(jù)返回時(shí),與cacheData進(jìn)行比對(duì),只有在數(shù)據(jù)不一致時(shí)需要重新渲染頁面(注意這里為了簡(jiǎn)便,粗略地使用了JSON.stringify()方法進(jìn)行對(duì)象間的比較)。這么做有兩個(gè)優(yōu)勢(shì):

離線可用。如果我們之前訪問過某些URL,那么即使在離線的情況下,重復(fù)相應(yīng)的操作依然可以正常展示頁面;

優(yōu)化體驗(yàn),提高訪問速度。讀取本地cache耗時(shí)相比于網(wǎng)絡(luò)請(qǐng)求是非常低的,因此就會(huì)給我們的用戶一種“秒開”、“秒響應(yīng)”的感覺。

4. 使用Lighthouse測(cè)試我們的應(yīng)用

至此,我們完成了PWA的兩大基本功能:Web App Manifest和Service Worker的離線緩存。這兩大功能可以很好地提升用戶體驗(yàn)與應(yīng)用性能。我們用Chrome中的Lighthouse來檢測(cè)一下目前的應(yīng)用:

可以看到,在PWA評(píng)分上,我們的這個(gè)Web App已經(jīng)非常不錯(cuò)了。其中唯一個(gè)扣分項(xiàng)是在HTTPS協(xié)議上:由于是本地調(diào)試,所以使用了http://127.0.0.1:8085,在生產(chǎn)肯定會(huì)替換為HTTPS。

5. 這太酷了,但是兼容性呢?

隨著今年(2018年)年初,Apple在iOS 11.3中開始支持Service Worker,加上Apple一直以來較為良好的系統(tǒng)升級(jí)率,整個(gè)PWA在兼容性問題上有了重大的突破。

雖然Service Worker中的一些其他功能(例如推送、后臺(tái)同步)Apple并未表態(tài),但是Web App Manifest和Service Worker的離線緩存是iOS 11.3所支持的。這兩大核心功能不僅效果拔群,而且目前看來具有還不錯(cuò)的兼容性,非常適合投入生產(chǎn)。

更何況,作為漸進(jìn)式網(wǎng)頁應(yīng)用,其最重要的一個(gè)特點(diǎn)就是在兼容性支持時(shí)自動(dòng)升級(jí)功能與體驗(yàn);而在不支持時(shí),會(huì)靜默回退部分新功能。在保證我們的正常服務(wù)情況下,盡可能利用瀏覽器特性,提供更優(yōu)質(zhì)的服務(wù)。

6. 寫在最后

本文中所有的代碼示例均可以在learn-pwa/sw-cache上找到。注意在git clone之后,切換到sw-cache分支,本文所有的代碼均存在于該分支上。切換其他分值可以看到不同的版本:

basic分支:基礎(chǔ)項(xiàng)目demo,一個(gè)普通的圖書搜索應(yīng)用(網(wǎng)站);

manifest分支:基于basic分支,添加manifest等功能,具體可以看上一篇文章了解;

sw-cache分支:基于manifest分支,添加緩存與離線功能;

master分支:應(yīng)用的最新代碼。

如果你喜歡或想要了解更多的PWA相關(guān)知識(shí),歡迎關(guān)注我,關(guān)注《PWA學(xué)習(xí)與實(shí)踐》系列文章。我會(huì)總結(jié)整理自己學(xué)習(xí)PWA過程的遇到的疑問與技術(shù)點(diǎn),并通過實(shí)際代碼和大家一起實(shí)踐。

最后聲明一下,文中的代碼作為demo,主要是用于了解與學(xué)習(xí)PWA技術(shù)原理,可能會(huì)存在一些不完善的地方,因此,不建議直接使用到生產(chǎn)環(huán)境。
《PWA技術(shù)學(xué)習(xí)與實(shí)踐》系列

第一篇:開始你的PWA學(xué)習(xí)之旅

第二篇:10分鐘學(xué)會(huì)使用Manifest,讓你的WebApp更“Native”

第三篇:從今天起,讓你的WebApp離線可用(本文)

第四篇:TroubleShooting: 解決FireBase login驗(yàn)證失敗問題

第五篇:與你的用戶保持聯(lián)系: Web Push功能

第六篇:How to Debug? 在chrome中調(diào)試你的PWA

第七篇:增強(qiáng)交互:使用Notification API來進(jìn)行提醒

第八篇:使用Service Worker進(jìn)行后臺(tái)數(shù)據(jù)同步

第九篇:PWA實(shí)踐中的問題與解決方案

第十篇:Resource Hint - 提升頁面加載性能與體驗(yàn)

第十一篇:從PWA離線工具集workbox中學(xué)習(xí)各類離線策略(寫作中…)

參考資料

Using Service Workers(MDN)

Cache(MDN)

Service Worker使用方式

JavaScript Promise:簡(jiǎn)介

Promise(MDN)

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

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

相關(guān)文章

  • 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
  • PWA學(xué)習(xí)實(shí)踐】(2) 使用Manifest,你的WebApp更“Native”

    摘要:,不過在上會(huì)導(dǎo)致狀態(tài)欄不顯示任何東西。下面是項(xiàng)目中的相關(guān)設(shè)置圖書搜索中的處理方式與類似,中也有自己的標(biāo)簽來指示相應(yīng)的資源。 《PWA學(xué)習(xí)與實(shí)踐》系列文章已整理至gitbook - PWA學(xué)習(xí)手冊(cè),文字內(nèi)容已同步至learning-pwa-ebook。轉(zhuǎn)載請(qǐng)注明作者與出處。 本文是《PWA學(xué)習(xí)與實(shí)踐》系列的第二篇文章。文中的代碼都可以在learning-pwa的manifest分支上找到...

    flyer_dev 評(píng)論0 收藏0
  • PWA學(xué)習(xí)實(shí)踐】(1) 2018,開始你的PWA學(xué)習(xí)之旅

    摘要:學(xué)習(xí)與實(shí)踐系列文章已整理至學(xué)習(xí)手冊(cè),文字內(nèi)容已同步至。本系列文章學(xué)習(xí)與實(shí)踐會(huì)逐步拆解背后的各項(xiàng)技術(shù),通過實(shí)例代碼來講解這些技術(shù)的應(yīng)用方式。而隨著在中也開始支持其中的某些技術(shù),的舞臺(tái)更大了。這個(gè)最開始是不具備任何的能力。 《PWA學(xué)習(xí)與實(shí)踐》系列文章已整理至gitbook - PWA學(xué)習(xí)手冊(cè),文字內(nèi)容已同步至learning-pwa-ebook。轉(zhuǎn)載請(qǐng)注明作者與出處。 PWA作為今年最火...

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

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

0條評(píng)論

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