sw-precache使用指南

文章目录

    • 安装
    • 准备工作
    • 示例
    • 注意事项
    • 命令行界面
    • 实时缓存

Service Worker Precache是一个能自动生成Service Worker文件的模块,你可以利用它来预先缓存资源。它可以和你的构建过程集成在一起,一旦配置完成,它就可以识别你的站点中所有静态资源(HTML,JavaScript,CSS,图片等)并生成每个文件内容的哈希值。每个静态资源的网址、版本信息的哈希值都存储在生成的Service Worker文件中,当客户端发起向这些静态资源的网络请求时,Service Worker会优先返回缓存中的相应资源,并且当之后的构建过程中改变了这些资源后,Service Worker也会更新相应的资源。

优先从本地提供已经缓存的静态资源 ,使得你可以获取你的网络应用程序所有关键的支持文件而无需等待任何网络响应。

该模块可以在基于JavaScript的构建脚本中使用,例如使用gulp编写的脚本,同时它也提供了命令行界面。你可以直接使用模块,或者如果你愿意的话,也可以对sw-precache进行包装以配合特定的构建环境,例如webpack。

sw-precache可以与sw-toolbox一起使用,sw-toolbox可以为动态资源提供更好的缓存机制。

安装

本地构建集成:

$ npm install --save-dev sw-precache

全局命令行界面:

$ npm install --global sw-precache

准备工作

  1. 确保你的网站使用HTTPS访问。Service Worker功能仅在通过HTTPS访问的页面上可用(在localhost也可以使用,以方便本地测试)。之所以会设置这个限制,Prefer Secure Origins For Powerful New Features一文描述了相关原理;
  2. 将sw-precache整合到你的构建脚本中。它可以与gulp、Grunt或其他以node.js编写的构建脚本良好地配合。我们在demo 文件夹中提供了两个例子,demo中的每个构建脚本都有一个名为writeServiceWorkerFile()的函数,它显示了如何使用对应的API。 这两个脚本都可以生成功能完备的JavaScript代码,这些代码负责预先缓存和获取你的网站脱机工作时需要的所有资源。我们还提供了一个一个命令行界面,方便那些使用其它构建方式的人使用;
  3. 注册service worker文件。你需要将生成的JavaScript文件注册为控制你的网站的service worker。通常这只需要在你的网站的顶级的入口页面中完成,因为service worker一旦在根目录注册,就会自动包含根目录以下的所有页面。service-worker-registration.js是一个示例脚本,它说明了注册service worker以及处理各种生命周期事件的最佳实践。

示例

项目的示例文件gulpfile.js说明了如何在适当的环境中使用sw-precache(注意:这里的示例文件是demo文件夹下的,而不是根目录下的)。我可以通过克隆此repo来运行示例,使用npm install下载依赖项,进入demo文件夹,运行npm bin 或者gulp serve-dist,然后访问localhost:3000查看效果。

还有一个示例Gruntfile.js,说明了如何使用Grunt中生成service worker。 虽然它不能像gulp一样在本地运行。

这里有一个更简单的gulp示例,它假定你的网站的资源都位于app文件夹下,并且你想要缓存所有的JavaScript,HTML,CSS和图片文件。

gulp.task('generate-service-worker', function(callback) {
  var path = require('path');
  var swPrecache = require('sw-precache');
  var rootDir = 'app';

  swPrecache.write(`${rootDir}/service-worker.js`), {
    staticFileGlobs: [rootDir + '/**/*.{js,html,css,png,jpg,gif,svg,eot,ttf,woff}'],
    stripPrefix: rootDir
  }, callback);
});

这个任务将在app文件夹下创建service-worker.js文件,你需要在使用这个文件前在你的页面里注册它,你也可以直接使用我们已经编写好的service-worker-registration.js来进行注册。

注意事项

  1. service worker应该是渐进增强的。如果你只在浏览器支持service worker时才注册它(可以通过'serviceWorker' in navigator来判断),那么你可以在支持service worker的浏览器上获得离线支持,但在不支持service worker的浏览器上,对应的离线支持的代码永远不会被调用。如此,在老旧的浏览器上使用sw-precache并不会产生额外开销。
  2. 只要service worker一安装,所有预先缓存的资源都会由service worker在一个单独的线程中获取,因而当你在dynamicUrlToDependenciesstaticFileGlobs选项中列出需要缓存资源时需要谨慎,因为列出那些非必要的文件,比如不是每个页面都需要的图片,会导致浏览器下载更多不必要的数据。
  3. 预缓存所有类型的资源并没有意义(见上一点)。其他缓存策略,如在offline cookbook中概述的那些策略,可以和sw-precache结合使用,从而为你的用户提供最好的体验。如果你自己实现了额外的缓存逻辑,请把代码放在一个单独的JavaScript文件中,并使用importScripts()方法来引入。
  4. sw-precache使用了缓存优先策略,浏览器会会在没有询问服务器的情况下返回文件的缓存版本。使用此策略时,一个建议的方案是,当有新内容可用时提醒用户,并给予他们重新加载页面以获取新内容的机会(service worker已将新内容添加到缓存中,并在刷新页面时显示)。示例的service-worker-registration.js文件说明了你可以通过关注service worker生命周期事件来触发此类消息。

命令行界面

对于那些不喜欢使用sw-precache作为gulp或Grunt构建系统的一部分的人,我们也提供一个命令行界面,它支持API中列出的选项,可以通过外部JavaScript文件等方式引入各种配置。

注意:如果不使用相应的自动构建系统而是使用命令行,则每次对本地资源进行更改时,你都需要重新运行命令行。如果不重新运行sw-precache,则以前缓存的本地资源将会一直使用。

如果没有具体设置选项,则会使用默认值。例如,在包含你的网站内容的顶级目录中,如果你想生成一个缓存所有本地资源的·service-worker.js·文件,则可以简单地运行:

$ sw-precache

或者,如果您只想缓存位于dist 文件夹(当前目录中的子目录)中的html文件,则可以运行:

$ sw-precache --root=dist --static-file-globs='dist/**/*.html'

注意:一定要在对shell有特殊含义的参数值(例如上面示例命令行中的*字符)中使用引号。

最后,可以使用--config 来传递复杂的配置。文件中的任何选项都可以通过命令行标志覆盖。 我们强烈建议通过module.exports传递一个外部JavaScript文件来定义config。例如,假设有一个path/to/sw-precache-config.js文件,其中包含:

module.exports = {
  staticFileGlobs: [
    'app/css/**.css',
    'app/**.html',
    'app/images/**.*',
    'app/js/**.js'
  ],
  stripPrefix: 'app/',
  runtimeCaching: [{
    urlPattern: /this\\.is\\.a\\.regex/,
    handler: 'networkFirst'
  }]
};

可以通过以下方式将该文件传递到命令行界面,同时设置verbose选项:

$ sw-precache --config=path/to/sw-precache-config.js --verbose

这种方式灵活性最高,例如可以为runtimeCaching.urlPattern选项提供正则表达式。我们也支持传递--configJSON文件,尽管这种方式灵活性要差一些:

{
  "staticFileGlobs": [
    "app/css/**.css",
    "app/**.html",
    "app/images/**.*",
    "app/js/**.js"
  ],
  "stripPrefix": "app/",
  "runtimeCaching": [{
    "urlPattern": "/express/style/path/(.*)",
    "handler": "networkFirst"
  }]
}

实时缓存

有时候需要同时使用预先缓存与实时缓存。也许你知道我们的sw-toolbox工具,它可处理实时缓存,但是想知道如何能同时使用sw-precache与sw-toolbox。幸运的是,sw-precache已经为你处理好了。

sw-precache模块可以引入sw-toolbox并且同时对它们进行配置。在sw-precache中使用runtimeCaching配置选项是一种更为便捷的配置方式,你不再需要手动引入sw-toolbox并编写自己的路由规则。如果使用此选项,则使用指定的缓存策略配置的sw-toolbox将自动包含在生成的service worker文件中。

配置选项数组中的每个对象都需要一个urlPattern,它是一个正则表达式或一个字符串,遵循sw-toolbox的配置约定。此外,还需要一个handler,它应该对应于sw-toolbox内置的处理程序。可选的选项包括:添加方法以指定一个受支持的HTTP方法(默认值为get)。

例如,下面的配置为两种不同URL模式定义了实时缓存行为。它对两种请求使用不同的处理程序,并为/articles/模式相匹配的请求指定了最大可用缓存:

runtimeCaching: [{
  urlPattern: /^https:\/\/example\.com\/api/,
  handler: 'networkFirst'
}, {
  urlPattern: /\/articles\//,
  handler: 'fastest',
  options: {
    cache: {
      maxEntries: 10,
      name: 'articles-cache'
    }
  }
}]

sw-toolbox提供五种针对网络请求的处理程序(handler),具体如下表:

  1. networkFirst:首先尝试通过网络来处理请求,如果成功就将响应存储在缓存中,否则返回缓存中的资源来回应请求。它适用于以下类型的API请求,即你总是希望返回的数据是最新的,但是如果无法获取最新数据,则返回一个可用的旧数据。
  2. cacheFirst:如果缓存中存在与网络请求相匹配的资源,则返回相应资源,否则尝试从网络获取资源。 同时,如果网络请求成功则更新缓存。此选项适用于那些不常发生变化的资源,或者有其它更新机制的资源。
  3. fastest:从缓存和网络并行请求资源,并以首先返回的数据作为响应,通常这意味着缓存版本则优先响应。一方面,这个策略总会产生网络请求,即使资源已经被缓存了。另一方面,当网络请求完成时,现有缓存将被更新,从而使得下次读取的缓存将是最新的。
  4. cacheOnly:从缓存中解析请求,如果没有对应缓存则请求失败。此选项适用于需要保证不会发出网络请求的情况,例如在移动设备上节省电量。
  5. networkOnly:尝试从网络获取网址来处理请求。如果获取资源失败,则请求失败,这基本上与不使用service worker的效果相同。

sw-toolbox选项中的cache选项可以指定缓存的最大数目以及缓存时间等,具体如下:

  1. cache.name[String]:用于存储实时缓存对象的缓存名称。使用唯一的名称允许您自定义缓存的最大空间和缓存时间。默认值:在运行时根据service worker的registration.scope值生成。
  2. cache.maxEntries[Number]:对缓存的项目实施least-recently缓存过期策略,可以将此项用于动态资源缓存。例如,将cache.maxEntries设置为10意味着在第11个项目被缓存之后,最近最少使用的条目将被自动删除。缓存永远不会超过cache.maxEntries规定的最大数量。此选项将仅在同时设置了cache.name时生效,它可以单独使用或与cache.maxAgeSeconds一起使用。默认值为空。
  3. cache.maxAgeSeconds[Number]:强制规定缓存项目的最大期限(以秒为单位),你可以用这个选项来存储没有自然过期策略的动态资源。例如,可以将cache.maxAgeSeconds设置为例如60 * 60 * 24,这意味着任何超过一天之前的缓存都将被自动删除。此选项仅在同时设置了cache.name时生效,它也可以单独使用或与cache.maxEntries一起使用。默认值为空。

你可能感兴趣的:(技术世界,service,worker,博客优化,网站提速)