热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JavaScript事情道理(八):ServiceWorkers,生命周期和運用案例

您可以已曉得,漸進式Web運用(PWA)會愈來愈受歡迎,因為它們旨在使Web運用的用戶體驗越發流通,建立Native運用程序般的體驗,而不只是運轉在瀏覽器的運用。構建漸進式Web運

《Javascript事情道理(八):Service Workers,生命周期和運用案例》
您可以已曉得,漸進式Web運用(PWA)會愈來愈受歡迎,因為它們旨在使Web運用的用戶體驗越發流通,建立Native運用程序般的體驗,而不只是運轉在瀏覽器的運用。

構建漸進式Web運用程序的重要緣由之一是使運用在收集和加載方面異常牢靠 – 它應當可用於不確定或不存在的收集前提。

在這篇文章中,我們將深入探討Service Worker:他們怎樣運作以及應當注重的處所。末了,我們還列出了您應當應用的Service Workers的一些奇特上風。

概述

假如你想相識關於Service Workers的統統,你應當起首瀏覽本系列第幾篇文章。

基本上,Service Worker是一種收集工作者,更具體地說,它就像一個Shared Worker:

  • Service Worker在它自己的全局劇本高低文中運轉
  • 它沒有綁定到特定的網頁
  • 它沒法接見DOM

Service Worker API令人興奮的重要緣由之一是它可以讓你的收集運用程序支撐離線體驗,從而使開發人員可以完整掌握流程。

Service Worker 的生命周期

Service Worker生命周期與您的網頁是完整離開。它由以下幾個階段構成:

  • 下載
  • 裝置
  • 激活

下載

這是瀏覽器下載包括Service Worker的.js文件的時刻。

裝置

您的Web運用程序想要裝置Service Worker,您必須先註冊它,您可以在Javascript代碼中舉行註冊。當Service Worker被註冊時,它會提醒瀏覽器在背景啟動Service Worker裝置步驟。

經由歷程註冊Service Worker,你可以關照瀏覽器你的Service Worker的Javascript文件在那裡。我們來看下面的代碼:

if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/sw.js').then(function(registration) {
// 註冊勝利
console.log('ServiceWorker registration successful');
}, function(err) {
// 註冊失利
console.log('ServiceWorker registration failed: ', err);
});
});
}

該代碼搜檢當前環境中是不是支撐Service Worker API。假如支撐,則註冊/sw.js Service Worker。

您可以在每次加載頁面時挪用register()要領而不必憂鬱 – 瀏覽器會推斷Service Worker是不是已註冊,而且會正確處置懲罰。

register()要領的一個重要細節是Service Worker文件的位置。在這類狀況下,您可以看到效勞工作者文件位於域的根目錄。這意味着Service Worker的局限將是全部泉源。換句話說,這個Service Worker將會收到這個域的一切東西的fetch事宜(我們將在背面議論)。假如我們在/example/sw.js註冊Service Worker文件,那末效勞工作者將只能看到URL以/example/(即/example/page1/,/example/page2/)開首的頁面的fetch事宜。

在裝置階段,最好加載和緩存一些靜態資本。資本勝利緩存后,Service Worker裝置完成。假如沒有勝利(加載失利) – Service Worker將重試。一旦裝置勝利,您將曉得靜態資本位於緩存中。
在裝置階段,最好加載和緩存一些靜態資本。資本勝利緩存后,Service Worker裝置完成。假如沒有勝利(加載失利) – Service將重試。一旦裝置勝利,您將曉得靜態資產位於緩存中。

假如註冊須要在加載事宜以後發作,這將回覆您的題目。這不是必須的,但它是相對引薦的。

為何如許?讓我們斟酌用戶第一次接見您的收集運用程序。如今還沒有Service Worker,瀏覽器沒法事前曉得是不是會有裝置的Service Worker。假如裝置了Service Worker,則瀏覽器須要為這個分外的線程消費分外的CPU和內存,不然瀏覽器將消費在襯着網頁上。

最重要的是,假如你只是在你的頁面上裝置一個Service Worker,你可以會有耽誤加載和襯着的風險 – 而不是儘快讓你的用戶可以運用這個頁面。

請注重,這僅在第一次接見頁面時才顯得重要。後續頁面接見不受Service Worker裝置的影響。一旦在第一次接見頁面時激活Service Worker,它可以處置懲罰加載/緩存事宜,以便隨後接見您的Web運用程序。這統統都是有原理的,因為它須要準備好處置懲罰有限的收集銜接。

激活

裝置Service Worker以後,下一步是將其激活。這一步是治理之前緩存的好機會。

一旦激活,Service Worker將最先掌握一切屬於其局限的頁面。一個風趣的事實是:初次註冊Service Worker的頁面將不會被掌握,直到該頁面再次被加載。一旦處於Service Worker掌握之下,它將處於以下狀況之一:

  • 它將處置懲罰從頁面發出收集請求或音訊時發作的fetch和message事宜
  • 它將被住手以節約內存

以下是生命周期的表面:
《Javascript事情道理(八):Service Workers,生命周期和運用案例》

在ervice Worker內部處置懲罰裝置

在頁面加快註冊歷程以後,讓我們看看Service Worker劇本中發作了什麼,它經由歷程向Service Worker實例增加事宜偵聽器來處置懲罰install事宜。

這些是install事宜處置懲罰時須要採用的步驟:

  • 翻開緩存
  • 緩存我們的文件
  • 確認是不是緩存了一切必須的資本

這是一個簡樸的install在Service Worker內:

var CACHE_NAME = 'my-web-app-cache';
var urlsToCache = [
'/',
'/styles/main.css',
'/scripts/app.js',
'/scripts/lib.js'
];
self.addEventListener('install', function(event) {
// event.waitUntil takes a promise to know how
// long the installation takes, and whether it
// succeeded or not.
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});

假如一切文件勝利被緩存,Service Worker會被裝置。假如任何文件下載失利,install步驟會失利。所以重要注重你須要緩存的文件。

處置懲罰install事宜是可選的,你可以防止處置懲罰它。在這類狀況下,上面三個步驟你都無需處置懲罰。

在運轉時緩存請求

這部份是關鍵地點。這裏您將看到怎樣阻攔請求並返回建立的緩存(並建立新緩存)。

裝置Service Worker而且用戶導航到另一個頁面或革新他地點的頁面后,Service Worker將收到fetch事宜。下面是一個演示怎樣返回緩存資本或實行新請求然後緩存效果的示例:

self.addEventListener('fetch', function(event) {
event.respondWith(
// This method looks at the request and
// finds any cached results from any of the
// caches that the Service Worker has created.
caches.match(event.request)
.then(function(response) {
// If a cache is hit, we can return thre response.
if (response) {
return response;
}
// Clone the request. A request is a stream and
// can only be consumed once. Since we are consuming this
// once by cache and once by the browser for fetch, we need
// to clone the request.
var fetchRequest = event.request.clone();

// A cache hasn't been hit so we need to perform a fetch,
// which makes a network request and returns the data if
// anything can be retrieved from the network.
return fetch(fetchRequest).then(
function(response) {
// Check if we received a valid response
if(!response || response.status !== 200 || response.type !== 'basic') {
return response;
}
// Cloning the response since it's a stream as well.
// Because we want the browser to consume the response
// as well as the cache consuming the response, we need
// to clone it so we have two streams.
var respOnseToCache= response.clone();
caches.open(CACHE_NAME)
.then(function(cache) {
// Add the request to the cache for future queries.
cache.put(event.request, responseToCache);
});
return response;
}
);
})
);
});

簡而言之,這就是發作的歷程:

  • event.respondWith()將決議我們怎樣相應fetch事宜。我們傳遞了一個來自caches.match()的promise,它檢察請求並發現是不是有任何已建立的緩存的緩存效果。
  • 假如存在緩存,則返回效果。
  • 不然,將實行fetch事宜。
  • 搜檢狀況是不是為200。我們還搜檢相應範例是不是basic,這表明它是來自我們origin的請求。在這類狀況下,不會緩存對第三方資本的請求。
  • 相應效果被增加到緩存中。

要乞降相應必須被克隆,因為它們是流。流的主體只能被運用一次。而且因為我們想要運用它們,瀏覽器也要運用它們,所以必須克隆它們。

更新效勞工作者

當用戶接見您的Web運用程序時,瀏覽器會嘗試從新下載包括Service Worker代碼的.js文件。這發作在背景。

假如與當前Service Worker的文件比擬,如今下載的Service Worker文件中以至存在單字節差別,則瀏覽器將假定有轉變而且必須啟動新的Service Worker。

新的Service Worker將啟動而且install事宜將被觸發。然則,在這一點上,舊的Service Worker仍在掌握你的收集運用程序的頁面,這意味着新的Service Worker將進入waiting狀況。

一旦您的Web運用程序當前翻開的頁面封閉,舊的Service Worker將被瀏覽器住手,新裝置的Service Worker將完整掌握。這是當它的激活事宜將被觸發。

為何須要這些?為了防止兩個版本的Web運用程序同時運轉在差別的選項卡上 – 這在收集上實際上異常罕見,而且可以會建立異常蹩腳的毛病(比方,在瀏覽器中存儲數據時存在差別形式的狀況)。

從緩存中刪除數據

activate回調中最罕見的步驟是緩存治理。你如今要如許做,因為假如你在裝置步驟中刪除了一切舊的緩存,舊的Service Workers將倏忽住手供應緩存中的文件。

下面是一個示例,您可以從緩存中刪除某些未列入白名單的文件(在這類狀況下,其稱號中包括page-1或page-2):

self.addEventListener('activate', function(event) {
var cacheWhitelist = ['page-1', 'page-2'];
event.waitUntil(
// Retrieving all the keys from the cache.
caches.keys().then(function(cacheNames) {
return Promise.all(
// Looping through all the cached files.
cacheNames.map(function(cacheName) {
// If the file in the cache is not in the whitelist
// it should be deleted.
if (cacheWhitelist.indexOf(cacheName) === -1) {
return caches.delete(cacheName);
}
})
);
})
);
});

HTTPS請求

在構建Web運用程序時,您可以經由歷程當地主機運用Service Worker,然則一旦將其布置到臨盆環境中,則須要準備好HTTPS(這是您具有HTTPS的末了一個緣由)。

運用Service Worker,您可以挾制銜接並製造相應。 經由歷程不運用HTTPs,您的Web運用程序變得輕易遭到進擊。

為了讓事變更平安,您須要在經由歷程HTTPS供應的頁面上註冊Service Worker,以便您曉得瀏覽器吸收的Service Worker在經由歷程收集中未被修正。

瀏覽器支撐

效勞人員的瀏覽器支撐正在變得愈來愈好:
《Javascript事情道理(八):Service Workers,生命周期和運用案例》

Service Worker運用場景

Service Worker供應的一些奇特功用是:

  • 推送關照 – 許可用戶挑選從收集運用程序實時更新。
  • 背景同步 – 許可您推延操縱,直到用戶具有穩固的銜接。如許,您可以確保不管用戶想要發送什麼,實際上都邑發送。
  • 按期同步(未支撐) – 供應治理按期背景同步功用的API。
  • Geofencing(將來支撐) – 您可以定義參數,也稱為繚繞感興趣地區的地輿圍欄。當裝備逾越地輿圍欄時,Web運用程序會收到關照,這可以讓您依據用戶的地輿位置供應有效的體驗。

推荐阅读
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • 本文介绍了如何通过conda安装Selenium的wheel文件,包括查看环境、卸载旧版本、下载新版本的wheel文件以及安装操作的步骤。同时提供了使用清华源的方法。 ... [详细]
  • 如何查询zone下的表的信息
    本文介绍了如何通过TcaplusDB知识库查询zone下的表的信息。包括请求地址、GET请求参数说明、返回参数说明等内容。通过curl方法发起请求,并提供了请求示例。 ... [详细]
  • 本文记录了在vue cli 3.x中移除console的一些采坑经验,通过使用uglifyjs-webpack-plugin插件,在vue.config.js中进行相关配置,包括设置minimizer、UglifyJsPlugin和compress等参数,最终成功移除了console。同时,还包括了一些可能出现的报错情况和解决方法。 ... [详细]
  • 解决github访问慢的问题的方法集锦
    本文总结了国内用户在访问github网站时可能遇到的加载慢的问题,并提供了解决方法,其中包括修改hosts文件来加速访问。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • 本文详细介绍了cisco路由器IOS损坏时的恢复方法,包括进入ROMMON模式、设置IP地址、子网掩码、默认网关以及使用TFTP服务器传输IOS文件的步骤。 ... [详细]
author-avatar
c_陈可儿
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有