You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Decouple routing and strategy logic from the PrecacheController class in order to:
Reduce bugs/confusion stemming from route order/precedence of precached routes.
Give developers more control over how assets are stored and served from the precache
Reduce bundle sizes for developers not using many of the existing built-in precaching options
Make it possible (in the future) to swap out PrecacheStrategy for a custom strategy
Background
The workbox-precaching package was recently updated to use modules from workbox-strategies and workbox-routing under the hood, but it did not change the API—which means the degree of decoupling was limited, and it could not fully address several issues:
With v6 being a major release and breaking changes being possible, this proposals continues the work started in #2459 and fully removes any custom route-matching or strategy-handling logic done in workbox-precaching. All of that work is now being done by subclasses of workbox-routing or workbox-strategy classes.
New modules
This proposal introduces several new modules (both public and private) to the workbox-precaching packages. These modules are largely self-contained and independent, so developers will only pay the cost for the modules they import:
PrecacheStrategy
PrecacheStrategy is a custom strategy that can populate the precache using the same logic currently used in v5. This includes:
Adding a request to the cache on install
Retrieving a request from the cache on fetch
Falling back to network on cache miss (without updating the cache)
Handling same-origin redirects
Handling opaque responses (if a cacheWillUpdate plugin callback isn't used).
Note, two items explicitly NOT handled by the PrecacheStrategy class are:
Handling revision cache keys
Generating a list of updated/not-updated URLs on install
These are handled by the PrecacheCacheKeyPlugin and PrecacheInstallReportPlugin plugins (respectively), and both of these plugins are added to the strategy by the PrecacheController on instantiation.
There are two primary reasons this logic is handled by plugins rather than PrecacheStrategy itself:
To avoid coupling of concerns between the PrecacheController (which maintains the precache manifest and cacheKey mapping) and the PrecacheStrategy (which handles how requests are fetched/cached).
To make it possible (in the future, not in v6) for a developer to use their own custom strategy (or a built-in strategy like CacheFirst) with precaching.
Note: while this proposal doesn't include any API changes to support custom precaching strategies, it does make it possible through module aliasing with a build tool. While this is not currently recommended, the fact that it does work validates the flexibility of the new design.
PrecacheRoute
PrecacheRoute is a custom route that gets created passing it a PrecacheController instance as well as the configuration options currently accepted by the addRoute() method in v5.
The route will use the urls-to-cache-keys map of the PrecacheController instance to determine whether an incoming request "matches", and it will use the strategy created by the controller as the handler. The matcher will also pass the cacheKey value as a custom param to the handler so it doesn't have to re-lookup that value.
Since the PrecacheRoute logic in v6 is separate from the PrecacheController logic, developers who don't need to use the configuration options can avoid bundling that logic in their service worker file.
PrecacheCacheKeyPlugin (not publicly exposed) is a custom plugin that gets automatically set on the strategy created by the PrecacheController.
The plugin contains a cacheKeyWillBeUsed callback to map request URLs to revisioned assets in the precache.
As mentioned above, the rationale for putting this logic into its own plugin (rather than as part of PrecacheStrategy) is that it can then be used with any other strategy as well.
Similar to PrecacheCacheKeyPlugin, the PrecacheInstallReportPlugin (not publicly exposed) gets automatically set on the strategy created by the PrecacheController, and it's responsible for generating the list of updated (and not updated) URLs during service worker installation.
For each handler instance run during the install event, if the URL is found in the cache already, it'll be added to the notUpdatedURLs array, otherwise it'll be added to the updatedURLs array.
Again, this logic is implemented via a plugin to make it possible for other strategies to be used with PrecacheController, and to make it possible for the PrecacheStrategy to be used as a runtime strategy (not sure if there are real use cases for this, but it would be technically possible).
Breaking changes
This proposal intentionally limits the amount of breaking changes to the top level function modules exported by workbox-precaching. Most of the breaking changes are scoped to the lesser-used PrecacheController class and to the recently-introduced (and also lesser-used) createHandler and createHandlerBoundToURL functions.
PrecacheController
Changes to the constructor() parameter{#changes-to-the-constructor-parameters}
In v5 the only option you could pass to the PrecacheController constructor was a single cacheName param. In v6 the PrecacheController will take an object in order to make it more extensible in the future.
The current set of accepted object properties is:
cacheName
plugins
fallbackToNetwork (defaults to true)
// In v5constpc=newPrecacheController('precache');pc.addPlugins([...])// In v6constpc=newPrecacheController({cacheName: 'precache',plugins: [...]});
In v5 the only way to add plugins was via the top-level addPlugins() function, or by passing them to the install() method of PrecacheController.
In v6, plugins are passed when creating the PrecacheController instance.
Lastly, in v6 the fallbackToNetwork option (previously set when calling createHandler() or createHandlerBoundToURL()) is now set when creating the PrecacheController instance, which means it will now the same setting will apply to all handled requests.
If a developer needs different fallback logic for different resources, they will need to create multiple PrecacheController instances.
Changes to the createHandlerBoundToURL() method parameter{#changes-to-the-createhandlerboundtourl-method-parameters}
The createHandlerBoundToURL method no longer accepts a second, fallbackToNetwork parameter.
As mentioned above, the fallback-to-network logic is now set on the PrecacheController instance itself (and applied to the PrecacheStrategy the controller creates upon instantiation) and thus it applies to all requests handled by the controller.
Note: the same change will be made to the top-level createHandlerBoundToURL() function, see below.
Changes to the install() method parameter{#changes-to-the-install-method-parameters}
The install method previously took an optional {event, plugins} config object. In v6 it will only take an event object, which will be required.
In addition (and not technically a breaking change), the install event will now automatically call event.waitUntil(), since it's easy for developers to forget that this is needed, which can cause installations to fail.
// In v5constpc=newPrecacheController();addEventListener('install',(event)=>event.waitUntil(pc.install({event})));// In v6constpc=newPrecacheController();addEventListener('install',pc.install);
Changes to the activate() method parameter{#changes-to-the-activate-method-parameters}
Similar to the install() method, the activate() method will also now require an event (previously it took no parameters), and that event will automatically call event.waitUntil().
// In v5constpc=newPrecacheController();addEventListener('activate',(event)=>event.waitUntil(pc.activate()));// In v6constpc=newPrecacheController();addEventListener('activate',pc.activate);
Remove the addRoute() method
Since this proposal introduces a new PrecacheRoute class, the addRoute() method on PrecacheController will be removed in favor of developers explicitly adding routes for precaching.
This will help prevent cases where the order of initializing precaching can affect what routes match particular requests:
// In v5constpc=newPrecacheController();// Adds a fetch event listener to match precaching requestspc.addRoute({...});// In v6constpc=newPrecacheController();// Creates and registers a route explicitly on the default router.registerRoute(newPrecacheRoute(pc,{...}))
Note: for better backwards compatibility, the top-level addRoute() function will continue to work as it does today, only the PrecacheController method is being removed.
Remove the precacheAndRoute() method
Since the addRoute() method is being removed (see above), it also makes sense to remove the precacheAndRoute() method from the PrecacheController class.
_Note: as with the addRoute() method, the top-level precacheAndRoute() function will continue to be available, it's just the PrecacheContoller method that's being removed.
Remove the createMatchCalback() metho{#remove-the-creatematchcalback-method}
The primary purpose of the createMatchCallback() method was to create a route to match precached assets, but with this proposal's addition of the PrecacheRoute class, this is no longer needed.
Remove the createHandler() method
Since the PrecacheController object now creates and exposes a strategy instance, and since all strategies have a handle() method, the createHandler() method of PrecacheController will be removed.
Developers who need a handler to respond to requests for precached assets can use the strategy directly:
// In v5constpc=newPrecacheController();registerRoute(({request})=>request.destination==='script',pc.createHandler(),)// In v6constpc=newPrecacheController();registerRoute(({request})=>request.destination==='script',pc.strategy,);
The createHandler() method also took a configuration option fallbackToNetwork, which defaulted to true. Developers who do not want their precaching logic to fall back to network can set this to false when creating the PrecacheController instance:
// In v5constpc=newPrecacheController();registerRoute(({request})=>request.destination==='script',pc.createHandler({fallbackToNetwork: false}),)// In v6constpc=newPrecacheController({fallbackToNetwork: false});registerRoute(({request})=>request.destination==='script',pc.strategy,);
createHandlerBoundToURL()
As with the changes to the createHandlerBoundToURL() method (mentioned above), the top-level createHandlerBoundToURL() method no longer accepts a second fallbackToNetwork parameter.
Developers who do not want the default behavior of falling back to network on precache misses will not be able to use the default precach controller, they'll need to create their own PrecacheController instance and set the fallbackToNetwork option to false.
createHandler()
As with the removal of the createHandler() method (mentioned above), the top-level createHandler() will be removed.
Developers who need to use a handler for precached assets will not be able to use the default precache controller, they'll need to create their own PrecacheController instance and use its strategy property.
Objective
Decouple routing and strategy logic from the
PrecacheController
class in order to:PrecacheStrategy
for a custom strategyBackground
The
workbox-precaching
package was recently updated to use modules fromworkbox-strategies
andworkbox-routing
under the hood, but it did not change the API—which means the degree of decoupling was limited, and it could not fully address several issues:With v6 being a major release and breaking changes being possible, this proposals continues the work started in #2459 and fully removes any custom route-matching or strategy-handling logic done in
workbox-precaching
. All of that work is now being done by subclasses ofworkbox-routing
orworkbox-strategy
classes.New modules
This proposal introduces several new modules (both public and private) to the workbox-precaching packages. These modules are largely self-contained and independent, so developers will only pay the cost for the modules they import:
PrecacheStrategy
PrecacheStrategy
is a custom strategy that can populate the precache using the same logic currently used in v5. This includes:cacheWillUpdate
plugin callback isn't used).Note, two items explicitly NOT handled by the
PrecacheStrategy
class are:These are handled by the
PrecacheCacheKeyPlugin
andPrecacheInstallReportPlugin
plugins (respectively), and both of these plugins are added to the strategy by thePrecacheController
on instantiation.There are two primary reasons this logic is handled by plugins rather than
PrecacheStrategy
itself:PrecacheController
(which maintains the precache manifest and cacheKey mapping) and thePrecacheStrategy
(which handles how requests are fetched/cached).CacheFirst
) with precaching.Note: while this proposal doesn't include any API changes to support custom precaching strategies, it does make it possible through module aliasing with a build tool. While this is not currently recommended, the fact that it does work validates the flexibility of the new design.
PrecacheRoute
PrecacheRoute
is a custom route that gets created passing it aPrecacheController
instance as well as the configuration options currently accepted by theaddRoute()
method in v5.The route will use the urls-to-cache-keys map of the
PrecacheController
instance to determine whether an incoming request "matches", and it will use the strategy created by the controller as the handler. The matcher will also pass thecacheKey
value as a custom param to the handler so it doesn't have to re-lookup that value.Since the
PrecacheRoute
logic in v6 is separate from thePrecacheController
logic, developers who don't need to use the configuration options can avoid bundling that logic in their service worker file.PrecacheCacheKeyPlugin (private)
PrecacheCacheKeyPlugin
(not publicly exposed) is a custom plugin that gets automatically set on the strategy created by thePrecacheController
.The plugin contains a
cacheKeyWillBeUsed
callback to map request URLs to revisioned assets in the precache.As mentioned above, the rationale for putting this logic into its own plugin (rather than as part of
PrecacheStrategy
) is that it can then be used with any other strategy as well.PrecacheInstallReportPlugin (private)
Similar to
PrecacheCacheKeyPlugin
, thePrecacheInstallReportPlugin
(not publicly exposed) gets automatically set on the strategy created by thePrecacheController
, and it's responsible for generating the list of updated (and not updated) URLs during service worker installation.For each handler instance run during the
install
event, if the URL is found in the cache already, it'll be added to thenotUpdatedURLs
array, otherwise it'll be added to theupdatedURLs
array.Again, this logic is implemented via a plugin to make it possible for other strategies to be used with
PrecacheController
, and to make it possible for thePrecacheStrategy
to be used as a runtime strategy (not sure if there are real use cases for this, but it would be technically possible).Breaking changes
This proposal intentionally limits the amount of breaking changes to the top level function modules exported by
workbox-precaching
. Most of the breaking changes are scoped to the lesser-usedPrecacheController
class and to the recently-introduced (and also lesser-used)createHandler
andcreateHandlerBoundToURL
functions.PrecacheController
Changes to the
constructor()
parameter{#changes-to-the-constructor-parameters}In v5 the only option you could pass to the
PrecacheController
constructor was a singlecacheName
param. In v6 thePrecacheController
will take an object in order to make it more extensible in the future.The current set of accepted object properties is:
cacheName
plugins
fallbackToNetwork
(defaults totrue
)In v5 the only way to add plugins was via the top-level
addPlugins()
function, or by passing them to theinstall()
method ofPrecacheController
.In v6, plugins are passed when creating the
PrecacheController
instance.Lastly, in v6 the
fallbackToNetwork
option (previously set when callingcreateHandler()
orcreateHandlerBoundToURL()
) is now set when creating thePrecacheController
instance, which means it will now the same setting will apply to all handled requests.If a developer needs different fallback logic for different resources, they will need to create multiple
PrecacheController
instances.Changes to the
createHandlerBoundToURL()
method parameter{#changes-to-the-createhandlerboundtourl-method-parameters}The
createHandlerBoundToURL
method no longer accepts a second,fallbackToNetwork
parameter.As mentioned above, the fallback-to-network logic is now set on the
PrecacheController
instance itself (and applied to thePrecacheStrategy
the controller creates upon instantiation) and thus it applies to all requests handled by the controller.Note: the same change will be made to the top-level
createHandlerBoundToURL()
function, see below.Changes to the
install()
method parameter{#changes-to-the-install-method-parameters}The install method previously took an optional
{event, plugins}
config object. In v6 it will only take anevent
object, which will be required.In addition (and not technically a breaking change), the install event will now automatically call
event.waitUntil()
, since it's easy for developers to forget that this is needed, which can cause installations to fail.Changes to the
activate()
method parameter{#changes-to-the-activate-method-parameters}Similar to the
install()
method, theactivate()
method will also now require an event (previously it took no parameters), and that event will automatically callevent.waitUntil()
.Remove the
addRoute()
methodSince this proposal introduces a new
PrecacheRoute
class, theaddRoute()
method onPrecacheController
will be removed in favor of developers explicitly adding routes for precaching.This will help prevent cases where the order of initializing precaching can affect what routes match particular requests:
Note: for better backwards compatibility, the top-level
addRoute()
function will continue to work as it does today, only thePrecacheController
method is being removed.Remove the
precacheAndRoute()
methodSince the
addRoute()
method is being removed (see above), it also makes sense to remove theprecacheAndRoute()
method from thePrecacheController
class._Note: as with the
addRoute()
method, the top-levelprecacheAndRoute()
function will continue to be available, it's just thePrecacheContoller
method that's being removed.Remove the
createMatchCalback()
metho{#remove-the-creatematchcalback-method}The primary purpose of the
createMatchCallback()
method was to create a route to match precached assets, but with this proposal's addition of thePrecacheRoute
class, this is no longer needed.Remove the
createHandler()
methodSince the
PrecacheController
object now creates and exposes a strategy instance, and since all strategies have ahandle()
method, thecreateHandler()
method ofPrecacheController
will be removed.Developers who need a handler to respond to requests for precached assets can use the strategy directly:
The
createHandler()
method also took a configuration optionfallbackToNetwork
, which defaulted totrue
. Developers who do not want their precaching logic to fall back to network can set this to false when creating thePrecacheController
instance:createHandlerBoundToURL()
As with the changes to the
createHandlerBoundToURL()
method (mentioned above), the top-levelcreateHandlerBoundToURL()
method no longer accepts a secondfallbackToNetwork
parameter.Developers who do not want the default behavior of falling back to network on precache misses will not be able to use the default precach controller, they'll need to create their own
PrecacheController
instance and set thefallbackToNetwork
option tofalse
.createHandler()
As with the removal of the
createHandler()
method (mentioned above), the top-levelcreateHandler()
will be removed.Developers who need to use a handler for precached assets will not be able to use the default precache controller, they'll need to create their own
PrecacheController
instance and use itsstrategy
property.Examples
Precaching an app shell
Precaching with custom routing
WIP Implementation
https://github.com/GoogleChrome/workbox/tree/precaching-v6
The text was updated successfully, but these errors were encountered: