RCFilters: Don't apply/clear highlights 66 times
authorRoan Kattouw <roan.kattouw@gmail.com>
Sat, 30 Sep 2017 00:35:43 +0000 (17:35 -0700)
committerRoan Kattouw <roan.kattouw@gmail.com>
Sat, 30 Sep 2017 00:35:43 +0000 (17:35 -0700)
Applying highlights on init was very slow, because applyHighlights
was called 66 times and clearHighlights 64 times.

We first call toggleHighlight() on each filter item, which
leads to update events being emitted by each item, and onItemUpdate
calls clearHighlights() followed by applyHighlights().
There are 64 filter items in my setup, so that's 64 pairs of
clear+apply calls. Then we emit highlightChange, which causes
another apply call, and onModelUpdate calls apply as well.

This change makes sure that the model-wide ("global") highlight
flag is always set to false while we're toggling the highlight
flags on the individual items, so that onItemUpdate short-circuits
and doesn't call clear/apply. There are still other issues (too many
places call clear/apply, too many events emitted), but running the
highlight code twice instead of 130 times on init fixes most
of the performance problems.

Bug: T177107
Change-Id: I65c409ccfabd974ef0b5e2bddff70c9e78e8fd60

resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js

index 3b882a6..fdea5ef 100644 (file)
                enable = enable === undefined ? !this.highlightEnabled : enable;
 
                if ( this.highlightEnabled !== enable ) {
-                       this.highlightEnabled = enable;
-
+                       // HACK make sure highlights are disabled globally while we toggle on the items,
+                       // otherwise we'll call clearHighlight() and applyHighlight() many many times
+                       this.highlightEnabled = false;
                        this.getItems().forEach( function ( filterItem ) {
                                filterItem.toggleHighlight( this.highlightEnabled );
                        }.bind( this ) );
 
+                       this.highlightEnabled = enable;
                        this.emit( 'highlightChange', this.highlightEnabled );
                }
        };