Item page perf: memoize species faces
This is a pretty easy change, that makes re-renders faster when something about the item preview state changes! That said, the initial render is still pretty slow, too, and that's the one that's bothering me more lol
This commit is contained in:
parent
07bf555a02
commit
ab2dbeb02a
2 changed files with 242 additions and 222 deletions
|
@ -528,9 +528,9 @@ function ItemPageOutfitPreview({ itemId }) {
|
|||
null
|
||||
);
|
||||
|
||||
const setPetStateFromUserAction = (newPetState) => {
|
||||
setPetState(newPetState);
|
||||
|
||||
const setPetStateFromUserAction = React.useCallback(
|
||||
(newPetState) =>
|
||||
setPetState((prevPetState) => {
|
||||
// When the user _intentionally_ chooses a species or color, save it in
|
||||
// local storage for next time. (This won't update when e.g. their
|
||||
// preferred species or color isn't available for this item, so we update
|
||||
|
@ -539,10 +539,16 @@ function ItemPageOutfitPreview({ itemId }) {
|
|||
// Re the "ifs", I have no reason to expect null to come in here, but,
|
||||
// since this is touching client-persisted data, I want it to be even more
|
||||
// reliable than usual!
|
||||
if (newPetState.speciesId && newPetState.speciesId !== petState.speciesId) {
|
||||
if (
|
||||
newPetState.speciesId &&
|
||||
newPetState.speciesId !== prevPetState.speciesId
|
||||
) {
|
||||
setPreferredSpeciesId(newPetState.speciesId);
|
||||
}
|
||||
if (newPetState.colorId && newPetState.colorId !== petState.colorId) {
|
||||
if (
|
||||
newPetState.colorId &&
|
||||
newPetState.colorId !== prevPetState.colorId
|
||||
) {
|
||||
if (colorIsBasic(newPetState.colorId)) {
|
||||
// When the user chooses a basic color, don't index on it specifically,
|
||||
// and instead reset to use default colors.
|
||||
|
@ -551,7 +557,11 @@ function ItemPageOutfitPreview({ itemId }) {
|
|||
setPreferredColorId(newPetState.colorId);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return newPetState;
|
||||
}),
|
||||
[setPreferredColorId, setPreferredSpeciesId]
|
||||
);
|
||||
|
||||
// We don't need to reload this query when preferred species/color change, so
|
||||
// cache their initial values here to use as query arguments.
|
||||
|
@ -694,6 +704,21 @@ function ItemPageOutfitPreview({ itemId }) {
|
|||
const isCompatible = itemLayers.length > 0;
|
||||
const usesHTML5 = itemLayers.every(layerUsesHTML5);
|
||||
|
||||
const onChange = React.useCallback(
|
||||
({ speciesId, colorId }) => {
|
||||
const validPoses = getValidPoses(valids, speciesId, colorId);
|
||||
const pose = getClosestPose(validPoses, idealPose);
|
||||
setPetStateFromUserAction({
|
||||
speciesId,
|
||||
colorId,
|
||||
pose,
|
||||
isValid: true,
|
||||
appearanceId: null,
|
||||
});
|
||||
},
|
||||
[valids, idealPose, setPetStateFromUserAction]
|
||||
);
|
||||
|
||||
const borderColor = useColorModeValue("green.700", "green.400");
|
||||
const errorColor = useColorModeValue("red.600", "red.400");
|
||||
|
||||
|
@ -824,17 +849,7 @@ function ItemPageOutfitPreview({ itemId }) {
|
|||
selectedColorId={petState.colorId}
|
||||
compatibleBodies={compatibleBodies}
|
||||
couldProbablyModelMoreData={couldProbablyModelMoreData}
|
||||
onChange={({ speciesId, colorId }) => {
|
||||
const validPoses = getValidPoses(valids, speciesId, colorId);
|
||||
const pose = getClosestPose(validPoses, idealPose);
|
||||
setPetStateFromUserAction({
|
||||
speciesId,
|
||||
colorId,
|
||||
pose,
|
||||
isValid: true,
|
||||
appearanceId: null,
|
||||
});
|
||||
}}
|
||||
onChange={onChange}
|
||||
isLoading={loadingGQL || loadingValids}
|
||||
/>
|
||||
</Box>
|
||||
|
@ -1087,7 +1102,8 @@ function SpeciesFacesPicker({
|
|||
);
|
||||
}
|
||||
|
||||
function SpeciesFaceOption({
|
||||
const SpeciesFaceOption = React.memo(
|
||||
({
|
||||
speciesId,
|
||||
speciesName,
|
||||
colorId,
|
||||
|
@ -1098,7 +1114,7 @@ function SpeciesFaceOption({
|
|||
couldProbablyModelMoreData,
|
||||
onChange,
|
||||
isLoading,
|
||||
}) {
|
||||
}) => {
|
||||
const selectedBorderColor = useColorModeValue("green.600", "green.400");
|
||||
const selectedBackgroundColor = useColorModeValue("green.200", "green.600");
|
||||
const focusBorderColor = "blue.400";
|
||||
|
@ -1275,7 +1291,8 @@ function SpeciesFaceOption({
|
|||
)}
|
||||
</ClassNames>
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function ItemZonesInfo({ compatibleBodiesAndTheirZones, restrictedZones }) {
|
||||
// Reorganize the body-and-zones data, into zone-and-bodies data. Also, we're
|
||||
|
|
|
@ -309,7 +309,8 @@ export function useLocalStorage(key, initialValue) {
|
|||
|
||||
const [storedValue, setStoredValue] = React.useState(loadValue);
|
||||
|
||||
const setValue = (value) => {
|
||||
const setValue = React.useCallback(
|
||||
(value) => {
|
||||
try {
|
||||
setStoredValue(value);
|
||||
window.localStorage.setItem(key, JSON.stringify(value));
|
||||
|
@ -317,7 +318,9 @@ export function useLocalStorage(key, initialValue) {
|
|||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
},
|
||||
[key]
|
||||
);
|
||||
|
||||
const reloadValue = React.useCallback(() => {
|
||||
setStoredValue(loadValue());
|
||||
|
|
Loading…
Reference in a new issue