Refacto views (#10272)
In this huge (sorry!) PR: - introducing objectMetadataItem in contextStore instead of objectMetadataId which is more convenient - splitting some big hooks into smaller parts to avoid re-renders - removing Effects to avoid re-renders (especially onViewChange) - making the view prefetch separate from favorites to avoid re-renders - making the view prefetch load a state and add selectors on top of it to avoir re-renders As a result, the performance is WAY better (I suspect the favorite implementation to trigger a lot of re-renders unfortunately). However, we are still facing a random app freeze on view creation. I could not investigate the root cause. As this seems to be already there in the precedent release, we can move forward but this seems a urgent follow up to me ==> EDIT: I've found the root cause after a few ours of deep dive... an infinite loop in RecordTableNoRecordGroupBodyEffect... prastoin edit: close https://github.com/twentyhq/twenty/issues/10253 --------- Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com> Co-authored-by: prastoin <paul@twenty.com>
This commit is contained in:
@ -0,0 +1,110 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useRecoilCallback, useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
|
||||
import { currentUserState } from '@/auth/states/currentUserState';
|
||||
import { Favorite } from '@/favorites/types/Favorite';
|
||||
import { FavoriteFolder } from '@/favorites/types/FavoriteFolder';
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
||||
import { findAllFavoritesFolderOperationSignatureFactory } from '@/prefetch/graphql/operation-signatures/factories/findAllFavoritesFolderOperationSignatureFactory';
|
||||
import { findAllFavoritesOperationSignatureFactory } from '@/prefetch/graphql/operation-signatures/factories/findAllFavoritesOperationSignatureFactory';
|
||||
import { prefetchFavoriteFoldersState } from '@/prefetch/states/prefetchFavoriteFoldersState';
|
||||
import { prefetchFavoritesState } from '@/prefetch/states/prefetchFavoritesState';
|
||||
import { prefetchIsLoadedFamilyState } from '@/prefetch/states/prefetchIsLoadedFamilyState';
|
||||
import { PrefetchKey } from '@/prefetch/types/PrefetchKey';
|
||||
import { useIsWorkspaceActivationStatusSuspended } from '@/workspace/hooks/useIsWorkspaceActivationStatusSuspended';
|
||||
import { isDefined } from 'twenty-shared';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
|
||||
export const PrefetchRunFavoriteQueriesEffect = () => {
|
||||
const currentUser = useRecoilValue(currentUserState);
|
||||
|
||||
const isWorkspaceSuspended = useIsWorkspaceActivationStatusSuspended();
|
||||
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
|
||||
const setIsPrefetchFavoritesLoaded = useSetRecoilState(
|
||||
prefetchIsLoadedFamilyState(PrefetchKey.AllFavorites),
|
||||
);
|
||||
|
||||
const setIsPrefetchFavoritesFoldersLoaded = useSetRecoilState(
|
||||
prefetchIsLoadedFamilyState(PrefetchKey.AllFavoritesFolders),
|
||||
);
|
||||
|
||||
const findAllFavoritesOperationSignature =
|
||||
findAllFavoritesOperationSignatureFactory({
|
||||
objectMetadataItem: objectMetadataItems.find(
|
||||
(item) => item.nameSingular === CoreObjectNameSingular.Favorite,
|
||||
),
|
||||
});
|
||||
|
||||
const findAllFavoriteFoldersOperationSignature =
|
||||
findAllFavoritesFolderOperationSignatureFactory({
|
||||
objectMetadataItem: objectMetadataItems.find(
|
||||
(item) => item.nameSingular === CoreObjectNameSingular.FavoriteFolder,
|
||||
),
|
||||
});
|
||||
|
||||
const { records: favorites } = useFindManyRecords({
|
||||
objectNameSingular: CoreObjectNameSingular.Favorite,
|
||||
filter: findAllFavoritesOperationSignature.variables.filter,
|
||||
recordGqlFields: findAllFavoritesOperationSignature.fields,
|
||||
skip: !currentUser || isWorkspaceSuspended,
|
||||
});
|
||||
|
||||
const { records: favoriteFolders } = useFindManyRecords({
|
||||
objectNameSingular: CoreObjectNameSingular.FavoriteFolder,
|
||||
filter: findAllFavoriteFoldersOperationSignature.variables.filter,
|
||||
recordGqlFields: findAllFavoriteFoldersOperationSignature.fields,
|
||||
skip: !currentUser || isWorkspaceSuspended,
|
||||
});
|
||||
|
||||
const setPrefetchFavoritesState = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
(favorites: Favorite[]) => {
|
||||
const existingFavorites = snapshot
|
||||
.getLoadable(prefetchFavoritesState)
|
||||
.getValue();
|
||||
|
||||
if (!isDeeplyEqual(existingFavorites, favorites)) {
|
||||
set(prefetchFavoritesState, favorites);
|
||||
}
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const setPrefetchFavoriteFoldersState = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
(favoriteFolders: FavoriteFolder[]) => {
|
||||
const existingFavoriteFolders = snapshot
|
||||
.getLoadable(prefetchFavoriteFoldersState)
|
||||
.getValue();
|
||||
|
||||
if (!isDeeplyEqual(existingFavoriteFolders, favoriteFolders)) {
|
||||
set(prefetchFavoriteFoldersState, favoriteFolders);
|
||||
}
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (isDefined(favorites)) {
|
||||
setPrefetchFavoritesState(favorites as Favorite[]);
|
||||
setIsPrefetchFavoritesLoaded(true);
|
||||
}
|
||||
}, [favorites, setPrefetchFavoritesState, setIsPrefetchFavoritesLoaded]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isDefined(favoriteFolders)) {
|
||||
setPrefetchFavoriteFoldersState(favoriteFolders as FavoriteFolder[]);
|
||||
setIsPrefetchFavoritesFoldersLoaded(true);
|
||||
}
|
||||
}, [
|
||||
favoriteFolders,
|
||||
setPrefetchFavoriteFoldersState,
|
||||
setIsPrefetchFavoritesFoldersLoaded,
|
||||
]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
Reference in New Issue
Block a user