This is a common source of confusion, so I wanted to go into a bit more detail.
I have a full working demo in this Gist, and you can view a live version of it thanks to RawGit.
Here's the relevant portion of the service worker code inline, for illustrative purposes:
self.addEventListener('fetch', event => {
if (event.request.url.endsWith('one.js')) {
// Requests for one.js will result in the SW firing off a fetch() request,
// which will be reflected in the DevTools Network panel.
event.respondWith(fetch(event.request));
} else if (event.request.url.endsWith('two.js')) {
// Requests for two.js will result in the SW constructing a new Response object,
// so there won't be an additional network request in the DevTools Network panel.
event.respondWith(new Response('// no-op'));
}
// Requests for anything else won't trigger event.respondWith(), so there won't be
// any SW interaction reflected in the DevTools Network panel.
});
And here's what a filtered version of the Network panel looks like in Chrome 48 when that service worker is in control of a page, and requests are made for one.js
, two.js
, and three.js
:
Our service worker's fetch
handler will do one of three things:
- If it's a request for
one.js
, it will fire off a fetch()
request for the same URL, and then call event.respondWith()
using that response. The first one.js
entry in the screenshot, the one with "(from ServiceWorker)" in the "Size" column, is there by virtue of the fact that we called event.respondWith()
inside the fetch
handler. The second one.js
entry in the screenshot, the one with the little gear icon next to it and "(from cache)" in the "Size" column, represents that fetch()
request that was made inside the service worker while responding to the event. Since the actual one.js
file was already in the HTTP cache at the point I took this screenshot, you see "(from cache)", but if the HTTP cache didn't have that response already, you would see an actual network request along with the response size.
- If it's a request for
two.js
, it will handle the request by constructing a new Response
object "from thin air". (Yes, you can do that!) In this case, we are calling event.respondWith()
, so there's an entry for two.js
with "(from ServiceWorker)" in the "Size" column. But unlike with one.js
, we're not using fetch()
to populate the response, so there's no additional entry in the Network panel for two.js
.
- Finally, if it's a request for
three.js
, our service worker's fetch
event handler won't actually call event.respondWith()
. From the perspective of the page, and also from the perspective of the Network panel, there's no service worker involvement with that request, which is why there's just a "(from cache)" rather than "(from ServiceWorker)" in the "Size" column.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…