mdn / content

The content behind MDN Web Docs
https://developer.mozilla.org
Other
9.16k stars 22.46k forks source link

Storage.setItem is a synchronous function, but the browser's implementation of committing changes to storage may be asynchronous #36295

Open davidbroyles opened 5 days ago

davidbroyles commented 5 days ago

MDN URL

https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API

What specific section or headline is this issue about?

setItem generally throughout this section

What information was incorrect, unhelpful, or incomplete?

There's no mention of potential loss of data if something is written via Storage.setItem(...) and immediately followed by e.g. window.location.href = '/'

What did you expect to see?

I don't know if this page, or setItem's, or sessionStorage & localStorage is the most appropriate place for a note, but I've run into a lot of debugging situations where the browser's implementation of committing the data occasionally fails to complete before a redirect, resulting in a loss of data. While the JS function is itself synchronous, a lot of browser implementations appear to have asynchronous implementations with respect to nonvolatile storage across pageloads, creating a race condition. Adding a note to give a brief pause before redirects/unloads could save a lot of devs heartache. I'm not convinced that a getItem check would suffice, since it may be reading from the same volatile cache that setItem is initially writing to.

Do you have any supporting links, references, or citations?

No response

Do you have anything more you want to share?

No response

MDN metadata

Page report details * Folder: `en-us/web/api/web_storage_api` * MDN URL: https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API * GitHub URL: https://github.com/mdn/content/blob/main/files/en-us/web/api/web_storage_api/index.md * Last commit: https://github.com/mdn/content/commit/44c4ec928281dc2d7c5ea42b7d2c74a2013f16ac * Document last modified: 2024-07-26T15:41:23.000Z
skyclouds2001 commented 5 days ago

There's no mention of potential loss of data if something is written via Storage.setItem(...) and immediately followed by e.g. window.href = '/'

I think you are saying location.href = '/'?

And I try to make some small test, but can not figure out if the issue would happen.

davidbroyles commented 5 days ago

Yes, sorry! I updated the original comment with window.location.href. I'm not sure if it has to do with larger/complex scripts having more overhead and making late writes more likely for sessionStorage, but I'm also having trouble replicating it with a smaller test, e.g.

console.log('retrieved value: '+sessionStorage.getItem('test'));
var val = Date.now();
console.log('written value: '+val);
sessionStorage.setItem('test', val);
window.location.href = '?'+val;

The error has occurred for me across multiple projects using different frameworks, though. The fix was always the same, but I didn't know what was causing it. When I asked chatGPT, it said

sessionStorage operations are synchronous, but if you write to sessionStorage immediately before a page redirect, the browser may not have enough time to properly commit the data to storage before the page unloads. This can lead to scenarios where the data is not available on the next page load.

Sorry if opening this Issue was premature, we can close it if it's not sufficiently vetted for documentation. I've just had this problem multiple times across very different environments, and the fix was always the same.

Josh-Cena commented 5 days ago

I'm not sure if there's anything actionable if we can't isolate a demo and confirm that it's working as intended and not a browser bug.