-
Notifications
You must be signed in to change notification settings - Fork 70
Description
If a transaction becomes inactive and no request for that transaction has a success event handler then there can be no further writes. We can act as if commit had been called on that transaction and shortcut the process.
Consider the following code
function putSomething(db) {
const kStore = "store";
const transaction = db.transaction([kStore], 'readwrite');
const store = transaction.objectStore(kStore);
store.put(...);
}As written above, in Chrome, this will cause
- An IPC from the renderer to the storage process.
- A response back to the renderer.
- The renderer will find that there is no
successhandler. - The renderer will signal to the storage process to commit, requiring one more IPC.
- During most of this time a lock is held on the store.
If instead, we were to notice that there is no success handler on the request by the end of the JS task, we could silently call commit, remove 2-4 and shorten the duration of that lock.
This is even more of a problem when people naively do this in a pagehide/unload/visibitilitychange handler at end of page life. In that case, steps 2-4 do not occur as the has already been destroyed. This leaves the write uncommitted. In the case where the page is going into BFCache, it leaves the lock held while in BFCache, resulting in eviction if another document contends for that lock.
The one caveat is that currently, this is an observable change in behaviour. JS can add the success handler at any point after the put, as long as it's before step 3 above and add new writes to the transaction. I think adding success handlers later (i.e. in a different JS task) is a pretty weird thing to do, with unpredictable outcomes, it seems unlikely anyone is depending on that behaviour. It's also observable in that puts from pagehide/unload/visibitilitychange would start working.