动用 Service worker 创设贰个分外简单的离线页面

2016/06/07 · JavaScript
· 1 评论 · Service
Worker

本文由 伯乐在线 –
刘健超-J.c
翻译,艾凌风
校稿。未经许可,禁止转载!
英文出处:Dean
Hume。欢迎参与翻译组。

让大家想像以下境况:大家那时候在一辆通往农村的列车上,用运动装备望着一篇很棒的篇章。与此同时,当你点击“查看更多”的链接时,轻轨忽然进入了隧道,导致运动设备失去了互连网,而
web 页面会展现出类似以下的始末:

图片 1

worker实现加速,创建一个非常简单的离线页面。那是一定令人黯然的心得!幸运的是,web
开发者们能经过一些新特点来创新那类的用户体验。作者近来间接在折腾 ServiceWorkers,它给 web 带来的无尽恐怕性总能给自家惊喜。Service Workers
的杰出特质之一是允许你检查和测试网络请求的境况,并让您作出相应的响应。

在那篇小说里,我打算用此性情检查用户的脚下网络连接情形,要是没连接则赶回三个最佳简单的离线页面。即便那是叁个要命基础的案例,但它能给您带来启迪,让您精通运维并运转该个性是何其的简便!要是您没理解过
Service Worker,笔者提出您看看此 Github
repo,理解越来越多相关的音信。

在本案例初叶前,让我们先不难地探访它的劳作流程:

  1. 在用户第③遍访问我们的页面时,大家会安装 瑟维斯Worker,并向浏览器的缓存添加大家的离线 HTML 页面
  2. 下一场,假若用户打算导航到另一个 web
    页面(同三个网站下),但此时已断网,那么大家将赶回已被缓存的离线
    HTML 页面
  3. 而是,假如用户打算导航到其余一个 web
    页面,而此时网络已连续,则能照常浏览页面

html5 离线存储

动用Service worker达成加速/离线访问静态blog网站

2017/02/19 · JavaScript
· Service Worker

原稿出处: Yang
Bo   

方今极红基于Github
page和markdown的静态blog,分外适合技术的沉思和习惯,针对不一样的语言都有一对精粹的静态blog系统出现,如Jekyll/Ruby,Pelican/Python,Hexo/NodeJs,由于静态内容的特征分外适合做缓存来增长速度页面包车型地铁拜访,就采取Service
worker
来促成加快,结果是除了PageSpeed,CDN这几个常见的服务器和互连网加速之外,通过客户端达成了更好的拜会体验。

应用工具:VS二零一三

让大家开首吧

若果你有以下 HTML 页面。那纵然可怜基础,但能给您完全思路。

XHTML

<!DOCTYPE html>

1
<!DOCTYPE html>

进而,让我们在页面里登记 Service Worker,那里仅创立了该目的。向正要的
HTML 里添加以下代码。

JavaScript

<script> // Register the service worker // 注册 service worker if
(‘serviceWorker’ in navigator) {
navigator.serviceWorker.register(‘/service-worker.js’).then(function(registration)
{ // Registration was successful // 注册成功 console.log(‘ServiceWorker
registration successful with scope: ‘, registration.scope);
}).catch(function(err) { // registration failed 🙁 // 注册失利 🙁
console.log(‘ServiceWorker registration failed: ‘, err); }); }
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
// Register the service worker
// 注册 service worker
if (‘serviceWorker’ in navigator) {
    navigator.serviceWorker.register(‘/service-worker.js’).then(function(registration) {
    // Registration was successful
    // 注册成功
    console.log(‘ServiceWorker registration successful with scope: ‘, registration.scope);
}).catch(function(err) {
    // registration failed 🙁
    // 注册失败 🙁
    console.log(‘ServiceWorker registration failed: ‘, err);
   });
}
</script>

下一场,我们供给创立 Service Worker 文件并将其取名为
‘service-worker.js‘。大家打算用这些 Service Worker
拦截任何互联网请求,以此检查网络的连接性,并根据检查结果向用户再次来到最符合的情节。

JavaScript

‘use strict’; var cacheVersion = 1; var currentCache = { offline:
‘offline-cache’ + cacheVersion }; const offlineUrl =
‘offline-page.html’; this.addEventListener(‘install’, event => {
event.waitUntil( caches.open(currentCache.offline).then(function(cache)
{ return cache.addAll([ ‘./img/offline.svg’, offlineUrl ]); }) ); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
‘use strict’;
 
var cacheVersion = 1;
var currentCache = {
  offline: ‘offline-cache’ + cacheVersion
};
const offlineUrl = ‘offline-page.html’;
 
this.addEventListener(‘install’, event => {
  event.waitUntil(
    caches.open(currentCache.offline).then(function(cache) {
      return cache.addAll([
          ‘./img/offline.svg’,
          offlineUrl
      ]);
    })
  );
});

在上头的代码中,大家在设置 Service Worker
时,向缓存添加了离线页面。如若我们将代码分为几小块,可观望前几行代码中,作者为离线页面钦命了缓存版本和UGL450L。即便你的缓存有例外版本,那么您只需立异版本号即可简单地解除缓存。在大概在第三2
行代码,作者向那么些离线页面及其财富(如:图片)发出请求。在取得成功的响应后,我们将离线页面和有关财富丰富到缓存。

未来,离线页面已存进缓存了,大家可在急需的时候检索它。在同一个 ServiceWorker 中,大家需求对无互连网时回来的离线页面添加相应的逻辑代码。

JavaScript

this.add伊芙ntListener(‘fetch’, event => { // request.mode = navigate
isn’t supported in all browsers // request.mode = naivgate
并从未获得全数浏览器的支撑 // so include a check for Accept: text/html
header. // 由此对 header 的 Accept:text/html 举行把关 if
(event.request.mode === ‘navigate’ || (event.request.method === ‘GET’ &&
event.request.headers.get(‘accept’).includes(‘text/html’))) {
event.respondWith( fetch(event.request.url).catch(error => { //
Return the offline page // 重临离线页面 return caches.match(offlineUrl);
}) ); } else{ // Respond with everything else if we can //
重回任何大家能回去的东西 event.respondWith(caches.match(event.request)
.then(function (response) { return response || fetch(event.request); })
); } });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
this.addEventListener(‘fetch’, event => {
  // request.mode = navigate isn’t supported in all browsers
  // request.mode = naivgate 并没有得到所有浏览器的支持
  // so include a check for Accept: text/html header.
  // 因此对 header 的 Accept:text/html 进行核实
  if (event.request.mode === ‘navigate’ || (event.request.method === ‘GET’ && event.request.headers.get(‘accept’).includes(‘text/html’))) {
        event.respondWith(
          fetch(event.request.url).catch(error => {
              // Return the offline page
              // 返回离线页面
              return caches.match(offlineUrl);
          })
    );
  }
  else{
        // Respond with everything else if we can
        // 返回任何我们能返回的东西
        event.respondWith(caches.match(event.request)
                        .then(function (response) {
                        return response || fetch(event.request);
                    })
            );
      }
});

为了测试该成效,你可以利用 Chrome
内置的开发者工具。首先,导航到您的页面,然后假使设置上了 ServiceWorker,就开辟 Network 标签并将节流(throttling)改为
Offline。(译者注:若将节流设置为 Offline
没意义,则可经过关闭网络或许通过360朔州警卫禁止 Chrome 访问网络)

图片 2

假设您刷新页面,你应有能看到相应的离线页面!

图片 3

一旦您只想大约地质度量试该意义而不想写任何代码,那么你能够访问笔者已开立好的
demo。别的,上述总体代码能够在
Github repo 找到。

本人通晓用在此案例中的页面非常粗大略,但你的离线页面则在于你协调!若是您想深切该案例的剧情,你能够为离线页面添加缓存破坏(
cache busting),如:
此案例。

<!DOCTYPE html>
<html manifest="cache.manifest">       <!--manifest存储-->
<head lang="en">
    <meta charset="UTF-8">
    <title>html5 离线存储  小应用</title>
</head>
<body>
1.在服务器如,apache 的httpd.conf 添加
AddType text/cache-manifest .manifest
2.顶部添加  manifest存储
3.编辑 cache.manifest

cache.manifest(文件名)
//以下是文件内容,缓存了一张图片
CACHE MANIFEST
2.png

</body>
</html>

增长速度/离线访问只需三步

  • 首页添加注册代码

JavaScript

<script> if (‘serviceWorker’ in navigator) {
navigator.serviceWorker.register(‘/sw.js’); } </script>

1
2
3
4
5
<script>
if (‘serviceWorker’ in navigator) {
navigator.serviceWorker.register(‘/sw.js’);
}
</script>
  • 复制代码

将封存到你的网站根目录下

  • 修改不缓存域名列表及离线状态页面

在你的sw.js中修改

JavaScript

const ignoreFetch = [ /https?:\/\/cdn.bootcss.com\//,
/https?:\/\/static.duoshuo.com\//,
/https?:\/\/www.google-analytics.com\//,
/https?:\/\/dn-lbstatics.qbox.me\//, ];

1
2
3
4
5
6
const ignoreFetch = [
  /https?:\/\/cdn.bootcss.com\//,
  /https?:\/\/static.duoshuo.com\//,
  /https?:\/\/www.google-analytics.com\//,
  /https?:\/\/dn-lbstatics.qbox.me\//,
];

打开Chrome Dev Tools->Source,看看本人的blog都引用了何等第③方财富,各个加到忽略列表里。

图片 4

在根目录下添加offline.html,在没有网络且缓存中也尚无时利用,效果如下:

图片 5

在根目录下添加offline.svg,在无互联网时图片财富请求重临该公文。

图片 6

进展阅读

此外,还有多少个很棒的离线成效案例。如:Guardian 营造了一个具备 crossword
puzzle(填字游戏)的离线
web 页面 –
因而,尽管等待网络重连时(即已在离线状态下),也能找到一点乐趣。作者也援引看看
Google Chrome Github
repo,它包涵了成都百货上千不比的
Service Worker 案例 – 当中一部分施用案例也在那!

而是,借使您想跳过上述代码,只是想大约地通过三个库来拍卖相关操作,那么小编引进您看看
UpUp。那是1个轻量的剧本,能让你更自在地应用离线作用。

打赏接济我翻译愈来愈多好小说,多谢!

打赏译者

 html5 worker

增长速度效果

首页加速后,互联网请求从16降为1,加载时间从2.296s降为0.654s,获得了弹指间加载的结果。

图片 7

基于webpagetest

查看测试结果

using System;using System.Collections.Generic;using System.Linq;using System.Runtime.Serialization;using System.Web;namespace Test_One{ [DataContract] public class User { [DataMember] public string Name { get; set; } [DataMember] public string Password { get; set; } [DataMember] public string Email { get; set; } }}

using System;using System.Collections.Generic;using System.Linq;using System.Runtime.Serialization;using System.ServiceModel;using System.ServiceModel.Web;using System.Text;namespace Test_One{ [ServiceContract] public interface IUser { [OperationContract] [WebInvoke(Method = "GET", UriTemplate = "getuser/{name}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] User GetUserData(string name); [OperationContract] [WebInvoke(Method = "POST", UriTemplate = "checkuser", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] User CheckUserData(User user); }}

using System;using System.Collections.Generic;using System.Linq;using System.Runtime.Serialization;using System.ServiceModel;using System.ServiceModel.Web;using System.Text;namespace Test_One{ // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together. // NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging. public class UserService : IUserService { public User GetUserData(string name) { User user = new User(); user.Name = name; user.Email = "test@123.com"; return user; } public User CheckUserData(User user) { user.Name += "-test"; return user; } }}

<?xml version="1.0"?><configuration> <appSettings> <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> </appSettings> <system.web> <compilation debug="true" targetFramework="4.5" /> <httpRuntime targetFramework="4.5"/> </system.web> <system.serviceModel> <services> <service name="Test_One.UserService" behaviorConfiguration="RESTBehaviour"> <endpoint address="" binding="webHttpBinding" contract="Test_One.IUserService" behaviorConfiguration="ESEndPointBehavior"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name="RESTBehaviour"> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="true"/> </behavior> <behavior> <!-- To avoid disclosing metadata information, set the values below to false before deployment --> <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> <endpointBehaviors> <behavior name="ESEndPointBehavior"> <webHttp/> </behavior> </endpointBehaviors> </behaviors> <protocolMapping> <add binding="basicHttpsBinding" scheme="https" /> </protocolMapping> <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> </system.serviceModel> <system.webServer> <!-- To browse web app root directory during debugging, set the value below to true. Set to false before deployment to avoid disclosing web app folder information. --> <directoryBrowse enabled="true"/> <!--<modules runAllManagedModulesForAllRequests="true"/>--> <modules runAllManagedModulesForAllRequests="true"> <remove name="WebDAVModule" /> </modules> <handlers> <remove name="WebDAV" /> </handlers> </system.webServer></configuration>

打赏支持本人翻译越多好文章,谢谢!

任选一种支付情势

图片 8
图片 9

1 赞 3 收藏 1
评论

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
html5 worker 在服务器后台创建一个线程,加快程序运行。
<script>
    var w1 = new Worker('test.js');
    w1.postMessage('hi');
    w1.onmessage = function(ev){    //  把一部分数据处理交给  html5  worker处理,
        alert( ev.data );
    };
</script>
<!--
test.js 文件 

self.onmessage = function(ev){
    self.postMessage(ev.data + '妙味课堂');   // 对数据进行处理,再返回
};

-->
</body>
</html>

加紧/离线原理探索

图片 10图片 11学习网址:

至于小编:刘健超-J.c

图片 12

前端,在路上…
个人主页 ·
作者的篇章 ·
19 ·
    

图片 13

 内容编排 语言输入 桌面提示

什么是 Service worker

图片 14

如上图,Service
worker

是一种由Javascript编写的浏览器端代理脚本,位于你的浏览器和服务器之间。当叁个页面注册了二个
Service
worker
,它就能够挂号一多级事件处理器来响应如互联网请求和新闻推送这几个事件。Service
worker

能够被用来保管缓存,当响应2个网络请求时得以安插为回去缓存依然从网络获得。由于Service
worker

是基于事件的,所以它只在拍卖那几个事件的时候被调入内部存款和储蓄器,不用操心常驻内部存款和储蓄器占用财富导致系统变慢。

网站地图xml地图