Get Started(开始)
Create and Register a Service Worker File(创建和注册 Service Worker)
- Before we can use Workbox, we need to create a service worker file and register it to our website.(在使用Workbox之前,我们需要创建一个服务工作者文件并将其注册到我们的网站。)
<script>
if ('serviceWorker' in navigator) {// Use the window load event to keep the page load performant(使用窗口加载事件保持页面加载性能)window.addEventListener('load', () => {navigator.serviceWorker.register('/service-worker.js');});
}
</script>
- Looking in the “Application” tab in Chrome DevTools you should see your service worker registered.(在chrome devtools中的“application”选项卡中,您应该看到服务工作者已注册。)
- Click the “Update on reload” checkbox to make it easier to develop with your new service worker.(单击 “Update on reload” 复选框,以便与新的 service worker 一起开发。)
Importing Workbox(导入工作框)
- To start using Workbox you just need to import the workbox-sw.js file in your service worker.(要开始使用Workbox,只需在服务工作者中导入Workbox-sw.js文件。)
- Importing workbox-sw.js will create a workbox object inside of your service worker, and that instance is responsible for importing other helper libraries, based on the features you use.(导入workbox-sw.js将在服务工作者内部创建一个workbox对象,该实例负责根据您使用的功能导入其他助手库。)
- Due to restrictions in the service worker specification, these imports need to happen either inside of an install event handler, or synchronously in the top-level code for your service worker.(由于 service worker 规范中的限制,这些导入需要在安装事件处理程序内部或在服务工作者的顶级代码中同步进行。?)
importScripts('https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js'); // 同步的if (workbox) {console.log(`Yay! Workbox is loaded ?`);
} else {console.log(`Boo! Workbox didn't load ?`);
}
Using Workbox
- The easiest way to do this is to register a route with Workbox that will match any .js files that are requested, which we can do with a regular expression:(在Workbox中注册一个路由,这里我们使用正则表达式去匹配请求的任何.js文件)
- If we want our JavaScript files to come from the network whenever possible, but fallback to the cached version if the network fails, we can use the “network first” strategy to achieve this.(如果我们希望我们的javascript文件尽可能来自网络,但是如果网络失败,我们可以回退到缓存版本,我们可以使用“network first”策略来实现这一点。)
workbox.routing.registerRoute(new RegExp('.*\.js'),new workbox.strategies.NetworkFirst()
);
- Add this code to your service worker and refresh the page. If your web page has JavaScript files in it, you should see some logs similar to this:(在控制台会有相应策略的打印提醒)
- Workbox provides a few caching strategies that you can use.(Workbox提供了一些您可以使用的缓存策略。)
- your CSS could be served from the cache first and updated in the background(可以先从缓存中提供CSS,然后在后台进行更新。)
workbox.routing.registerRoute(// Cache CSS files./\.css$/,// Use cache but update in the background.new workbox.strategies.StaleWhileRevalidate({// Use a custom cache name.(使用自定义缓存名称。?)cacheName: 'css-cache',})
);
- your images could be cached and used until it’s a week old, after which it’ll need updating.(使图像被缓存并使用一周,一周后才更新。)
workbox.routing.registerRoute(// Cache image files./\.(?:png|jpg|jpeg|svg|gif)$/,// Use the cache if it's available.(如果缓存可用,请使用它。)new workbox.strategies.CacheFirst({// Use a custom cache name.cacheName: 'image-cache',plugins: [new workbox.expiration.Plugin({// Cache only 20 images.(只有20个图像)maxEntries: 20,// Cache for a maximum of a week.(最多一周的缓存。)maxAgeSeconds: 7 * 24 * 60 * 60,})],})
);
What Else Can Workbox Do?
- Routing and caching strategies are performed by the routing and strategies modules, but there are plenty of other modules, each offering specific behaviors that you can use in your service worker.(路由和缓存策略是由路由和策略模块执行的,但是还有许多其他模块,每个模块都提供可以在服务工作者中使用的特定行为。)
Precache Files(预缓存文件)
- If you want your web app to work offline or there are assets you know can be cached for a long time, precaching is the best approach.(当需要离线使用网页或有需要加载很久的资源时,使用预缓存)
- Workbox provides an easy way to precache files, ensuring that as your service worker changes, the precached files are maintained efficiently, only downloading updated files and cleaning up after the service worker is made redundant.(Workbox提供了一种简单的预缓存文件的方法,确保随着服务工作者的更改,预缓存文件得到有效的维护,只下载更新的文件,并在服务工作者被冗余后进行清理。)
- The above snippet will download the files /styles/index.0c9a31.css, /scripts/main.0d5770.js and /index.html during the service worker install event and create a route that serves these files directly from the cache.(上述代码段将在ServiceWorker安装事件期间下载文件/styles/index.0c9a31.css、/scripts/main.0d5770.js和/index.html,并创建直接从缓存为这些文件提供服务的路由。)
- This list of files is normally generated using a tool that manages the versioning of files.(此文件列表通常使用管理文件版本控制的工具生成。)
workbox.precaching.precacheAndRoute(['/styles/index.0c9a31.css','/scripts/main.0d5770.js',{ url: '/index.html', revision: '383676' },
]);
Generating a Precache Manifest(生成预缓存清单)
- Below is a list of tools that can generate this list of files.(下面是可以生成此文件列表的工具列表。)
- Workbox Command Line Interface (CLI):Ideal for developers who are unfamiliar with Node or have simple needs.(非常适合不熟悉节点或有简单需求的开发人员。)
- workbox Build:Perfect for developers wanting to programmatically build the list in Node or are using Gulp for their build process.(非常适合希望以编程方式在节点中构建列表或在其构建过程中使用Gulp的开发人员。)
- Workbox Webpack Plugin:Ideal for developers using webpack to build their project.(非常适合使用Webpack构建项目的开发人员。)
CLI(Precache Files with Workbox CLI)
Gulp or Node(Precache Files with workbox-build)
Webpack(Precache Files with Webpack)
Route Requests(路由请求)
- There are three ways developers can match a request with workbox-routing.(开发人员可以通过三种方式将请求与Workbox路由相匹配。)
- A string.
- A regular expression.(正则表达式。)
- A callback function.(回调函数。)
Matching a Route with a String(将路由与字符串匹配)
- The only thing to be wary of is that this would only match for requests on your origin. (这只会与源站上的请求匹配。)
workbox.routing.registerRoute('/logo.png',handler // 这里应该是处理程序,这个例子先用handler占个位置,以下同
);
- Instead you’d need to define the entire URL to match.(匹配源之外的路径,需要定义整个URL来匹配。)
workbox.routing.registerRoute('https://some-other-origin.com/logo.png',handler
);
Matching a Route with a Regular Expression(将路由与正则表达式匹配)
- The regular expression provided is tested against the full URL.(提供的正则表达式根据完整的URL进行测试)
workbox.routing.registerRoute(new RegExp('\\.js$'),jsHandler
);workbox.routing.registerRoute(new RegExp('\\.css$'),cssHandler
);workbox.routing.registerRoute(new RegExp('/blog/\\d{4}/\\d{2}/.+'),handler
);
- If we wanted a route that would match that general path pattern made against both same- and cross-origin requests, using a regular expression with a wildcard (.+)at the start is one approach:(如果我们想要一个路由与针对相同和跨源请求的常规路径模式相匹配,那么在开始使用带有通配符(.+)的正则表达式是一种方法:?不在头部添加通配符,只能匹配同源的?)
workbox.routing.registerRoute(new RegExp('.+/blog/\\d{4}/\\d{2}/.+'),handler
);
Matching a Route with a Callback Function(将路由与回调函数匹配)
- The callback will receive an object with the requests URL and the FetchEvent received in the service worker.(回调将接收一个对象,该对象具有在 service worker 中接收到的请求URL和FetchEvent。)
- One thing to note is that if you return a value in the match callback, it’ll be passed into the handler callback as a params argument.(如果在matchFunction回调中返回一个值,它将作为params参数传递到处理程序回调handler中。)
const matchFunction = ({url, event}) => {// Return true if the route should match // 路由匹配则返回 truereturn false;
};workbox.routing.registerRoute(matchFunction,handler
);
——————————————————————
- There are two ways you can handle a request:(有两种方法可以处理请求:)
- Use one of Workbox’s strategies provided by workbox.strategies.(使用Workbox.Strategies提供的Workbox策略)
- Provide a callback function that returns a Promise that resolves to a Response(提供一个回调函数,该函数返回解析为响应的承诺?)
Handling a Route with a Workbox Strategy(使用 Workbox 策略处理路由)
- Most routes can be handled with one of the built in caching strategies.(大多数路由都可以通过一种内置的缓存策略来处理。)
- Stale While Revalidate(缓存优先,随后更新):This strategy will use a cached response for a request if it is available and update the cache in the background with a response form the network. (If it’s not cached it will wait for the network response and use that). (如果请求可用,则此策略将使用缓存响应,并使用来自网络的响应在后台更新缓存。(如果没有缓存,它将等待网络响应并使用该响应)。)
- Network First(网络优先):This will try and get a request from the network first. If it receives a response, it’ll pass that to the browser and also save it to a cache. If the network request fails, the last cached response will be used.(这将尝试首先从网络获取请求。如果它收到一个响应,它将把它传递给浏览器,并将其保存到缓存中。如果网络请求失败,将使用上次缓存的响应。)
- Cache First(缓存优先,不更新):This strategy will check the cache for a response first and use that if one is available. If the request isn’t in the cache, the network will be used and any valid response will be added to the cache before being passed to the browser.(此策略将首先检查缓存。如果请求不在缓存中,则将使用网络,并在传递到浏览器之前将任何有效响应添加到缓存中。)
- Network Only(强制网络):Force the response to come from the network.(强制响应来自网络。)
- Cache Only(强制缓存):Force the response to come from the cache.
workbox.routing.registerRoute(match,new workbox.strategies.StaleWhileRevalidate()
);workbox.routing.registerRoute(match,new workbox.strategies.NetworkFirst()
);workbox.routing.registerRoute(match,new workbox.strategies.CacheFirst()
);workbox.routing.registerRoute(match,new workbox.strategies.NetworkOnly()
);workbox.routing.registerRoute(match,new workbox.strategies.CacheOnly()
);
- With each strategy you can customize the behavior of the Route by defining a custom cache to use and / or adding plugins.(每个策略,您可以定义要使用的缓存名 和 添加插件来定制路由的行为。定义相同的缓存名会怎样?有什么意义?一个缓存名可以保存一组缓存数据,不同的缓存名是为了保存同一个接口不同的返回数据吗?)
- These options are often needed to make it safer when caching requests (i.e. limiting how long they are cached or making sure the data used on a device is limited).(缓存请求时,通常需要这些选项以使其更安全。例如:限制缓存的时间或保存空间)
new workbox.strategies.StaleWhileRevalidate({// Use a custom cache for this route.(为此路由使用自定义缓存。)cacheName: 'my-cache-name',// Add an array of custom plugins (like workbox.expiration.Plugin).(添加一组自定义插件,例如 workbox.expiration.Plugin)plugins: [...]
});
Handling a Route with a Custom Callback(使用自定义回调处理路由)
- you can provide an asyncfunction which returns a Response object.(传入一个返回 Response 对象的Async Function来处理。)
- Fetch API 的 Response 接口代表一次请求的响应数据
- It'll be called with a parameter object containing url and event (the FetchEvent) properties.(它将接收 URL 和 fetchvent 事件对象)
const handler = async ({url, event}) => {return new Response(`Custom handler response.`);
};workbox.routing.registerRoute(match, handler);
- One thing to note is that if you return a value in the match callback, it’ll be passed into the handler callback as a params argument.(如果在match回调中返回一个值,它将作为params参数传递到处理程序回调中。)
const match = ({url, event}) => {return {name: 'Workbox',type: 'guide',};
};const handler = async ({url, event, params}) => {// Response will be "A guide to Workbox"return new Response(`A ${params.type} to ${params.name}`);
};workbox.routing.registerRoute(match, handler);
- By default, Workbox will only create two caches, one for precaching and one for runtime caching. Using workbox-core you can get the current cache names like so:(默认情况下,Workbox将只创建两个缓存,一个用于预缓存,另一个用于运行时缓存。使用Workbox Core,您可以获得当前缓存名称,如下所示:)
const precacheCacheName = workbox.core.cacheNames.precache;
const runtimeCacheName = workbox.core.cacheNames.runtime;
- Both the precache and runtime cache names are made of three pieces of information:
<prefix>-<cacheId>-<suffix>
(预缓存和运行时缓存名称都由三条信息组成:) - You can alter the cache names by altering all or some of these pieces of information:(可以通过更改以下信息来更改缓存名称:)
- We recommend changing the prefix for each of your projects. This allows you to work on multiple projects using the same localhost port number without mixing up the caches.(我们建议更改每个项目的前缀。这允许您使用相同的本地主机端口号处理多个项目,而不会混淆缓存。)
workbox.core.setCacheNameDetails({prefix: 'my-app',suffix: 'v1',precache: 'custom-precache-name',runtime: 'custom-runtime-name'
});
Custom Cache Names in Strategies(策略中自定义缓存名称)
- but it’s not uncommon to want additional caches for specific uses, such as a cache just for images.(需要额外的缓存用于特定用途并不少见,例如只用于图像的缓存。)
- In these cases, the cache name will be used exactly as you specify; the prefix and suffix will not be used.(在这些情况下,缓存名称将完全按照您指定的方式使用。不会出现前缀和后缀)
/\.(?:png|jpg|jpeg|svg|gif)$/,new workbox.strategies.CacheFirst({cacheName: 'my-image-cache',})
);
Custom Fetch Options in Strategies(策略中自定义提取选项)
- you might find the need to customize some aspects of the outgoing requests.you can pass in a configuration value named fetchOptions to a strategy's constructor, corresponding to the init options used in the underlying Fetch API. (您可能会发现需要自定义传出请求的某些方面。您可以将名为fetchOptions的配置值传递给策略的构造函数,对应于底层fetch api中使用的init选项。)
workbox.routing.registerRoute(new RegExp('https://third-party\\.example\\.com/'),new workbox.strategies.NetworkFirst({fetchOptions: {credentials: 'include',},})
);