Indulge in the beauty of life. Look at the stars and imagine yourself riding with them. — Marcus Aurelius, philosopher
- Wechat official account “JavaScript Full Stack”
- Nuggets’ Master of One ‘
- Bilibili, The Master of One
Performance is always a tradeoff in time and space, and optimization of computer systems requires a variety of caching strategies, from CPU to memory, from interfaces to peripherals. If one day hardware cost and implementation difficulty are no longer obstacles, there may be no such thing as “optimization.”
At present, the front-end is facing more optimization and challenges, complex terminal environment, a variety of different browser kernels, different sizes of browsing devices, compatibility to do. Complex and unstable network environment, more and more resources, optimization to do. We are not unfamiliar with caching, but we want to have subjective caching. We can decide what we want to cache, how long we want to cache, and what the strategy of caching and requesting resources is. The service worker can help us do this.
To use a service worker, you need to create a registration file. You can create a file called sw.js under your project
console.log('Hello, I am sw.js file')
Copy the code
Then register the service worker in the application through this file. The following code can complete the registration of the service worker in the application. The subsequent processing related to the service worker will be carried out in the sw.js file
<script>
// Check whether the current browser supports service workers
if ('serviceWorker' in navigator) {
// Make sure the resource is loaded before registering the service worker
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js');
});
}
</script>
Copy the code
Refresh the page and you can see that the console prints this sentence indicating that the service worker was successfully registered
Open the console Application and everything is under control. The service worker has been registered successfully
The service worker has been registered. For its configuration and processing, let’s define it in sw.js file.
Google’s standard unified API, Service Worker-based policy cache library has a few nice features
- Precaching
- Runtime caching
- Strategies
- Request routing
- Background sync
- Helpful debuggin
- Greater flexibility and feature set than sw-precache and sw-toolbox
I think of a sentence, simple concept complicated, popular concept mystery, this is to show their extraordinary, 😆, a joke. I believe that most people see these concepts as confusing, we just need to focus on one concept: caching, and it is strategic, and what can be controlled, but also gives us ideas for developing offline applications.
Using Workbox
Remember that sw.js file? Now we’re going to focus on it, because we’re going to do all the related stuff in this file. Ready? Go!
# # # import Workbox
Import workbox.js in the first line of sw.js with the following syntax
importScripts('https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js');
Copy the code
Does that make the import successful? Write some code to test it out!
if (workbox) {
console.log(`Yay! Workbox is the loaded 🎉 `);
} else {
console.log(`Boo! Workbox didn 't load 😬 `);
}
Copy the code
After the changes are completed, I will go back to the browser and refresh the browser without any changes. Here I need to remind you that after changing the service worker registration file, you need to terminate, restart or update it.
Get started with Workbox
Workbox defines a standard unified API. How can we use the API provided by Workbox to gradually optimize the project
Route request definition cache
In Workbox, the core concept is route-based policy caching. The key words here are route-based and policy caching. The next step is to focus on how to implement policies based on routing.
Most of the front-end resources are obtained through HTTP requests, including JS, CSS, images and so on. Since these contents need to be requested, can I do some processing after the request is issued? Just like the landlord renting a house, the information between the landlord and the tenant may be asymmetric, then the intermediary appears, it can do some processing before the landlord rents the house, such as adding intermediary fees. When a web page initiates a resource request, we can also make some decisions about whether to take it from the cache or request it. For different resources, it is the resource request address that is implemented, which is __ based on route __, as shown in the following example
workbox.routing.registerRoute(
/\.js$/,...). ;Copy the code
In this code, we define a routing caching policy, that is, all requests with the suffix.js will be processed in this policy. What processing should we do? There will be different caching policies defined for resources that match the route, for example, we require that resource network requests be specified first
workbox.routing.registerRoute(
/\.js$/.new workbox.strategies.NetworkFirst()
);
Copy the code
This cache will take effect if a JS file is introduced in the project, assuming that the project introduces hello.js
console.log('hello js file')
Copy the code
Introduced in HTML
<script src="./hello.js"></script>
Copy the code
Update the service worker when you go to the browser. Following the refresh, we can see the printed log indicating that the configuration was successful
All things are difficult at the beginning, so we have overcome the first problem. Now we will expand horizontally and choose different strategies for different types of file configuration. Let’s start by looking at the configuration for handling different files, which is very simple
String mode
workbox.routing.registerRoute(
'/logo.png',
handler // handler is a callback to the cache policy, usually referred to as' cache policy function '.
);
workbox.routing.registerRoute(
'https://some-host/some-path/logo.png',
handler
);
Copy the code
Regular expression
workbox.routing.registerRoute(
// Cache images./ \. (? :png|jpg|jpeg|svg|gif)$/, handler );Copy the code
Functional form
// Use the function to match the request route
const matchFunction = ({url, event}) = > {
// Return true if the request route matches, or return a parameter object for the handler to receive
return false;
};
workbox.routing.registerRoute(
matchFunction,
handler
);
Copy the code
The handler for this code is a cache policy API provided by WorkBox
Policy name | API |
---|---|
staleWhileRevalidate | If the requested route has the corresponding Cache result, it will directly return. When the Cache result is returned, the network request will be sent in the background to get the request result and update the Cache. If there is no Cache, the network request will be sent directly and return the result |
networkFirst | Network first policy |
cacheFirst | The result is fetched directly from the Cache. If there is no result in the Cache, the network request is made, the network request is fetched, the result is updated to the Cache, and the result is returned to the client |
networkOnly | Force a normal network request to be used |
cacheOnly | Use the cached result directly |
In common scenarios, the preceding five policies can meet the requirements. If the requirements are not met, you can customize policies
workbox.routing.registerRoute(
({url, event}) = > {
return {
name: 'workbox'
};
},
({url, event, params}) => {
// A guide on workbox is returned
return new Response(
`I am ${params.name}`); });Copy the code
Here is an example of how to use different policies
For example, image resources, which do not change very often, can be grouped under Application -> Cache
workbox.routing.registerRoute(
/ \. (? :png|jpg|jpeg|svg|gif)$/.new workbox.strategies.CacheFirst({
cacheName: 'my-image-cache',}));Copy the code
Js and other relevant files can be appropriately selected network priority
workbox.routing.registerRoute(
/\.html$/.new workbox.strategies.NetworkFirst()
);
workbox.routing.registerRoute(
/\.js$/.new workbox.strategies.NetworkFirst({
networkTimeoutSeconds: 3,}));Copy the code
Workbox is used in Webpack
First install the Workbox-webpack-plugin and choose to use the NPM installation
npm install --save-dev workbox-webpack-plugin
Copy the code
Configure the plug-in in the WebPack configuration file
const workboxPlugin = require('workbox-webpack-plugin');
// ...
webpack({
plugins: [
// ...
new workboxPlugin({
swSrc: './src/sw.js'.swDest: './dist/sw.js'.globDirectory: './dist/'.globPatterns: ['**/*.{html,js,css}'],})]// ...
});
Copy the code
To use the Webpack plug-in provided by Workbox, you must include the following code in app/sw.js to complete the pre-cached content list injection
workbox.precaching.precacheAndRoute(self.__precacheManifest || []);
Copy the code
At this point, can you imagine supporting offline access through our configuration of resources in the project? These configurations can greatly improve application performance, policy, and you want the best.
I am one, farewell hero!