Skip to content

Web Cache invalidation based on Build Number #63500

Closed

Description

@phackwer

Use case

Flutter has a very strong caching done by it's service worker, which sometimes forces a user to have to clear the cache for the app even when resources are sent from the web server with a no-cache and already expired date headers. This sometimes causes problems because even with the proper code already in place in the server, the app takes a while to retrieve the latest resources from it. Sometimes, even adding ?v=(timestamp) to force this reload don't work as the cache is not controlled by the browser, but by this flutter service worker.

Proposal

Based on the version/build number of the app, cache could be deleted to force the retrieval of the latest versions from the server. This could easily and elegantly be achieve by using package info which is still not implemented as stated on #46609.

Current Successful Workaround

Currently in our pipelines we are dumping a file named version.txt in the root of the published code that contains the values from pubspec.yaml with build number updated and call caches to delete the caches everytime this build number is changed. Code is not beautiful but definitely may help those who are facing this problem:

<script>
       if ('serviceWorker' in navigator) {
        window.addEventListener('load', function () {
            //getting rid of undesired cache before running the app
            var seconds = new Date().getTime()
            xmlhttp = new XMLHttpRequest();
            xmlhttp.open("GET", '/version.txt?v=' + seconds, true);
            xmlhttp.onload = function () {
                if (xmlhttp.status == 200) {
                    var buildNumber = xmlhttp.responseText.split('+')[1];
                    var currentBuildNumber = window.localStorage.getItem('buildNumber');

                    if (currentBuildNumber && currentBuildNumber != buildNumber) {
                        caches.delete('flutter-app-manifest');
                        caches.delete('flutter-temp-cache');
                        caches.delete('flutter-app-cache');
                    }

                    window.localStorage.setItem('buildNumber', buildNumber);
                }
                navigator.serviceWorker.register('flutter_service_worker.js');
            }
            xmlhttp.error = function () {navigator.serviceWorker.register('flutter_service_worker.js');}
            xmlhttp.abort = function () {navigator.serviceWorker.register('flutter_service_worker.js');}
            xmlhttp.timeout = function () {navigator.serviceWorker.register('flutter_service_worker.js');}
            xmlhttp.send();
        });
    }
</script>

Activity

  1. jlubeck commented on Aug 13, 2020

    @jlubeck
    Contributor

    @phackwer Just wanted to thank you for the workaround and also ask you if with this script do I also need to add the ?v= to <script src="main.dart.js?v=" type="application/javascript"></script> ?

  2. yjbanov commented on Aug 13, 2020

    @yjbanov
    Contributor

    /cc @jonahwilliams What are your thoughts on this?

  3. jonahwilliams commented on Aug 13, 2020

    @jonahwilliams
    Contributor

    I think we should generally weaken the caching to online-first, with cache busting query strings on the app shell. If apps are still not being updated after that change, it is probably due to a service misconfiguration that we can't work around

  4. coleweinman commented on Aug 17, 2020

    @coleweinman

    The strong caching is such a big problem. The new service works just stay not activated until the cache is manually cleared which results in old versions of apps running indefinitely. I hope this can be fixed in Flutter soon, difficult to have live web apps with this problem.

  5. added
    P2Important issues not at the top of the work list
    toolAffects the "flutter" command-line tool. See also t: labels.
    on Aug 20, 2020
  6. phackwer commented on Sep 10, 2020

    @phackwer
    Author

    @phackwer Just wanted to thank you for the workaround and also ask you if with this script do I also need to add the ?v= to <script src="main.dart.js?v=" type="application/javascript"></script> ?

    Hi, @jlubeck I still have this too. :-) My pipelines do a dump of the buildnumber to a version.txt file. Headers from nginx try to avoid having the browser to cache it, but since we call this file to present version in flutter it was getting cached there. Only way was to call the version.txt file in the index.html before flutter service and force an invalidation of flutter caches when the local storage in the browser had a different buildnumber stored there.

  7. TheCGDF commented on Oct 9, 2020

    @TheCGDF

    @phackwer Just wanted to thank you for the workaround and also ask you if with this script do I also need to add the ?v= to <script src="main.dart.js?v=" type="application/javascript"></script> ?

    But index.html will be cached.

  8. phackwer commented on Nov 2, 2020

    @phackwer
    Author

    set header to index.html not to cache on nginx or apache. I've also set the headers for version.txt not to be cached, so this kind of solves the problem. Sometimes however I still need to press reload 2 times. Don't know why.

    We use bitbucket pipelines (yaml) so replace the command is this

    • &tagBuildNumberOnMainDart echo "Tagging index.html" && sed -i -e ''s,main.dart.js,main.dart.js?v=${BITBUCKET_BUILD_NUMBER},g'' src/build/web/index.html && cat src/build/web/index.html

    Because it's a YAML file, the sed had 2 single quotes, and not a double quote. So, cleaned up command would be

    sed -i -e 's,main.dart.js,main.dart.js?v=${BITBUCKET_BUILD_NUMBER},g' src/build/web/index.html && cat src/build/web/index.html

    Where BITBUCKET_BUILD_NUMBER would be whatever you want to append to it. Run this after you finished your build and before you copy the built code to docker or zip or whatever other means you use to deploy it.

  9. TheCGDF commented on Nov 2, 2020

    @TheCGDF

    We are using CDN so that we cannot control the final header. CDN will always dismiss our Cache-Control in header.

  10. phackwer commented on Nov 4, 2020

    @phackwer
    Author

    If you are using AWS as CDN you can setup the file to be sent with expired headers. Check with the service you use and make this file to be sent always as expired. All services support this kind of feature

    https://www.google.com/search?q=setting+cdn+header+to+expire+a+specific+file&oq=setting+cdn+header+to+expire+a+specific+file&aqs=chrome..69i57.17706j0j1&sourceid=chrome&ie=UTF-8

  11. phackwer commented on Nov 4, 2020

    @phackwer
    Author
  12. phackwer commented on Nov 4, 2020

    @phackwer
    Author
  13. 97 remaining items

  14. phackwer commented on May 24, 2024

    @phackwer
    Author
  15. phackwer commented on May 24, 2024

    @phackwer
    Author
  16. phackwer commented on May 24, 2024

    @phackwer
    Author
  17. c-seeger commented on May 24, 2024

    @c-seeger

    @phackwer Can you keep it open for reference, i think you can also unsubscribe from messages.

  18. adrianjagielak commented on May 24, 2024

    @adrianjagielak
  19. commandiron commented on May 24, 2024

    @commandiron
  20. RajeevRetire100 commented on Jun 5, 2024

    @RajeevRetire100
  21. WCN-llc commented on Jun 8, 2024

    @WCN-llc

    Wouldn't it be better to contact the Chrome team? :-) ))

    Did I understand correctly that Web Flutter has poor performance?

  22. zamirszn commented on Jun 8, 2024

    @zamirszn

    Wouldn't it be better to contact the Chrome team? :-) ))

    Did I understand correctly that Web Flutter has poor performance?

    it's a flutter issue , same thing happens on other browsers too

  23. WCN-llc commented on Jun 8, 2024

    @WCN-llc
  24. zamirszn commented on Jun 9, 2024

    @zamirszn
  25. github-actions commented on Jun 23, 2024

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  26. locked as resolved and limited conversation to collaborators on Jun 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listc: proposalA detailed proposal for a change to Fluttercustomer: crowdAffects or could affect many people, though not necessarily a specific customer.platform-webWeb applications specificallyteam-webOwned by Web platform teamtoolAffects the "flutter" command-line tool. See also t: labels.triaged-webTriaged by Web platform team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions