Improve performance and avoid DOM update issues with CollectionView sorting.
Review Request #11666 — Created June 20, 2021 and submitted
RB.CollectionView
made an attempt to rebuild the list of views
whenever there was asort
event. There were some performance and DOM
update issues that came from this, and during the investigation, it
turned out that sort handling was often run unnecessarily.
collection.fetch()
, by default, would prepare a list of models, add
them to the collection, sort them silently (avoiding any event
triggers), and then eventually trigger some events (includingsort
).
By the timeRB.CollectionView
saw thesort
event, the models were
actually in the correct order, yet it would go through and rebuild the
views and re-add to the DOM.This would have been harmless, but it actually broke
<option selected>
children. On initial render, an<option selected>
would normally
appear selected in the browser, but the sort would then happen
immediately after that render, and browsers wouldn't preserve the sort
order (tested with Chrome and Firefox).This manifested as a bug in the New Review Request page's Branches
drop-down, where the last item would be selected despite the default
branch being marked asselected
. It wasn't an issue in Review Board 3,
due to Backbone 1.0 only triggering thissort
event if we were
actually intentionally sorting (the version we use in Review Board 4,
1.3.3, along with the latest version, 4.0, trigger it under more
conditions, including when populating an empty collection for the first
time without specifyingreset: true
as an option).To avoid this, we're now comparing the order of stored views with the
new order. If it differs, we re-build the order of views and re-add to
the DOM. Otherwise, we skip the entire operation.That not only fixes the
<option selected>
issue, but it also improves
performance.There's one more performance improvement in this change, which is the
manner by which views are sorted and removed. We were looping through
the list of views, trying to find one with the proper model, and while
there was logic to reduce the search space, a more efficient approach is
just to keep a map of model IDs to views and use that for all lookup.Combined, this change improves any views using
RB.CollectionView
and
avoids browser quirks.
All unit tests passed.
Tested the New Review Request page with a Mercurial repository. Saw that
the correct default branch was selected in the Branches list, instead of
the last branch in the list. Verified this on Chrome and Firefox.
Summary | ID |
---|---|
503231b66032469afc447f52967e5a2ee789f335 |
Description | From | Last Updated |
---|---|---|
Should we also do delete this._viewsByModelID[item.cid]? |
david |