New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Workaround for Safari issue with getAll(). #579
Conversation
Resolves issue #565
This breaks the performance of e.g. Chrome, too and even the Safari (iOS 10.3, iOS 11) versions which do support IndexdedDB 2.0 and the getAll method. See my stackoverflow question/issue regarding very, very bad performance. Testing with getAll instead results in 10x faster loading times for us. |
@timbru31 Thanks. I never like UA sniffing, but need to find a way to work around the bug of Safari idintified in the more recent comments of issue 565. If I roll back this PR we will get issues again on Safari: Version 10.1.2 (12603.3.8). At least I must fix the false positive for Chrome (which is a major!) but can we identify the Safari issue some other way? Does this lib deal with that? https://github.com/raphinesse/dexie-batch ? Any idea someone? |
Hm maybe |
Besides that, getAll works fine for me on iOS 10.3 and iOS 11 - I'd like to keep support for these, too. |
We might be able to combine the vendor with the version from the userAgent but the test will probably be rather brittle.. |
navigator.appVersion might help to detect the iOS versions: https://developer.mozilla.org/en-US/docs/Web/API/NavigatorID/appVersion (deprecated though :/) |
appVersion on Mac OS Safari is basically the same as userAgent minus the "Mozilla" at the beginning of the UA string.. |
The issue in Safari 10.1 on iOS 10.3 is rather severe. Repro: http://dexie.org/test/dexie-issue-565/ |
Output: Testing Safari issue with IDBObjectStore.getAll() Status: Preventing eternal reload. Last status was: Could put item. Now trying IDBObjectStore.getAll() navigator.userAgent: Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E269 Safari/602.1 navigator.vendor: Apple Computer, Inc. navigator.appVersion: 5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E269 Safari/602.1 |
Also on desktop mac, same issue: navigator.userAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8 navigator.vendor: Apple Computer, Inc. navigator.appVersion: 5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8 |
Could someone try the repro on a newer Safari version to see if it is solved? Note that this happens from a WebWorker calling IDBObjectStore.getAll(). Unless we can see a non-failing Safari version, we need to keep preventing using getAll() on Safari (but keep Chrome untouched of course). If we see it's fixed, we could allow it functional versions only. |
However, I noticed that running the code outside a Worker, the web page did not reload - this means we need to detect a Worker environment and the special Safari versions? |
Ok, great, so Safari 604 is fine but not <=603. What about the following: hasGetAll = 'getAll' in store &&
!(/Apple/.test(navigator.vendor) &&
[].concat(navigator.userAgent.match(/Safari\/(\d*)/))[1] < 604); |
What about the WebWorker check, too? Something like this could work: https://stackoverflow.com/a/18002694/1902598 see my test: https://pastebin.com/iC9jbmmZ (just logs to the console) |
I haven't checked that it's only an issue in workers. I'll test now. |
Tested. Issue seems only tied to workers, so I could use that check. But I found that navigator.vendor is not accessable from workers :( only navigator.userAgent seem to be accessable. So I have to do something else than /Apple/.test(navigator.vendor). Suggestion? |
I've updated the check to: // Bug with getAll() on Safari ver<604 on Workers only, see discussion following PR #579
if (/Safari/.test(navigator.userAgent) &&
!/Chrome/.test(navigator.userAgent) &&
_global.WorkerGlobalScope && _global instanceof _global.WorkerGlobalScope &&
[].concat(navigator.userAgent.match(/Safari\/(\d*)/))[1] < 604)
{
hasGetAll = false;
} Thoughts? |
Ah! Edge also has "Safari" in UA! Another false positive. Need to update yet again. if (/Safari/.test(navigator.userAgent) &&
!/(Chrome\/|Edge\/)/.test(navigator.userAgent) &&
_global.WorkerGlobalScope && _global instanceof _global.WorkerGlobalScope &&
[].concat(navigator.userAgent.match(/Safari\/(\d*)/))[1] < 604)
{
hasGetAll = false;
} |
PR #579 was meant to work around a severe Safari issue with IDBObjectStore.getAll() that when called from a Web worker, results in a page crash followed by an automatic page reload. Since getAll() is just an optimization and not needed for IndexedDB to work, PR 579 shut down this optimization of utilizing on Safari. Due to the nature of the Safari bug (page crash + reload), feature testing was not possible - we could only do user-agent sniffing to avoid the bug. The user-agent sniffing in PR #579 did only look for "Safari" in user-agent, which made it also affect Chrome and Opera browsers (which was not the intent). Also, the bug has since been fixed in a later version of Safari + it only happened when called from a web worker, so we needed a more fine grained control of whether the getAll() optimization should be avoided or not. This new PR will replace the user-agent code from PR #579 with another more fine grained check that only disables getAll() when: * browser is Safari (user agent contains "Safari" but not "Chrome" or "Edge") * we are in a Worker environment * Safari internal version number is less than 604, as the issue has been fixed in 604.
Sorry for opening this issue up again. I'm pretty sure I'm running into this issue again on an iPhone SE iOS 10.3 emulator using a webkit view (cordova). Edit: I can confirm that it fixes the bug when I manually set hasGetAll to false. |
If you use dexie@3 it will work the same on all browsers. That is, it will avoid this issue without UA sniffing |
Resolves issue #565