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

Need to clear application cache and then refresh to see the new changes on PWA enabled Blazor WebAssembly apps #18

Open
jsakamoto opened this issue Jul 27, 2022 · 14 comments

Comments

@jsakamoto
Copy link
Owner

From: @fingers10
(The original post is in the Issue #17)


@jsakamoto The fix provided in the service-worker.published.js,

Change the code inside the onFetch() function from const request = shouldServeIndexHtml ? 'index.html' : event.request; to const request = shouldServeIndexHtml ? (new URL(event.request.url)).pathname.replace(/\/$/, '') + '/index.html' : event.request;.

creates a cache issue.

Steps:

  1. Deploy a blazor wasm app with pwa enabled.
  2. Now make some changes in Index.razor screen.
  3. Now publish and deploy again and navigate to index url of the app.
  4. Note that new changes will not be reflected. You need to clear application cache and then refresh to see the new changes.

Video showing the problem:

  1. I have an intial version deployed.
  2. I made code change in Index.razor by adding <h1 style="background-color:yellow">Hello, Cache Problem</h1>.
  3. Published and deployed the app.
  4. Navigated to index url of the app.
  5. Refreshed and expecting to see new changes but nothing happens.
  6. Cleared cache and refreshed. Now I can see new code changes.
CacheProblem.mp4
@jsakamoto
Copy link
Owner Author

@fingers10

This behavior is by design on the service-woker.js generated by .NET SDK (Visual Studio) standard project templates.

You should close all browser instances after a new version of your Blazor Wasm PWA was fetched in the background to see a new version's contents.

The official documentation is here:

https://docs.microsoft.com/en-us/aspnet/core/blazor/progressive-web-app?view=aspnetcore-6.0&tabs=visual-studio#background-updates

P.S.
In fact, this issue is not related to the "BlazorWasmPreRendering.Build" package at all. It is not related to pre-rendering too. You should ask about this theme elsewhere, such as StakcOverflow.com. Please consider well it is suitable for posting this GitHub repository's issue thread.

@fingers10
Copy link
Contributor

fingers10 commented Jul 29, 2022

@jsakamoto ,

I'm trying to debug by logging console.log((new URL(event.request.url)).pathname); and see if this will log the route entered in address bar. But it logs all the paths of static assets.

Do we need to try something like below?

const request = shouldServeIndexHtml
            ? (new URL(event.request.url)).pathname === '' ? 'index.html' : (new URL(event.request.url)).pathname.replace(/\/$/, '') + '/index.html'
            : event.request;

This way index.html will forced to reload?

Please correct me if I'm wrong.

@jsakamoto
Copy link
Owner Author

@fingers10
Sorry for the late reply, but I've spent time these days investigating how to control refreshing a PWA to the next version.

see if this will log the route entered in address bar. But it logs all the paths of static assets.

The above behavior is definitely no wonder. Please remember that service worker processes are like a proxy server inside a web browser. It is a process like a proxy, so it is obvious that a service worker intercepts all HTTP requests, such as static assets.
That is why your logging logs not only the path you entered in an address bar but also all static contents.

Do we need to try something like below?
This way index.html will forced to reload?

The answer is no. What you consider to try is not make sense. Because the JavaScript code which you are going to modify is the part of responding to an HTTP GET request with a fallback page (like a app.MapFallbak("index.html") on an ASP.NET Core host for Blazor WebAssembly).
Whether the contents a web browser will fetch will be provided from the cache or not depends on the JavaScript code await cache.match(request).

However, don't try to modify the code around await cache.match(request) in a hurry.

There is a deep reason why the service worker and its offline cache will never update until all browser tabs that open it are closed. I can t explain it now because there is not enough time to do that, but the keyword is "atomic". If you break this offline strategy by changing the above code, you and your site users will see confused site content mixed up with new and old versions.

All we can do to update your PWA site as soon as a newer version is detected is the following strategy.

"Notify a new version is available for site users via a user interface such as snack bar, and reload the page by user's action such as clicking the "update now" button you provided as UI elements."

I'll explain how to implement the above strategy as a specific code, but please give me a few more days or a week. The PoC sample code is almost done on my hand. I have to spend time validating and refining that sample code.
Thank you for your patience.

@jsakamoto
Copy link
Owner Author

@fingers10

I implemented a sample code.

📦BlazorPWA2.zip

Step.1 Copy the files in the "BlazorPWA2.zip" below into your Blazor WebAssembly project.

  • Components/UpdatePWA.razor
  • Components/UpdatePWA.razor.css
  • wwwroot/blazor-pwa-updater.js

Step.2 Add the <UpdatePWA/> component into your MainLayout.razor.

Step.3 Change your index.html as below.

    ...
    <!--
    Remove the line "<script>navigator.serviceWorker.register('service-worker.js');</script>",
    and insert the line below instead.
    -->
    <script src="blazor-pwa-updater.js" data-script-path="service-worker.js"></script>
</body>
...

Step.4 Add one line below to the top of your wwwroot/service-worker.published.js.

self.addEventListener('message', event => { if (event.data?.type === 'SKIP_WAITING') self.skipWaiting() });
...

Then you can get the behavior like the following animation GIF picture.

movie 001

Would you try to apply these changes to your app?

P.S.
I'm also considering creating and publishing a NuGet package encapsulating the code modifications above.

@fingers10
Copy link
Contributor

@jsakamoto can we connect and work together on this? I would like to learn and understand a lot from you. I would like to learn on how you think when solving these problem. The way you approach the solution. This could open the doors for me to think in new ways or get myself exposed to new learning

@fingers10
Copy link
Contributor

@jsakamoto , I tried the above steps with sample pwa app and published to https://fingers10.github.io/WasmServerPrerender/ but I'm not able to see the changes and update button. New changes are visible only when I press Ctrl+F5.

Steps I tried:

  1. Added the changes mentioned in above step and committed and published to github pages.
  2. Made a change in Index.razor and committed and published to above URL.
  3. Now when I navigate to https://fingers10.github.io/WasmServerPrerender/ I'm not able to see new changes.
  4. When I press Ctrl+F5, I can see new changes getting reflected. But not able to see update button.

Please can you assist?

@jsakamoto
Copy link
Owner Author

jsakamoto commented Aug 8, 2022

@fingers10
I verified it works fine.

  1. I forked your repository. (The repository is here.)
  2. I deployed the forked version to GitHub Pages.
  3. I opened that forked version's GitHub Pages by my Microsoft Edge web browser.
  4. I changed the Index.razor of the forked version, committed, and pushed it.
  5. The GitHub Actions workflow built it and deployed it.
  6. After that, I opened that forked version's GitHub Pages by another window of my Microsoft Edge web browser.
  7. Then, I saw the "The new version is ready" message on it. I clicked the "YES" button, then the page reloaded, and I could see the contents of the changed Index.razor.

movie-001

Do you remember that the PWA won't be updated to the new version without closing all browser windows by default?
I guess your PWA's new version that is bundled with the "The new version had been ready" UI feature is ready in the background. But you had not closed all browser windows, so you could not see the next version of your PWA, and the current version of PWA you would see doesn't have the ability to show the "The new version had been ready" UI feature.

Can you understand?
I recommend retrying it after closing all browser windows once.

@fingers10
Copy link
Contributor

@jsakamoto ,

I tried closing and opening browser window with the same repo. But not working for me.

Steps I tried,

  1. Made a change and published. This will prerender after publish.
  2. Opened the published site in normal window. No Change.
  3. Closed the window and opened again. No Change.
  4. Tried opening in Incognito window. Changes reflected.
  5. Again opened in normal window. No Change.

Every time I closed and opened the chrome browser.

I also installed the site as PWA. When I close the PWA and open I didn't see yes button but the contents are updated.

PWA.Not.Reloading.Issue.mp4

@jsakamoto
Copy link
Owner Author

@fingers10
I opened the URL https://fingers10.github.io/WasmServerPrerender/ again right now, then I saw the "The new version is ready" message as expectedly.

image

And I clicked the "Yes" button, then the page was reloaded, and the page was settled.

Everything looks well work for me for now.

If your browser still shows no-changes contents "Welcome to your new app" message, could you take a screenshot of your browser's developer tools window like below? (The "Application" Tab > "Service Workers" section)

image

@fingers10
Copy link
Contributor

@jsakamoto Yeah I also noticed the update message. Looks like issue is sporadic. I'll do another round of testing to make sure if something else is wrong.

@jsakamoto
Copy link
Owner Author

jsakamoto commented Aug 11, 2022

@fingers10
One of the other factors we have to notice is that new contents deployed to GitHub Pages will not be able to download from a browser immediately. It will take a few seconds or minutes to be all new contents replicated to all CDN endpoints of GitHub Pages.

Another one is the "The new version is ready" indicator will be shown only when after all updated contents are downloaded correctly in background. It was not when a browser detected the new version.

The above factors mean sometimes it will take much longer than our expectation until the "The new version is ready" indicator has appeared.

I hope these knowledges are helpful for you.

@fingers10
Copy link
Contributor

fingers10 commented Aug 11, 2022

@jsakamoto I have a suggestion if this is going to be published as nuget package. Can we supply a custom UI to refresh and get new content instead of default one?

@jsakamoto
Copy link
Owner Author

@fingers10

Can we supply a custom UI to refresh and get new content instead of default one?

Yes. I'll provide the ability on the NuGet package library I'm going to publish to customize UI fully.

@jsakamoto
Copy link
Owner Author

@fingers10
[FYI] The "Blazor PWA Updater" NuGet package has been rolled out!

https://twitter.com/jsakamoto/status/1558456715237986309

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