githubbob42 / mingle2github2

0 stars 1 forks source link

Degraded iPad report rendering performance #3609

Open githubbob42 opened 8 years ago

githubbob42 commented 8 years ago

Mingle Card: 3928 Steps to reproduce

| | |
|-|-|
|**Version #**|
| |
|**OS**|
|iOS|
|**Browser**|
|Safari|
|**Username**|
| |
|**Password**|
| |
  1. revert temp fix in #3927
  2. add a few dozen ticket items to a ticket
  3. open up reports and select “Standard Report”

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:

  1. a request for the sobject description which is intercepted and resolved by the cache-polyfill which makes a cursor call to indexedDB
  2. 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:

  1. RecordTypes are now included in the v2 sync
  2. 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:

  1. Chrome makes a single describe call for RecordType and utilizes the cache for subsequent requests. The single request takes about 25ms
  2. Chrome takes about 150ms to resolve each RecordType
  3. iOS Simulator makes a describe call for RecordType for every single ticket item rendered. Each request takes anywhere from 5~10ms
  4. 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.

  1. Update cache-polyfill to not use indexedDB (which was in turn using indexedDBShim, which translated to WebSQL) and use native localstorage which is fast
  2. Update sync/store.get() to use indexedDB directly to fetch individual records by index/key (instead of using dexie wrapper for syntactic sugar)
  3. Make sure we reuse a single instance of Dexie instead of instantiating for every CRUD method call
  4. Don’t open indexedDB directly every time we try to resolve a reference to look for an sobject table.

Test Plan

Checklist for Merging

githubbob42 commented 8 years ago

Pull Request #1718