title: Activate updated service worker on refresh
body: <p>When a service worker updates, it doesn't take control of the page right way; it goes into a "waiting" state, waiting to be activated.</p>
  
  <p>Surprisingly, the updated service worker doesn't even take control of the tab after refreshing the page. Google explains:</p>
  
  <p><a href="https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/lifecycle" rel="noreferrer">https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/lifecycle</a></p>
  
  <blockquote>
    <p>Even if you only have one tab open to the demo, refreshing the page
    isn't enough to let the new version take over. This is due to how
    browser navigations work. When you navigate, the current page doesn't
    go away until the response headers have been received, and even then
    the current page may stay if the response has a <code>Content-Disposition</code>
    header. Because of this overlap, the current service worker is always
    controlling a client during a refresh.</p>
    
    <p>To get the update, close or navigate away from all tabs using the
    current service worker. Then, when you navigate to the demo again, you
    should see the horse [updated content].</p>
    
    <p>This pattern is similar to how Chrome updates. Updates to Chrome
    download in the background, but don't apply until Chrome restarts. In
    the mean time, you can continue to use the current version without
    disruption. However, this is a pain during development, but DevTools
    has ways to make it easier, which I'll cover later in this article.</p>
  </blockquote>
  
  <p>This behavior makes sense in the case of multiple tabs. My app is a bundle that needs to be updated atomically; we can't mix and match part of the old bundle and part of the new bundle. (In a native app, atomicity is automatic and guaranteed.)</p>
  
  <p>But in the case of a single tab, which I'll call the "last open tab" of the app, this behavior is not what I want. I want refreshing the last open tab to update my service worker.</p>
  
  <p>(It's hard to imagine that anybody actually <em>wants</em> the old service worker to continue running when the last open tab is refreshed. Google's "navigation overlap" argument sounds to me like a good excuse for an unfortunate bug.)</p>
  
  <p>My app is normally only used in a single tab. In production, I want my users to be able to use the latest code just by refreshing the page, but that won't work: the old service worker will remain in control across refreshes.</p>
  
  <p>I don't want to have to tell users, "to receive updates, be sure to close or navigate away from my app." I want to tell them, "just refresh."</p>
  
  <p>How can I activate my updated service worker when the user refreshes the page?</p>
  
  <p>EDIT: There's one answer I'm aware of that's quick, easy, and wrong: <code>skipWaiting</code> in the service worker's install event. <code>skipWaiting</code> will make the new service worker take effect as soon as the update downloads, while the old page tab is open. That makes the update unsafely nonatomic; it's like replacing a native app bundle while the app's running. That's not OK for me. I need to wait until the user refreshes the page of the last open tab.</p>