Perf for thread list. See description

- ComponentRegistry: findComponentsMatching often returns zero results but makes a lot of transient data structures. Add a cache to make it O[1]

- Contact isMe is called a zillion times to compute thread participant display. Checking the AccountStore had been required was slow.

- getStandardCategory is also called a ton. Rather than create a filtered array and then searching that, just search the existing array.
This commit is contained in:
Ben Gotow 2016-01-12 09:10:52 -08:00
parent 4b11b0586d
commit d424192161
3 changed files with 12 additions and 3 deletions

View file

@ -19,6 +19,7 @@ class ComponentRegistry
constructor: ->
@_registry = {}
@_cache = {}
@_showComponentRegions = false
@ -61,6 +62,7 @@ class ComponentRegistry
if @_registry[component.displayName] and @_registry[component.displayName].component isnt component
throw new Error("ComponentRegistry.register(): A different component was already registered with the name #{component.displayName}")
@_cache = {}
@_registry[component.displayName] = {component, locations, modes, roles}
# Trigger listeners. It's very important the component registry is debounced.
@ -74,6 +76,7 @@ class ComponentRegistry
unregister: (component) =>
if _.isString(component)
throw new Error("ComponentRegistry.unregister() must be called with a component.")
@_cache = {}
delete @_registry[component.displayName]
@triggerDebounced()
@ -120,6 +123,9 @@ class ComponentRegistry
if not descriptor?
throw new Error("ComponentRegistry.findComponentsMatching called without descriptor")
cacheKey = JSON.stringify(descriptor)
return @_cache[cacheKey] if @_cache[cacheKey]
{locations, modes, roles} = @_pluralizeDescriptor(descriptor)
if not locations and not modes and not roles
@ -140,7 +146,9 @@ class ComponentRegistry
return false
return true
_.map entries, (entry) -> entry.component
results = _.map entries, (entry) -> entry.component
@_cache[cacheKey] = results
return results
triggerDebounced: _.debounce(( -> @trigger(@)), 1)
@ -153,6 +161,7 @@ class ComponentRegistry
{locations, modes, roles}
_clear: =>
@_cache = {}
@_registry = {}
# Showing Component Regions

View file

@ -2,6 +2,7 @@ Model = require './model'
Utils = require './utils'
Attributes = require '../attributes'
RegExpUtils = require '../../regexp-utils'
AccountStore = require '../stores/account-store'
_ = require 'underscore'
name_prefixes = {}
@ -93,7 +94,6 @@ class Contact extends Model
# You should use this method instead of comparing the user's email address to
# the account email, since it is case-insensitive and future-proof.
isMe: ->
AccountStore = require '../stores/account-store'
for account in AccountStore.accounts()
if Utils.emailIsEquivalent(@email, account.emailAddress)
return true

View file

@ -51,7 +51,7 @@ class CategoryStore extends NylasStore
return null unless account?
if not name in StandardCategoryNames
throw new Error("'#{name}' is not a standard category")
return _.findWhere @standardCategories(account), {name}
return _.findWhere(@categories(account), {name})
# Public: Returns the Folder or Label object that should be used for "Archive"
# actions. On Gmail, this is the "all" label. On providers using folders, it