w3c / webextensions

Charter and administrivia for the WebExtensions Community Group (WECG)
Other
581 stars 50 forks source link

Use cases that are not well served by service workers #72

Open dotproto opened 2 years ago

dotproto commented 2 years ago

Near the end of the 2021-08-19 meeting we briefly discussed (but didn't capture) the idea of collecting background page use cases and design patterns that are not well served by service workers. My hope is that by collecting these use cases in a well known location, community members and browser vendors we will be able to more concretely discuss the challenges posed by this new background context and explore potential solutions.

Please use this issue to link to use use cases that are impossible to accomplish with or not well supported by service workers. If you'd like to report a new use case, please create a new issue and reference this one.

Use cases

Specific ways that background pages are used that cannot be accomplished with a service worker.

Other discussions

mingyaulee commented 2 years ago

One additional use case for background service instead of service worker is the use of web assembly. This is related to the issue I raised in #39.

cuylerstuwe commented 2 years ago

Not added here is extension-driven behavior from an external source.

This includes user-driven input coming from an outside (related) desktop/cloud app via WebSockets or Native Messaging Hosts.

Their connections need to persist indefinitely in order to work effectively.

cohosh commented 2 years ago

Hey! I've just shared a use-case where we need access to RTCPeerConnection for service workers in order to upgrade to using v3 manifests here: https://github.com/w3c/webrtc-extensions/issues/77#issuecomment-912667886

avi12 commented 2 years ago

Another use-case is using FFmpeg via @ffmpeg/ffmpeg, which is using WebAssembly To provide the best user experience using this module, you need to put it on the background page, which would make it accessible from all of the parts of the extension Such a background page must also be persistent, as it takes a few seconds until FFmpeg gets initialized; if it isn't persistent, it might get terminated by the browser, thus requiring re-initializing FFmpeg for every user action that would result in FFmpeg processing

dotproto commented 2 years ago

Such a background page must also be persistent, as it takes a few seconds until FFmpeg gets initialized; if it isn't persistent, it might get terminated by the browser, thus requiring re-initializing FFmpeg for every user action that would result in FFmpeg processing

@avi12, from the Chrome team's point of view terminating an unused worker is a feature, not a bug. Can you expand on why reinitializing FFmpeg is a problem? Adding latency to an uncommon operation is understandably undesirable, but so is keeping around an unused JS context.

Is there a specific workflow with an existing extension you can point to?

dotproto commented 2 years ago

@mingyaulee Added a crbug link related to allowing Wasm in MV3 service workers.

@cuylerstuwe, I just added a thread you started on chromium-extensions related to WebSockets and a crbug issue tracking native messaging.

@cohosh Added your link and the related crbug issue

avi12 commented 2 years ago

@dotproto

Adding latency to an uncommon operation is understandably undesirable, but so is keeping around an unused JS context.

That's true. However, in CLI apps like FFmpeg, which can only do one job at a time (which is particularly true for the WebAssembly version), if the job takes too much time (depending on the operation and the size of the files you work with), it might get terminated mid-way through, due to the limited 5-minute lifespan of an extension's Service Worker

Is there a specific workflow with an existing extension you can point to?

Right now, I'm working on this extension

avi12 commented 2 years ago

Another use-case is when needing to download files, which, if need to be initiated in the current Service Worker, will have 2 issues:

  1. A Service Worker's lifespan is up to 5 minutes, If you need to download files that would take more than 5 minutes, it would be disrupted mid-way
  2. If you find yourself needing to use the Fetch API (like in my extension), making the download cancellable is important for a good user experience. The only way to cancel a Fetch process is by using AbortController's AbortSignal, which so happens to use the DOM
Jack-Works commented 2 years ago

A Service Worker's lifespan is up to 5 minutes, If you need to download files that would take more than 5 minutes, it would be disrupted mid-way

Try Background fetch?

avi12 commented 2 years ago

That's an interesting option However, my extension that I linked above also needs to run FFmpeg on the background, so I don't think the Background Fetch API will be enough for my use-case

cuylerstuwe commented 2 years ago

In a world where RAM is plentiful and tends to be cheaper/easier to upgrade than CPUs, it’s pretty odd that the current Chrome team would essentially prioritize memory over CPU cycles.

This is especially weird since Chrome has historically performed better than Firefox almost every synthetic and real-world benchmark, at the cost of higher RAM use.

On Fri, Sep 3, 2021 at 2:27 PM Simeon Vincent @.***> wrote:

Such a background page must also be persistent, as it takes a few seconds until FFmpeg gets initialized; if it isn't persistent, it might get terminated by the browser, thus requiring re-initializing FFmpeg for every user action that would result in FFmpeg processing

@avi12 https://github.com/avi12, from the Chrome team's point of view terminating an unused worker is a feature, not a bug. Can you expand on why reinitializing FFmpeg is a problem? Adding latency to an uncommon operation is understandably undesirable, but so is keeping around an unused JS context.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/w3c/webextensions/issues/72#issuecomment-912819913, or unsubscribe https://github.com/notifications/unsubscribe-auth/AE4MEMARJGBYH37GEZO2ILTUAE4SVANCNFSM5DJTXWDQ .

tregagnon commented 2 years ago

@dotproto I think crbug 893175: Request for an API to specify Light and Dark Mode Icons should be added to the list

The Service Worker does not have window.matchMedia() which was used by Extensions to identify if the OS was in Dark/Light mode. We need the action.setIcon() API to be extended so Light/Dark icons can be set.

Defining those Light/Dark icons in the Manifest only is insufficient for extensions like Dashlane, which also uses the icon to indicates if the user is authenticated or not.

ghostwords commented 2 years ago

What about the general mismatch of webpages having user-defined lifetimes with Service Worker-based extensions having arbitrarily limited lifetimes (five minutes in Chrome at this time)?

The user may be relying on extension-provided functionality on some webpage when the extension's SW gets shut down. Even if the SW were to get restarted in response to content script messages, shutting down and restarting a SW is inherently a waste of resources. The additional delay caused by SW startup will break use cases that depend on speedy messaging between the content script and the background page (for example, an extension that dynamically modifies the right-click menu based on type of clicked element). Furthermore, after a SW restart, content scripts may have stale configuration data and won't work properly without additional message passing or a page reload.

If content scripts were to also get reloaded along with the SW, this would introduce clear usability issues, where the user is in the middle of some extension-facilitated workflow that suddenly stops working.

tophf commented 2 years ago

Another blocker: https://crbug.com/1219164 - ability to create nested workers.

BTW, the title should reflect that these use cases are currently impossible to implement in a service worker, please don't use the euphemistic language such as "are not well served".

gildas-lormeau commented 2 years ago

It's not possible to use chrome.i18n.getMessage to set the label of the action button or the entries in the context menu.

capaj commented 2 years ago

Safely storing confidential information for the duration when browser is running.

Chrome docs on storage api explicitly say that: image

Yet they explicitly advise to use it to store data which is needed in the service worker: https://developer.chrome.com/docs/extensions/mv3/migrating_to_service_workers/#state

I think @bitwarden relies on this when they store the master password inside backgroundPage so that the user doesn't have to put it in every time when they open the Popup.

gorhill commented 2 years ago

Please use this issue to link to use use cases that are impossible to accomplish with or not well supported by service workers.

A use case not possible with a worker, "Bug 1580254: Support CSS selector validation API from a service worker":

Removing access to a DOM would currently break uBlock Origin (“uBO”). uBO uses a DOM element to validate plain cosmetic filters[4] – which are essentially CSS selectors. Having access to the DOM to validate plain cosmetic filters allow uBO to detect and discard or further process invalid cosmetic filters.

[...]

ghostwords commented 2 years ago

Requesting file:-scheme resources (aka file:// URLs)

The Fetch API is also unable to retrieve chrome:// resources apparently, something you can do now with XMLHttpRequest.

tophf commented 2 years ago

Dynamic import of scripts in a service worker is only partially implemented and prohibitively convoluted.

https://crbug.com/1198822

And there's also a foundational issue of an understandable reluctance in the service worker spec group to provide WebExtensions-specific improvements, further exacerbated by an understandable reluctance of the browser developers (Chromium extensions team, specifically) to provide non-standard exceptions in a service worker as it would add maintenance burden on them and introduce fragmentation of otherwise solid technology. Allowing the dynamic import of scripts without the need to pre-import them in the install event listener (all importable scripts are already local in an extension) is an example of such problem as well as the ability to control the lifetime of the service worker or create blob: object URLs, and many more problems introduced by the premature decision to switch to service workers in ManifestV3.

avi12 commented 2 years ago

from the Chrome team's point of view terminating an unused worker is a feature, not a bug. Can you expand on why reinitializing FFmpeg is a problem?

@dotproto Assuming the user is willing to wait a few seconds every time he wishes to use the FFmpeg functionality, the Service Worker will still get terminated after 5 minutes, making mv3 a huge limitation

Jack-Works commented 2 years ago

it imports solely into the global scope, which means you would need a module management system i.e. use webpack (and similar systems) or find some service-worker-compatible library or write one yourself;

For anyone interested, https://github.com/awesome-webextension/webpack-target-webextension/ this webpack extension support dynamic import in MV3 (early load chunks but not executing them).

jonathanmayer commented 2 years ago

Another use case where service workers are problematic: maintaining time-sensitive state about browser windows, tabs, and pages. My research group at Princeton has a number of academic studies that are implemented as browser extensions and that involve precisely understanding user interaction with the browser and web content. Even minor performance hiccups or event loop requeuing can introduce measurement error.

In the background page model (Manifest v2), we maintain state in variables and update state based on myriad API events and content script messages, using timestamps when possible. In the service worker model (Manifest v3), we can't rely on variables because the browser might shut down the service worker. The least-bad options, so far, are to either a) convert all of our (many) state variable operations to storage calls, which would introduce measurement error risks by littering asynchronous and slow storage calls throughout our implementation, or b) use runtime events to store state when the service worker shuts down and load state when the service worker starts again, also introducing measurement error risks and possibly failing because there's no guarantee asynchronous storage calls will succeed on shut down.

The option of a persistent extension worker, as many have proposed, would address this use case.

bitcrshr commented 2 years ago

Good day, everyone!

(Copied from Chromium Extensions forum by request)

I have taken on a new role in my company that involves me maintaining our browser extension which is based on MV2. I have a few concerns about the migration to MV3, and I was hoping to get some guidance.

For some background, we sell a bluetooth LE device that integrates with our password management software. Basically, as long as the device is in range, you can have access to your passwords.

The implication of this is that our desktop app needs to tell our Chrome extension "hey, the device is still in range!" regularly through a WebSocket. In fact, the extension's only way of getting sensitive data is through that WebSocket. I understand that WebSockets are still allowed in MV3, but I am concerned that the ephemeral nature of service workers will make this process impractical if not infeasible.

Sure, it's not a problem if the user doesn't need their credentials for a while, but what Chrome API could be called to 'wake up' the service worker after it dies? I've seen a good bit of workarounds in this forum talking about doing some arbitrary Chrome API call every 4.9 minutes to keep it alive or keeping a tab open specifically for the extension to run, but in my opinion these are hacky and counterintuitive.

Even if there was an MV3-compliant way to go about this, the user would no longer be able to see battery % or do basically anything at all in the extension if the service worker is not active.

I'll admit that I may not be getting the full picture here, but it seems that disallowing persistent background scripts in MV3 more or less breaks our entire Chrome platform. From what I have read around here, there are plenty of other people that have similar concerns and I hope that we will be able to find a solution that works for us all.

Also, I would like to politely note that the documentation for MV3 can be a little lacking--it's unclear how Chrome handles the lifecycle of Service Workers (i.e., conditions and timelines for becoming active/inactive). There's also not a lot of great guidance for maintaining state, other than the "in-memory storage" thing that doesn't seem to be a good replacement due to storage limits. All in all, I felt that a few questions that MV3 raised for me were far better answered in threads here than they were in the official docs.

I look forward to hearing y'alls thoughts on this!

Tyrowo commented 2 years ago

I have an extension that I wanted to use as a kind of voluntary parental advisory software. The idea was for users to input problem websites, specify an allowed amount of time and a blocked amount of time, and create listeners for specified websites that would trigger onCompleted visits to that website to activate a declarativeNetRequest blocking them.

Although the net request blocking worked quite well, I needed to create listeners in response to users specifying websites, and unfortunately at the end of the service worker lifecycle the listeners are always deleted.

Additionally I wanted to use a badge to count down the amount of time remaining before the allowed and blocked periods end, using a setTimeout or setInterval. Neither of these methods worked either, because the service worker is forced to die after 5 minutes, and so the badge eventually stops ticking.

There was no satisfying workaround for either of these issues so I've since abandoned the project.

birtles commented 2 years ago

Another blocker: https://crbug.com/1219164 - ability to create nested workers.

Building on this, I have an extension that, on install, downloads the necessary data files and stores them in Indexed DB using a worker so as not to block queries that occur while the update is still in progress. The process takes about 10 minutes (particularly on Chromium browsers where IDB performance is particularly poor) meaning that in addition to "nested" workers, a longer timeout is required.

absurd-sql appears to offer improvements to IndexedDB performance but it can only be run in a separate Worker.

klapauciusisgreat commented 2 years ago

In general, as I understand it, anything depending on sign-in-with-Google/facebook, 2FA or any other auth method that requires a browser window to sign in will no longer work in Chrome extensions because auth would need to run in the service worker and need to have access to a window to open a popup. At least, I have seen no-one from the crx or firebase team being able to articulate a way forward.

If there is a way, it would be great to explain how to go about it.

eadan-y commented 2 years ago

Let's say I want my extension to send a message to the server every time a user switch tabs. I only want to log tab switches according to a remote configuration, which is fetched when the extension is loaded. If the behavior is disabled, I don't want to register to the "tabs.onActivated" event at all (for performance reasons).

With the service-worker approach, I will always "miss" the first tab change event, since every time the service worker will start - I will have to fetch the configuration first (either from cloud or the storage) in an async way, delaying the event registration.

With the old background page (or a persistent service worker) - I could load the configuration just once, never missing any future event.

Another thing - once I'm subscribed to "tabs.onActivated" event, there is no way I can "unsubscribe" it, so it will no longer start my service worker.

aeharding commented 2 years ago

Hi,

I was told to post there here:

https://groups.google.com/a/chromium.org/g/chromium-extensions/c/Qpr-Wf8BcsI

Quote below:

Frankly, I'm at a loss of words. I understand the benefits of service workers for websites. They make sense.

But there are so many web extension use cases that need persistent background pages.

For example, I have an extension that acts like a password manager on steroids: It records the tab while the "session" is open on a tab, passes those recorded chunks to the server on an interval, and communicates with a websocket to the server to allow the session to be closed remotely, etc.

It needs a persistent background page when these "sessions" are active.

It's a corporate security product, and needs to be authoritarian over tabs it's been enabled on.

There's simply no way to replicate its behavior with manifest v3. There's no way to store HTMLAudioElement or MediaStream in the background page for cleanup when the session ends. There's no way to have a background websocket. There's no way to automatically clear in-memory data when the browser is closed. There's no way to implement webRequestBlocking + onAuthRequired. There's no way to run an interval < every minute. There's no way to store Blob video chunks from the tabCapture MediaStream to queue to upload to the server. There's so much more that is just not there.

I understand that most web extensions don't need this functionality. But some genuinely do. And I keep looking things up that my extension needs, and all I see are unanswered stackoverflow questions, empty forum threads, open issues.

I don't know what to do. I'm sorry for this rant, but I feel like there's major chasms of functionality that are lost in v3. And it's not just one thing, it's many completely absent core features to my extension's functionality.

Thanks.

wolfspelz commented 2 years ago

weblin.io is a messenger that lets people meet with avatars on web pages. Uses XMPP on websockets. A limited background/webworker lifetime would let users leave/enter all the time. The background page is the right abstraction: a persistent context that manages and coordinates states of multiple tabs AND holds the shared XMPP connection. A connection for each tab would generate much more load on client and server, would make the experience sluggish, would result in lots of TCP reconnects, and would need awkward workarounds. Might well kill the project. See issue #133

Now I install the extension and then it works seamlessly. That's what users want.

They do not want an extra tab that is automatically. You write: an additional tab is "an imperfect fit. Note quite as utilitarian, but it gets the job done". I am afraid this means: it is a worse user experience. If closed accidentally then either weblin.io breaks or auto-opens another tab which sounds annoying and error prone. Closing a tab sounds like a nice way to disable it but disabling is currently done by a single click on the extension icon. Cannot be easier. The tab is a workaround that makes things worse. It is only necessary because the good solution goes away.

The native companion app with native messaging looks good on paper if you ignore the fact that people must download a native app in addition for things to work. I had a native app before and switched to the extension because it is easier to convince people and safer for them. That's what the browser sandbox is good for. I don't understand why you would take that away making things more difficult for users, for the business, and by requiring native code less safe from the user's point of view. The native app / native messaging approach is only useful if the native app is the main and the extension is the addon.

The problems with handling the messaging connection on the page (iframe or directly) are obvious: a new connection on each navigate, takes more time to set up, needs more resources. That is generally considered so bad that HTTP 1.1 was developed to add keep-alive. Also (not as obvious) prohibits an intelligent mechanism, that skips leave/enter room during navigations, so that the avatar does not flash all the time from the point of view of other visitors. That makes it much worse for others.

If I only knew the rationale for this change we might be able to find a solution that meets the rationale and still does not make our app worse.

avi12 commented 2 years ago

I encourage you all to state your issues in the official Chrome Dev Summit Discord server, https://discord.gg/UhgDwtmw

wolfspelz commented 2 years ago

Any idea where exactly. I posted something in #extensions Can I do more?

avi12 commented 2 years ago

@wolfspelz You have #general

wolfspelz commented 2 years ago

Who drives this standardization? and why?

wolfspelz commented 2 years ago

With respect to weblin.io and Issue #133

I understand the desire to run extensions in resource constrained environments, especially if that means extensions will be available on chrome/android. Currently I am recommending my users to install another chromium-based browser on mobile. But you are probably aware that projects which need a persistent background context let the worker restart immediately. So, the worker is still running all the time despite the time limit. Only to restart it consumes more resources. Kind of defeats the purpose.

There is a difference between a compute job that runs for a long time in the background and a persistent context like a messenger connection. You are trying to kill permanent background computing by removing background persistence. But compute jobs that want to run permanently will just restart and applications needing a persistent context will need more resources to cope with the time limit. So, this change is not achieving its goal in one case and is actually counterproductive in the other.

Anarchotect commented 2 years ago

Say you use webRequest in a manifest v3, policy-installed, enterprise extension. Each request is either canceled, redirected, or allowed, but the decision has to be made based on the result of an API request, which you then cache for similar requests in the future.

chrome.webRequest.onBeforeRequest.addListener(
    (details) => mustBeSynchronous(details), { urls: [ '<all_urls>'] }, ["blocking"]
);

mustBeSynchronous(details) : chrome.webRequest.BlockingResponse {
    // Must use async fetch, cannot use sync XMLHttpRequest
    fetch('https://our.api.endpoint/param?uuid='+ourLookup)
        .then(response => response.json())
        .then(data => {
            //This returns a promise anyway, not a chrome.webRequest.BlockingResponse
            return makeDecisionsAbout(data);
        });
    // Returns as soon as fetch is sent, before promise resolves.
    //  tooLate cannot depend on makeDecisionsAbout()
    return tooLate;
}

Without a synchronous request, the page will load before a decision can be made. On subsequent requests a cached result can be used synchronously and locally to make the decision, but the first load of any page will bypass our logic.

I understand that asynchronous requests are better for performance, but in this instance we specifically need a synchronous request for exactly the reason it's shunned; we need to hold things up. I understand discouraging the use of synchronous requests, but banning the function entirely seems a bit Procrustean.

markon1 commented 2 years ago

geolocation API is not working with service workers...

avi12 commented 2 years ago

geolocation API is not working with service workers...

You're welcome to report it on the official Discord server

dotproto commented 2 years ago

Who drives this standardization? and why?

@wolfspelz, the short answer is no one. There are currently no standards for browser extensions or groups pursuing standardization. This group is not an exception. While we are aiming "to identify common ground, bring implementations into closer alignment, and chart a course for future evolution" (source), as stated in the Community Group FAQ, "Community Groups … do not create Web standards (though their outputs may advance to the standards track in a Working Group)."

rektide commented 2 years ago

Who drives this standardization? and why?

the short answer is no one. There are currently no standards for browser extensions or groups pursuing standardization.

It's depressing in extreme that such a distant ghostly shadow of what we de-jure have today would be what we would standardize & force upon ourselves in the coming months or years.

The current status quo affords extensions a range of powers comparable to what a page can do. That seems like a respectable baseline. To say that an extension should have less powers than a page seems absurd & upside down. This issue, #72, is one of the critical points. Other losses, like #139, seem also in need of justification & explanation, but which have never been explained or justified either.

What is being created now is awful, is a shriveled husk of what extensions have historically been. This community group, if the current path is maintained, is actively working against the freedom & future of the web, & should dissolve until some better less anti-user-agency basis can be established. One group, Google, has presented an effort, and so far it has been an abject failure.

ghostwords commented 2 years ago

Observational webRequest has been broken in service workers in Chrome for over two years now: https://bugs.chromium.org/p/chromium/issues/detail?id=1024211

Now if the bug did get fixed and webRequest events did restart the service worker, what does having to repeatedly restart over the course of typical browsing (for no good reason whatsoever other than Chrome's hardcoded five minute limit) do to Google's Manifest V3 improved performance claims? Who knows for sure because webRequest is still broken!

Just a reminder, we are apparently about thirteen months away from when Manifest V2 stops working in Chrome.

aeharding commented 2 years ago

god this is so stressful

hunterharris1 commented 2 years ago

Would also like to reiterate that nested workers not being supported is a problem for my company's use case as well.

Added to the Chrome issue here. Quoted info below (w/ some extra details).

The company I work for has an extension that we use to augment the experience of our customers that use our analytics products. Basically we allow information overlaid in the form of cards for specific keywords that are tied to datasets they have chosen to be interested in.

To be able to effectively search the webpage we build an efficient data structure in a web worker from the background page (it is computationally expensive to build, but allows fast search time). We then serialize this and send that version to the content scripts to use. This significantly gives us a performance boost for the user’s experience and for the amount of time we have to borrow from an individual page’s resources.

Additionally, we also have a search feature, that leverages the use of lunr search indexes, and we use workers to build and search those indexes (again from the background page).

We will not be able to do either of these efficiently anymore with Manifest V3, and it looks like it will cause major performance issues for us.

Our users expect this to work on every page they are visiting, and a persistent extension really did make sense for our use case.

By moving this to a service worker now, we now how to deal with large data serializations upon shutdown/startup, and w/o web workers have to do the computational heavy processing inline (or some major refactoring to do it in chunks, which will impact the perceived performance from the user's perspective).

Anyway, just posting here to help raise awareness of the limitations we're facing as it seems several others are having problems as well.

cuylerstuwe commented 2 years ago

Who drives this standardization? and why?

@wolfspelz, the short answer is no one. There are currently no standards for browser extensions or groups pursuing standardization. This group is not an exception. While we are aiming "to identify common ground, bring implementations into closer alignment, and chart a course for future evolution" (source), as stated in the Community Group FAQ, "Community Groups … do not create Web standards (though their outputs may advance to the standards track in a Working Group)."

The more accurate answer is:

Google

Chrome's extension platform is the "de-facto" standard which Firefox and Safari have sought to imitate to varying degrees. Chrome has most of the market share (especially on desktop, where extensions are generally used), and implementors for other browsers understand that extension availability is a major draw to one browser or another. Extensions are the web's "killer feature", and other browser implementors want to have access to Chrome's marketplace of extensions so that switching to those browsers doesn't cause so much suffering.

A de-facto standard is still a standard, and by that token, developing the de-facto standard qualifies as "standardization".

Google is mostly doing their own thing here, only really halfheartedly listening to any community feedback. The CG is mostly just Google just advertising what they're up to, while just about everyone who doesn't work at Google begs desperately for some sanity.

I think I speak for much of the developer community in hoping that this standardization effort fails, so that at least one major browser will actually remain worth using and developing for. It's totally pointless for all parties involved to standardize upon something inferior.

You remember when you were little and your mom asked you, "If your friend jumped off a bridge, would you?" Let Google jump off this bridge. Let Chrome become irrelevant through Google's own poor decisions. Let's watch and see what comes next. 🤷‍♂️

wmbenedetto commented 2 years ago

I'm looking at porting StayFocusd from Manifest v2 to v3, and it's pretty clear that moving from background pages to service workers is going to completely brick my extension. StayFocusd blocks time wasting websites once you have spent more than an allotted amount of time on them. To do this, it needs to run a setInterval() in a background page to check once a second how much time has elapsed. Once the time has expired, it blocks sites on the blocklist for the rest of the day. If I can't keep a persistent timer running, then my extension is useless. It was one of the first Chrome extensions, dating back to Jan 2010, and has over 625,000 users. The fact that it will be killed by this change is incredibly frustrating. There may be a hack workaround that I haven't found yet -- I just started looking into the changes -- but I shouldn't need to do that just to keep my extension alive.

wolfspelz commented 2 years ago

I'm looking at porting StayFocusd from Manifest v2 to v3, ...

We collected many cases in which the new manifest effectively kills old extension, because it is either impossible or very time consuming to change the code. Even if it is technically possible most devs moved to other projects just maintaining existing extensions on a small budget or even spare time. That makes major rewrite impossible in many cases.

So, if that move is to clear out un-maintained extensions, then a small change would do the trick without killing extensions that are still maintained on a small budget.

If the move is to force extensions to use less background resources then it does not the trick, because re-written extensions will use the same or even more resources to cope without persistency.

I wish they would let existing extensions live with a small change (to prove that they are still maintained) and force only new extensions to very different model. My proposal:

nopol10 commented 2 years ago

@wmbenedetto in StayFocusd's case is it possible to run the timer in each page's content script and have it read and update the local storage?

tophf commented 2 years ago

@nopol10, it's unreliable because content script timers aren't isolated by design so they can be cleared by the web page or by another extension or by the user in devtools console, https://crbug.com/860320.

gorhill commented 2 years ago

page's content script and have it read and update the local storage?

Additionally, extensions should never ever write private extension data to a sites' local storage.

nopol10 commented 2 years ago

I was referring to chrome.storage.local which I've seen https://github.com/hindmost/reduxed-chrome-storage use as a way to get Redux working in MV3. And it seems to be the new recommended way to pass state around the extension https://developer.chrome.com/docs/extensions/mv3/migrating_to_service_workers/#state though as others have pointed out, Google's own docs warn against storing confidential user information so use cases might be limited

wmbenedetto commented 2 years ago

@nopol10 That's the "hack workaround" I was referring to. It might be theoretically possible, but it will be waaaaay more complex and unreliable than the current implementation. With the background page, I have a single master timer that applies to all tabs and windows, so there's a single source of truth. With content scripts, I'd have a timer assigned to each tab, with no single source of truth. That means I'd have to keep track of all the different timers and make sure that only one is running at a time, creating and destroying timers every time a user navigates to a new page or opens a new tab. It will be a nightmare, and even then is still victim to all the issues that @tophf mentioned. 😞