inertia icon indicating copy to clipboard operation
inertia copied to clipboard

Excessive calls to `window.history.replaceState` when using a `rememberKey` with `useForm`

Open WilHall opened this issue 3 years ago • 3 comments

Versions:

  • @inertiajs/inertia version: 0.10.0
  • @inertiajs/inertia-svelte version: 0.7.4

Describe the problem:

Occasionally in our Sentry reporting, we see the following error:

SecurityError: Attempt to use history.replaceState() more than 100 times per 30 seconds: SecurityError: Attempt to use history.replaceState() more than 100 times per 30 seconds
  at replaceState([native code])
  at replaceState(./node_modules/@inertiajs/inertia/dist/index.js:434:35)
  at saveScrollPositions(./node_modules/@inertiajs/inertia/dist/index.js:145:10)
  at visit(./node_modules/@inertiajs/inertia/dist/index.js:294:16)
  at method(./node_modules/@inertiajs/inertia/dist/index.js:488:69)
  at submit(./node_modules/@inertiajs/inertia-svelte/src/useForm.js:227:17)
  at patch(./node_modules/@inertiajs/inertia-svelte/src/useForm.js:240:12)
  at apply(./app/javascript/pages/setup/savings_profile/PrimaryTransportationMode.svelte:31:11)
  at o(./node_modules/@sentry/browser/esm/helpers.js:87:17)

This is due to throttling of calls to window.history.replaceState by some browsers. The failure in this situation is not graceful, since depending on when the browser starts throttling only partial state may be persisted.

When using a rememberKey with useForm, the error occurs on the following line: https://github.com/inertiajs/inertia/blob/master/packages/inertia-svelte/src/useForm.js#L203

This gets called at least seven times on a successful submission for each modification to the store, in addition to a call any time the form data changes: https://github.com/inertiajs/inertia/blob/master/packages/inertia-svelte/src/useForm.js#L125-L129

Each call results in a call to window.history.replaceState even if the form data and errors did not change.

This issue doesn't exist in inertia-react because useRemember is implemented with a useEffect that includes the form data/errors in the dependency array, and thus Inertia.remember is only called when the data changes: https://github.com/inertiajs/inertia/blob/master/packages/inertia-react/src/useRemember.js#L11-L13

I suspect a similar guard around the Inertia.remember call in inertia-svelte would fix this issue.

Steps to reproduce:

  1. Create a form using useForm and pass a string rememberKey as the first argument
  2. Add a log line in the conditional at https://github.com/inertiajs/inertia/blob/master/packages/inertia-svelte/src/useForm.js#L203
  3. Note that Inertia.remember is called many times, even though the form data did not change

WilHall avatar Feb 22 '22 21:02 WilHall

@WilHall thanks for the detailed report, that's really helpful. I have some ideas to fix it, I spend some time on it next week.

pedroborges avatar Mar 04 '22 13:03 pedroborges

I'm pretty sure this only happens in Safari, see #411

reinink avatar Mar 10 '22 12:03 reinink

Any update on this? I just faced this. should be noted in the readme

sawirricardo avatar Aug 22 '22 05:08 sawirricardo

Hey! Thanks so much for your interest in Inertia.js and for sharing this issue/suggestion.

In an attempt to get on top of the issues and pull requests on this project I am going through all the older issues and PRs and closing them, as there's a decent chance that they have since been resolved or are simply not relevant any longer. My hope is that with a "clean slate" me and the other project maintainers will be able to better keep on top of issues and PRs moving forward.

Of course there's a chance that this issue is still relevant, and if that's the case feel free to simply submit a new issue. The only thing I ask is that you please include a super minimal reproduction of the issue as a Git repo. This makes it much easier for us to reproduce things on our end and ultimately fix it.

Really not trying to be dismissive here, I just need to find a way to get this project back into a state that I am able to maintain it. Hope that makes sense! ❤️

reinink avatar Jul 28 '23 01:07 reinink