From 0a846cb1b5f68b1b8acb8f67a502bb63bbc9fdec Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 21 Jul 2020 15:02:59 -0600 Subject: [PATCH] Don't hammer on the layout engine with avatar updates for the background Changing the property on every render of the left panel (which is basically all the time) is super bad on the GPU and for our CPU. We should only do that when something changes. --- src/components/structures/LeftPanel.tsx | 22 ++++++++++++++++++++++ src/components/structures/UserMenu.tsx | 3 --- src/settings/Settings.js | 4 ++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/components/structures/LeftPanel.tsx b/src/components/structures/LeftPanel.tsx index 43e75ffe88..86136233d8 100644 --- a/src/components/structures/LeftPanel.tsx +++ b/src/components/structures/LeftPanel.tsx @@ -35,6 +35,8 @@ import RoomListStore, { LISTS_UPDATE_EVENT } from "../../stores/room-list/RoomLi import {Key} from "../../Keyboard"; import IndicatorScrollbar from "../structures/IndicatorScrollbar"; import AccessibleTooltipButton from "../views/elements/AccessibleTooltipButton"; +import { OwnProfileStore } from "../../stores/OwnProfileStore"; +import { MatrixClientPeg } from "../../MatrixClientPeg"; interface IProps { isMinimized: boolean; @@ -59,6 +61,7 @@ const cssClasses = [ export default class LeftPanel extends React.Component { private listContainerRef: React.RefObject = createRef(); private tagPanelWatcherRef: string; + private bgImageWatcherRef: string; private focusedElement = null; private isDoingStickyHeaders = false; @@ -73,6 +76,9 @@ export default class LeftPanel extends React.Component { BreadcrumbsStore.instance.on(UPDATE_EVENT, this.onBreadcrumbsUpdate); RoomListStore.instance.on(LISTS_UPDATE_EVENT, this.onBreadcrumbsUpdate); + OwnProfileStore.instance.on(UPDATE_EVENT, this.onBackgroundImageUpdate); + this.bgImageWatcherRef = SettingsStore.watchSetting( + "RoomList.backgroundImage", null, this.onBackgroundImageUpdate); this.tagPanelWatcherRef = SettingsStore.watchSetting("TagPanel.enableTagPanel", null, () => { this.setState({showTagPanel: SettingsStore.getValue("TagPanel.enableTagPanel")}); }); @@ -84,8 +90,10 @@ export default class LeftPanel extends React.Component { public componentWillUnmount() { SettingsStore.unwatchSetting(this.tagPanelWatcherRef); + SettingsStore.unwatchSetting(this.bgImageWatcherRef); BreadcrumbsStore.instance.off(UPDATE_EVENT, this.onBreadcrumbsUpdate); RoomListStore.instance.off(LISTS_UPDATE_EVENT, this.onBreadcrumbsUpdate); + OwnProfileStore.instance.off(UPDATE_EVENT, this.onBackgroundImageUpdate); this.props.resizeNotifier.off("middlePanelResizedNoisy", this.onResize); } @@ -108,6 +116,20 @@ export default class LeftPanel extends React.Component { } }; + private onBackgroundImageUpdate = () => { + // Note: we do this in the LeftPanel as it uses this variable most prominently. + const avatarSize = 32; // arbitrary + let avatarUrl = OwnProfileStore.instance.getHttpAvatarUrl(avatarSize); + const settingBgMxc = SettingsStore.getValue("RoomList.backgroundImage"); + if (settingBgMxc) { + avatarUrl = MatrixClientPeg.get().mxcUrlToHttp(settingBgMxc, avatarSize, avatarSize); + } + const avatarUrlProp = `url(${avatarUrl})`; + if (document.body.style.getPropertyValue("--avatar-url") !== avatarUrlProp) { + document.body.style.setProperty("--avatar-url", avatarUrlProp); + } + }; + private handleStickyHeaders(list: HTMLDivElement) { if (this.isDoingStickyHeaders) return; this.isDoingStickyHeaders = true; diff --git a/src/components/structures/UserMenu.tsx b/src/components/structures/UserMenu.tsx index c9360d7ac3..8f9ca8d734 100644 --- a/src/components/structures/UserMenu.tsx +++ b/src/components/structures/UserMenu.tsx @@ -306,9 +306,6 @@ export default class UserMenu extends React.Component { public render() { const avatarSize = 32; // should match border-radius of the avatar - const {body} = document; - const avatarUrl = OwnProfileStore.instance.getHttpAvatarUrl(avatarSize); - body.style.setProperty("--avatar-url", `url('${avatarUrl}')`); let name = {OwnProfileStore.instance.displayName}; let buttons = ( diff --git a/src/settings/Settings.js b/src/settings/Settings.js index a8b6310b90..50d6ffc09e 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -166,6 +166,10 @@ export const SETTINGS = { displayName: _td("Show info about bridges in room settings"), default: false, }, + "RoomList.backgroundImage": { + supportedLevels: LEVELS_ACCOUNT_SETTINGS, + default: null, + }, "baseFontSize": { displayName: _td("Font size"), supportedLevels: LEVELS_ACCOUNT_SETTINGS,