Keep unchanged metadata stable for memoization
Everytime the metadata got updated, unchanged values could cause rerenders because their reference changed. This happened e.g., for the "customThemes" which caused the MUI theme to get recreated resulting in all components to rerender due to the theme context change.
This commit is contained in:
40
src/features/metadata/services/MetadataValueCache.ts
Normal file
40
src/features/metadata/services/MetadataValueCache.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) Contributors to the Suwayomi project
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { MetadataHolderType } from '@/features/metadata/Metadata.types.ts';
|
||||
|
||||
export class MetadataValueCache {
|
||||
private static convertedValueByKey = new Map<string, unknown>();
|
||||
|
||||
private static rawValueByKey = new Map<string, string | undefined>();
|
||||
|
||||
private static getCacheKey(type: MetadataHolderType, holderId: string | number | undefined, key: string): string {
|
||||
return `${type}::${holderId ?? ''}::${key}`;
|
||||
}
|
||||
|
||||
static getStableValue<T>(
|
||||
type: MetadataHolderType,
|
||||
holderId: string | number | undefined,
|
||||
key: string,
|
||||
rawValue: string | undefined,
|
||||
newValue: T,
|
||||
): T {
|
||||
const cacheKey = this.getCacheKey(type, holderId, key);
|
||||
const cachedRawValue = this.rawValueByKey.get(cacheKey);
|
||||
const cachedConvertedValue = this.convertedValueByKey.get(cacheKey);
|
||||
|
||||
if (cachedRawValue !== undefined && rawValue === cachedRawValue) {
|
||||
return cachedConvertedValue as T;
|
||||
}
|
||||
|
||||
this.rawValueByKey.set(cacheKey, rawValue);
|
||||
this.convertedValueByKey.set(cacheKey, newValue);
|
||||
|
||||
return newValue;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user