cache-polyfill relies on indexedDB, but was modified so we can use the same indexedDBShim our app uses to avoid multiple instances
cache-polyfill implementation uses cursors to find matches
cache-polyfill doesn’t actually cache requests in memory. Cache storage is a special type of browser cache, so the polyfill queries indexedDB for every request
In the case of ticket reports, the reference binding recently began resolving sobjects that are part of the new sync/store. The old method of resolving a reference involved a primary key ‘get’ by id to indexedDB handled by specific stores. Resolving sobjects that are part of the new sync/store requires multiple steps:
a request for the sobject description which is intercepted and resolved by the cache-polyfill which makes a cursor call to indexedDB
a second request that uses the description and an Id to make a cursor call to indexedDB to fetch the record
There are multiple causes for the slowdown in rendering ticket reports:
RecordTypes are now included in the v2 sync
making multiple cursor calls to indexedDB to resolve a single record is slower than the previous method of making a single primary key fetch
A performance profile of rendering the “standard” ticket report comparing Chrome to iOS (simulator) reveals the following:
Chrome makes a single describe call for RecordType and utilizes the cache for subsequent requests. The single request takes about 25ms
Chrome takes about 150ms to resolve each RecordType
iOS Simulator makes a describe call for RecordType for every single ticket item rendered. Each request takes anywhere from 5~10ms
iOS Simulator takes anywhere from 400~2000ms to resolve each RecordType
Resolution Optimizations
After careful measurement, we determined the cache-polyfill was inefficient but was not the primary cause of the observable degradation in report rendering performance. The implementation of sync/store.get() was slow and was also blocking in WebSQL because each get() was a separate transaction. The following summarizes the changes.
Update cache-polyfill to not use indexedDB (which was in turn using indexedDBShim, which translated to WebSQL) and use native localstorage which is fast
Update sync/store.get() to use indexedDB directly to fetch individual records by index/key (instead of using dexie wrapper for syntactic sugar)
Make sure we reuse a single instance of Dexie instead of instantiating for every CRUD method call
Don’t open indexedDB directly every time we try to resolve a reference to look for an sobject table.
Test Plan
Checklist for Merging
Enter the Pull Request number in the card properties
Mingle Card: 3928 Steps to reproduce
Expected result
Report should load quickly
Actual Result
Report flickers heavily as ticket items are loaded/reloaded
Related Cards
temporary fix in #3927
Analysis
In the case of ticket reports, the reference binding recently began resolving sobjects that are part of the new sync/store. The old method of resolving a reference involved a primary key ‘get’ by id to indexedDB handled by specific stores. Resolving sobjects that are part of the new sync/store requires multiple steps:
There are multiple causes for the slowdown in rendering ticket reports:
A performance profile of rendering the “standard” ticket report comparing Chrome to iOS (simulator) reveals the following:
Resolution Optimizations
After careful measurement, we determined the cache-polyfill was inefficient but was not the primary cause of the observable degradation in report rendering performance. The implementation of sync/store.get() was slow and was also blocking in WebSQL because each get() was a separate transaction. The following summarizes the changes.
Test Plan
Checklist for Merging