serviceWorker serving stale frontend assets #4339

Closed
opened 2025-11-02 05:46:47 -06:00 by GiteaMirror · 3 comments
Owner

Originally created by @silverwind on GitHub (Nov 16, 2019).

The serviceWorker script we use to cache frontend assets is rather hindering during frontend development as it often serves stale content where one does not see JS changes reflected on the running application.

To my understanding, the service worker script is at most fetched every 24h by a browser, but I'm not sure if that is actually the root issue because even if I force-reload (which should invalidate the SW cache), I often see stale assets. The only reliable way that get fresh content I found is to unregister the SW manually and force-reload the page.

For development needs, we can probably set up a separate development server where SW is always unregistered, but I wonder if we can improve the invalidation mechanism of the serviceWorker itself as users might see JS that's up to 24 hours old.

Originally created by @silverwind on GitHub (Nov 16, 2019). The serviceWorker script we use to cache frontend assets is rather hindering during frontend development as it often serves stale content where one does not see JS changes reflected on the running application. To my understanding, the service worker script is at most fetched every 24h by a browser, but I'm not sure if that is actually the root issue because even if I force-reload (which should invalidate the SW cache), I often see stale assets. The only reliable way that get fresh content I found is to unregister the SW manually and force-reload the page. For development needs, we can probably set up a separate development server where SW is always unregistered, but I wonder if we can improve the invalidation mechanism of the serviceWorker itself as users might see JS that's up to 24 hours old.
Author
Owner

@silverwind commented on GitHub (Nov 16, 2019):

One solution I have been using in the past is write the js/css build timestamp into HTML (like <html data-build-time="unix">, store it in localStorage and then conditionally re-register the service worker if those timestamps differ. I think this might be a good solution for us too, but it probably won't be a simple integration as HTML is not handled by webpack currently.

@silverwind commented on GitHub (Nov 16, 2019): One solution I have been using in the past is write the js/css build timestamp into HTML (like `<html data-build-time="unix">`, store it in `localStorage` and then conditionally re-register the service worker if those timestamps differ. I think this might be a good solution for us too, but it probably won't be a simple integration as HTML is not handled by webpack currently.
Author
Owner

@guillep2k commented on GitHub (Nov 16, 2019):

What about having some mechanism to override AppVer from the environment when MODE = development, would that work?

<script src="{{StaticUrlPrefix}}/js/index.js?v={{MD5 AppVer}}"></script>

And change:

navigator.serviceWorker.register('{{AppSubUrl}}/serviceworker.js').then(function(registration) {

into

navigator.serviceWorker.register('{{AppSubUrl}}/serviceworker.js?v={{MD5 AppVer}}').then(function(registration) {

Then we can run Gitea like:

GITEA_APP_VER=$(date +%s) gitea --config ....

Sorry if I'm speaking nonsense; I have only some superficial understanding of modern day UI library composition.

@guillep2k commented on GitHub (Nov 16, 2019): What about having some mechanism to override `AppVer` from the environment when `MODE = development`, would that work? ``` <script src="{{StaticUrlPrefix}}/js/index.js?v={{MD5 AppVer}}"></script> ``` And change: ``` navigator.serviceWorker.register('{{AppSubUrl}}/serviceworker.js').then(function(registration) { ``` into ``` navigator.serviceWorker.register('{{AppSubUrl}}/serviceworker.js?v={{MD5 AppVer}}').then(function(registration) { ``` Then we can run Gitea like: ``` GITEA_APP_VER=$(date +%s) gitea --config .... ``` Sorry if I'm speaking nonsense; I have only some superficial understanding of modern day UI library composition.
Author
Owner

@silverwind commented on GitHub (Nov 16, 2019):

I don't think that would work. A SW will not check for a update to itself unless it is being told do (or 24h have passed). I think the only leverage we have is a (inline) script loaded from HTML that will unregister the worker if gitea is started in development mode (maybe via a flag or env var). The next time gitea is started in "production" mode, it would then register again and do regular caching.

Do we have any suitable flags/vars that could be used?

@silverwind commented on GitHub (Nov 16, 2019): I don't think that would work. A SW will not check for a update to itself unless it is being told do (or 24h have passed). I think the only leverage we have is a (inline) script loaded from HTML that will unregister the worker if gitea is started in development mode (maybe via a flag or env var). The next time gitea is started in "production" mode, it would then register again and do regular caching. Do we have any suitable flags/vars that could be used?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/gitea#4339