element-web/src/shouldHideEvent.js
Travis Ralston f2468f562d Speed up room unread checks by not hitting the SettingsStore so often
This was noticed as a problem after `Unread.doesRoomHaveUnreadMessages` started being called a lot more frequently. Down the call stack, `shouldHideEvent` is called which used to call into the `SettingsStore` frequently, causing performance issues in many cases. The `SettingsStore` tries to be as fast as possible, however there's still code paths that make it less than desirable to use as the first condition in an AND condition. By not hitting the `SettingsStore` so often, we can shorten those code paths.

As for how much this improves things, I ran some profiling before and after this change. This was done on my massive 1200+ room account. Before it was possible to see nearly 2 seconds spent generating room lists where 20-130ms per room was spent figuring out if the room has unread messages. Afterwards, the room list was generating within ~330ms and each unread check taking 0-2ms. There's still room for improvement on generating the room list, however the significant gains here seem worth it.
2018-12-07 20:15:21 -07:00

56 lines
2.1 KiB
JavaScript

/*
Copyright 2017 Michael Telatynski <7t3chguy@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import SettingsStore from "./settings/SettingsStore";
function memberEventDiff(ev) {
const diff = {
isMemberEvent: ev.getType() === 'm.room.member',
};
// If is not a Member Event then the other checks do not apply, so bail early.
if (!diff.isMemberEvent) return diff;
const content = ev.getContent();
const prevContent = ev.getPrevContent();
const isMembershipChanged = content.membership !== prevContent.membership;
diff.isJoin = isMembershipChanged && content.membership === 'join';
diff.isPart = isMembershipChanged && content.membership === 'leave' && ev.getStateKey() === ev.getSender();
const isJoinToJoin = !isMembershipChanged && content.membership === 'join';
diff.isDisplaynameChange = isJoinToJoin && content.displayname !== prevContent.displayname;
diff.isAvatarChange = isJoinToJoin && content.avatar_url !== prevContent.avatar_url;
return diff;
}
export default function shouldHideEvent(ev) {
// Wrap getValue() for readability
const isEnabled = (name) => SettingsStore.getValue(name, ev.getRoomId());
// Hide redacted events
if (ev.isRedacted() && isEnabled('hideRedactions')) return true;
const eventDiff = memberEventDiff(ev);
if (eventDiff.isMemberEvent) {
if ((eventDiff.isJoin || eventDiff.isPart) && isEnabled('hideJoinLeaves')) return true;
if (eventDiff.isAvatarChange && isEnabled('hideAvatarChanges')) return true;
if (eventDiff.isDisplaynameChange && isEnabled('hideDisplaynameChanges')) return true;
}
return false;
}