Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can we make to avoid to invoke ServiceWorker _by default_ for if user code call event.addRoutes(rules) in install event handler? #1712

Open
tetsuharuohzeki opened this issue Mar 19, 2024 · 5 comments

Comments

@tetsuharuohzeki
Copy link

Motivation

event.addRoutes(rules) was introduced by #1701 whose motivation is explained in https://github.com/WICG/service-worker-static-routing-api to reduce the overhead to intercept by ServiceWorker.

According to the motivation, I seem our ideal status resolved by this API is ServiceWorker works as opt-in mode if a user code calls event.addRoutes().

I think almost combinations of RouterRule would be nice to work like opt-in semantics. However, there are some cases that are not intuitive combinations.

For example, the explainer illustrates Bypassing ServiceWorker for particular resources case. This case say that ServiceWorker to behave as just as opt-out for some network request path

// This example is cited from the explainer.
// I think this shows opt-out behavior semantics.
// -----

// Go straight to the network and bypass invoking "fetch" handlers for URLs that start
// with '/videos/' and '/images/'.
addEventListener('install', (event) => {
  event.addRoutes([{
    condition: {
      urlPattern: new URLPattern({pathname: "/images/*"})
    },
    source: "network"
  },
  {
    condition: {
      urlPattern: new URLPattern({pathname: "/videos/*"})
    },
    source: "network"
  }]);
});

On the other hands, if RouterRule.source is "fetch-event” or cache, ServiceWorker would work like as opt-in for registered conditions by the spec.

// By the current spec, this indicates ServiceWorker should wake up
// and intercept for URLs with `/assets/`. I seem this shows opt-in behavior semantics.
addEventListener('install', (event) => {
  event.addRoutes([{
    condition: {
      urlPattern: new URLPattern({pathname: "/assets/*"})
    },
    source: "cache"
  },

If I don't misunderstand the spec, I think this API semantics inconsistency may confuse a developer.

Idea

I also propose a rough idea to resolve this behavior inconsistencies.

  1. Introduce a new internal mode that ServiceWorker behaves like a pass through mode.
    1. Under this mode, ServiceWorker only works with registered conditions.
    2. For other (non-registered) conditions, ServiceWorker does not startup.
  2. Make ServiceWorker to pass through mode if user calls event.addRoutes() once in the install event handler.
    1. Luckily, event.addRoutes() is a newly introduced API. That method does not exist on old UAs. If user code does not call event.addRoutes(), ServiceWorker can work as a traditional style that intercept for all network requests implicitly.
    2. For UAs that had been shipped event.addRoutes() (Google Chrome), they can just ignores some patterns of conditions to keep a backword compatibility.
@tetsuharuohzeki tetsuharuohzeki changed the title Can we make to avoid to invoke ServiceWorker _by default_ for if user code call **~event.addRoutes(rules)~** in install event handler? Can we make to avoid to invoke ServiceWorker _by default_ for if user code call event.addRoutes(rules) in install event handler? Mar 19, 2024
@yoshisatoyanagisawa
Copy link
Collaborator

I guess we are in a different mental model. You might want addRoutes() to be a destructive behavior change, while I expect addRoutes() as just addition of the behavior. That is why I wrote "allows them to offload simple things ServiceWorkers do" in #1701.

addRoutes() just adds router rules before the default route (i.e. "fetch-event"). When people add routes, it is evaluated and executed before the default route. If no routes are added, it just goes to the default route. If you want to completely skip the fetch handler, you can explicitly add a rule to catch all to go to "network" before the default route.

What do you think?

@tetsuharuohzeki
Copy link
Author

@yoshisatoyanagisawa

If you want to completely skip the fetch handler, you can explicitly add a rule to catch all to go to "network" before the default route.

My intention of this proposal is that a developer can skip to write such thing.

I think we have a optimization chance and I guess this not might cause a destructive behavior change.

First, I think that we can regard as that calling InstallEvent.addRoutes() is an developer’s sign for optimization for an user agent. On a user agenet that does not support it, an user application will not call it. It would not a violate an exist code even if InstallEvent.addRoutes() introduce a new internal concept that allows some optimizations. And this assmption would not be against to the original motivation of #1701, I think.

Second, an application can call InstallEvent.addRoutes() only in install event handler. fetch event would a wait to complete install. There are lifecycle order. If an application did call InstallEvent.addRoutes(), user agent can firefetch event under this proposal’s assumption. On the contrary, if an application does not call InstallEvent.addRoutes(), user agent should fire fetch event with the traditional manner.

Third, I think this proposal can reduce a application code with the achievement of static routing API’s motivation.

Eventually,

@tetsuharuohzeki
Copy link
Author

Eventually,

Oops. I forgot to remove this word from my draft....

@yoshisatoyanagisawa
Copy link
Collaborator

You can find sites using the ServiceWorker static routing API in https://chromestatus.com/metrics/feature/timeline/popularity/4711.
I feel most of them are using a library that uses the API behind. However, as far as I picked sites listed, I failed to find sites that is trying to skip a fetch handler completely with the API.

I expected rules like followings in the end.

{
    condition: {
      urlPattern: new URLPattern()
    },
    source: "network"
}

or

{
    condition: {
      or: [ {requestMethod: "get"},
        {not: {requestMethod: "get"}}
      ]
    },
    source: "network"
}

They seem to try to avoid using fetch handler for specific resources, though.

If you want to completely skip the fetch handler, you can explicitly add a rule to catch all to go to "network" before the default route.

My intention of this proposal is that a developer can skip to write such thing.

Can I ask why avoiding writing code like above is important?
Do you have a specific request from your users, are there statistics, or anything else?

I think we have a optimization chance and I guess this not might cause a destructive behavior change.

There are sites using the API already. The proposal should bring behavior change on their API usage.

First, I think that we can regard as that calling InstallEvent.addRoutes() is an developer’s sign for optimization for an user agent. On a user agenet that does not support it, an user application will not call it. It would not a violate an exist code even if InstallEvent.addRoutes() introduce a new internal concept that allows some optimizations. And this assmption would not be against to the original motivation of #1701, I think.

As far as I saw the existing usage, I feel the developers try to use a fetch handler for a specific resource, but they seem to want a fetch handler for others.

Second, an application can call InstallEvent.addRoutes() only in install event handler. fetch event would a wait to complete install. There are lifecycle order. If an application did call InstallEvent.addRoutes(), user agent can firefetch event under this proposal’s assumption. On the contrary, if an application does not call InstallEvent.addRoutes(), user agent should fire fetch event with the traditional manner.

I am sorry, I failed to catch the point. The install event must happen before the fetch event, and regardless of addRoutes() is called or not, the fetch event will come (or may not come) after.
Will you rephrase this?

Also, the install event happen once after the registration until an update. I think the event rarely happen, and we may not need to focus on its performance.

Third, I think this proposal can reduce a application code with the achievement of static routing API’s motivation.

Again, can I ask why reducing the application code is so important?

@tetsuharuohzeki
Copy link
Author

@yoshisatoyanagisawa

Can I ask why avoiding writing code like above is important?
Do you have a specific request from your users, are there statistics, or anything else?

I'd like to clarify my position to avoid misunderstanding, I'm a volunteer contributor but not an paid developer from some browser vendors. I commented here with a hat of web developer.


I am sorry, I failed to catch the point. The install event must happen before the fetch event, and regardless of addRoutes() is called or not, the fetch event will come (or may not come) after.
Will you rephrase this?

What I wanted to say is that, if the spec defines the fetch event occurs only after the install event, we may have a chance to switch the running mode for UA's optimization as the motivation in the case that an developer calls event.addRoutes(). In other words, I'd like to say in this issue that we may be able change a internal mode related to firing fetch event and "network" in RouterSourceEnum maybe unnecessary (as a exposed API for developer).


Again, can I ask why reducing the application code is so important?

Simply, I feel the current proposal is a bit complex as a developer exposed API and I filed this issue.

As my understanding through I read https://github.com/WICG/service-worker-static-routing-api and your comment, the original motivation of it is that introduce the capability to skip some the registered fetch handler, isn't it?

I think there're mixed API semantics both opt-in behavior and opt-out behavior that may confuse a developer as illustrate sample codes in #1712 (comment). If the goal of https://github.com/WICG/service-worker-static-routing-api is to reduce the intercepting by service worker, can we move mental model to the opt-in invokation for the fetch handler on calling InstallEvent.addRoutes()?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants