Improve BackdropPanel performance by ignoring React
This commit is contained in:
parent
5f9b55eaa9
commit
7f58a21aac
2 changed files with 47 additions and 33 deletions
|
@ -23,26 +23,22 @@ interface IProps {
|
||||||
backgroundImage?: CanvasImageSource;
|
backgroundImage?: CanvasImageSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IState {
|
export default class BackdropPanel extends React.PureComponent<IProps> {
|
||||||
spacePanelWidth: number;
|
|
||||||
roomListWidth: number;
|
|
||||||
viewportHeight: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class BackdropPanel extends React.PureComponent<IProps, IState> {
|
|
||||||
private spacesCanvasRef = createRef<HTMLCanvasElement>();
|
private spacesCanvasRef = createRef<HTMLCanvasElement>();
|
||||||
private roomListCanvasRef = createRef<HTMLCanvasElement>();
|
private roomListCanvasRef = createRef<HTMLCanvasElement>();
|
||||||
|
|
||||||
private spacesCtx: CanvasRenderingContext2D;
|
private spacesCtx: CanvasRenderingContext2D;
|
||||||
private roomListCtx: CanvasRenderingContext2D;
|
private roomListCtx: CanvasRenderingContext2D;
|
||||||
|
|
||||||
|
private sizes = {
|
||||||
|
spacePanelWidth: 0,
|
||||||
|
roomListWidth: 0,
|
||||||
|
height: 0,
|
||||||
|
};
|
||||||
|
private currentFrame?: number;
|
||||||
|
|
||||||
constructor(props: IProps) {
|
constructor(props: IProps) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
|
||||||
spacePanelWidth: 0,
|
|
||||||
roomListWidth: 0,
|
|
||||||
viewportHeight: UIStore.instance.windowHeight,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentDidMount() {
|
public componentDidMount() {
|
||||||
|
@ -52,30 +48,41 @@ export default class BackdropPanel extends React.PureComponent<IProps, IState> {
|
||||||
UIStore.instance.on("LeftPanel", this.onResize);
|
UIStore.instance.on("LeftPanel", this.onResize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public componentDidUpdate() {
|
||||||
|
if (this.props.backgroundImage) {
|
||||||
|
this.refreshBackdropImage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public componentWillUnmount() {
|
public componentWillUnmount() {
|
||||||
UIStore.instance.off("SpacePanel", this.onResize);
|
UIStore.instance.off("SpacePanel", this.onResize);
|
||||||
UIStore.instance.off("LeftPanel", this.onResize);
|
UIStore.instance.off("LeftPanel", this.onResize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentDidUpdate() {
|
|
||||||
if (this.props.backgroundImage) {
|
|
||||||
requestAnimationFrame(this.refreshBackdropImage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private onResize = () => {
|
private onResize = () => {
|
||||||
const spacePanelDimensions = UIStore.instance.getElementDimensions("SpacePanel");
|
const spacePanelDimensions = UIStore.instance.getElementDimensions("SpacePanel");
|
||||||
const roomListDimensions = UIStore.instance.getElementDimensions("LeftPanel");
|
const roomListDimensions = UIStore.instance.getElementDimensions("LeftPanel");
|
||||||
this.setState({
|
this.sizes = {
|
||||||
spacePanelWidth: spacePanelDimensions ? spacePanelDimensions.width : 0,
|
spacePanelWidth: spacePanelDimensions?.width ?? 0,
|
||||||
roomListWidth: roomListDimensions ? roomListDimensions.width : 0,
|
roomListWidth: roomListDimensions?.width ?? 0,
|
||||||
viewportHeight: UIStore.instance.windowHeight,
|
height: UIStore.instance.windowHeight,
|
||||||
});
|
};
|
||||||
|
if (this.props.backgroundImage) {
|
||||||
|
this.refreshBackdropImage();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private animate = () => {
|
||||||
|
if (this.currentFrame !== undefined) {
|
||||||
|
cancelAnimationFrame(this.currentFrame);
|
||||||
|
this.currentFrame = undefined;
|
||||||
|
}
|
||||||
|
this.currentFrame = requestAnimationFrame(this.refreshBackdropImage);
|
||||||
};
|
};
|
||||||
|
|
||||||
private refreshBackdropImage = (): void => {
|
private refreshBackdropImage = (): void => {
|
||||||
const width = this.state.spacePanelWidth + this.state.roomListWidth;
|
const { spacePanelWidth, roomListWidth, height } = this.sizes;
|
||||||
const height = this.state.viewportHeight;
|
const width = spacePanelWidth + roomListWidth;
|
||||||
const { backgroundImage } = this.props;
|
const { backgroundImage } = this.props;
|
||||||
|
|
||||||
const imageWidth = (backgroundImage as ImageBitmap).width
|
const imageWidth = (backgroundImage as ImageBitmap).width
|
||||||
|
@ -98,10 +105,11 @@ export default class BackdropPanel extends React.PureComponent<IProps, IState> {
|
||||||
const x = (width - resultWidth) / 2;
|
const x = (width - resultWidth) / 2;
|
||||||
const y = (height - resultHeight) / 2;
|
const y = (height - resultHeight) / 2;
|
||||||
|
|
||||||
this.spacesCanvasRef.current.width = this.state.spacePanelWidth;
|
this.spacesCanvasRef.current.width = spacePanelWidth;
|
||||||
this.spacesCanvasRef.current.height = this.state.viewportHeight;
|
this.spacesCanvasRef.current.height = height;
|
||||||
this.roomListCanvasRef.current.width = this.state.roomListWidth;
|
this.roomListCanvasRef.current.width = roomListWidth;
|
||||||
this.roomListCanvasRef.current.height = this.state.viewportHeight;
|
this.roomListCanvasRef.current.height = height;
|
||||||
|
this.roomListCanvasRef.current.style.transform = `translateX(${spacePanelWidth}px)`;
|
||||||
|
|
||||||
this.spacesCtx.filter = `blur(30px)`;
|
this.spacesCtx.filter = `blur(30px)`;
|
||||||
this.roomListCtx.filter = `blur(60px)`;
|
this.roomListCtx.filter = `blur(60px)`;
|
||||||
|
@ -116,7 +124,7 @@ export default class BackdropPanel extends React.PureComponent<IProps, IState> {
|
||||||
backgroundImage,
|
backgroundImage,
|
||||||
0, 0,
|
0, 0,
|
||||||
imageWidth, imageHeight,
|
imageWidth, imageHeight,
|
||||||
x - this.state.spacePanelWidth,
|
x - spacePanelWidth,
|
||||||
y,
|
y,
|
||||||
resultWidth,
|
resultWidth,
|
||||||
resultHeight,
|
resultHeight,
|
||||||
|
@ -134,7 +142,7 @@ export default class BackdropPanel extends React.PureComponent<IProps, IState> {
|
||||||
/>
|
/>
|
||||||
<canvas
|
<canvas
|
||||||
style={{
|
style={{
|
||||||
transform: `translateX(${this.state.spacePanelWidth}px)`,
|
transform: `translateX(0)`,
|
||||||
opacity: .1,
|
opacity: .1,
|
||||||
}}
|
}}
|
||||||
ref={this.roomListCanvasRef}
|
ref={this.roomListCanvasRef}
|
||||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { ComponentProps, Dispatch, ReactNode, SetStateAction, useEffect, useState } from "react";
|
import React, { ComponentProps, Dispatch, ReactNode, SetStateAction, useEffect, useLayoutEffect, useRef, useState } from "react";
|
||||||
import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd";
|
import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
|
@ -42,8 +42,8 @@ import IconizedContextMenu, {
|
||||||
IconizedContextMenuOptionList,
|
IconizedContextMenuOptionList,
|
||||||
} from "../context_menus/IconizedContextMenu";
|
} from "../context_menus/IconizedContextMenu";
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
import UIStore from "../../../stores/UIStore";
|
|
||||||
import { SettingLevel } from "../../../settings/SettingLevel";
|
import { SettingLevel } from "../../../settings/SettingLevel";
|
||||||
|
import UIStore from "../../../stores/UIStore";
|
||||||
|
|
||||||
const useSpaces = (): [Room[], Room[], Room | null] => {
|
const useSpaces = (): [Room[], Room[], Room | null] => {
|
||||||
const invites = useEventEmitterState<Room[]>(SpaceStore.instance, UPDATE_INVITED_SPACES, () => {
|
const invites = useEventEmitterState<Room[]>(SpaceStore.instance, UPDATE_INVITED_SPACES, () => {
|
||||||
|
@ -207,6 +207,11 @@ const InnerSpacePanel = React.memo<IInnerSpacePanelProps>(({ children, isPanelCo
|
||||||
|
|
||||||
const SpacePanel = () => {
|
const SpacePanel = () => {
|
||||||
const [isPanelCollapsed, setPanelCollapsed] = useState(true);
|
const [isPanelCollapsed, setPanelCollapsed] = useState(true);
|
||||||
|
const ref = useRef<HTMLUListElement>();
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
UIStore.instance.trackElementDimensions("SpacePanel", ref.current);
|
||||||
|
return () => UIStore.instance.stopTrackingElementDimensions("SpacePanel");
|
||||||
|
}, []);
|
||||||
|
|
||||||
const onKeyDown = (ev: React.KeyboardEvent) => {
|
const onKeyDown = (ev: React.KeyboardEvent) => {
|
||||||
let handled = true;
|
let handled = true;
|
||||||
|
@ -281,6 +286,7 @@ const SpacePanel = () => {
|
||||||
onKeyDown={onKeyDownHandler}
|
onKeyDown={onKeyDownHandler}
|
||||||
role="tree"
|
role="tree"
|
||||||
aria-label={_t("Spaces")}
|
aria-label={_t("Spaces")}
|
||||||
|
ref={ref}
|
||||||
>
|
>
|
||||||
<Droppable droppableId="top-level-spaces">
|
<Droppable droppableId="top-level-spaces">
|
||||||
{ (provided, snapshot) => (
|
{ (provided, snapshot) => (
|
||||||
|
|
Loading…
Reference in a new issue