Skip to content

Commit

Permalink
perf: memoize common hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed Dec 11, 2020
1 parent d91a09c commit 6a8af1d
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 110 deletions.
169 changes: 89 additions & 80 deletions core/store/src/state/context/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import { useStore } from './store';
import { useStory, useCurrentStory } from './story';
import { useCurrentDocument } from './document';
import { useMemo } from 'react';

export interface ComponentInputProps {
/**
Expand All @@ -33,78 +34,80 @@ export const useComponents = ({
const store = useStore();
const story = useStory({ id: name });
const currentDoc = useCurrentDocument();
const { component: storyComponentName } = story || {};
const storyComponent = getComponentName(storyComponentName);
const doc = story && story.doc ? store.docs[story.doc] : currentDoc;
const component =
storyComponent && doc && doc.componentsLookup
? store.components[doc.componentsLookup[storyComponent]]
: undefined;
return useMemo(() => {
const { component: storyComponentName } = story || {};
const storyComponent = getComponentName(storyComponentName);
const doc = story && story.doc ? store.docs[story.doc] : currentDoc;
const component =
storyComponent && doc && doc.componentsLookup
? store.components[doc.componentsLookup[storyComponent]]
: undefined;

let components: Components | undefined = undefined;
const getComponents = (
components: { [key: string]: any } | undefined,
): Components => {
const getComponent = (name: string) =>
doc?.componentsLookup?.[name] &&
store?.components[doc.componentsLookup[name]];
return store && doc && components
? Object.keys(components).reduce((acc, key) => {
const comp = components[key];
if (comp === CURRENT_STORY) {
const comps: Record<string, Component> = {};
const name = getComponentName(doc.component);
let components: Components | undefined = undefined;
const getComponents = (
components: { [key: string]: any } | undefined,
): Components => {
const getComponent = (name: string) =>
doc?.componentsLookup?.[name] &&
store?.components[doc.componentsLookup[name]];
return store && doc && components
? Object.keys(components).reduce((acc, key) => {
const comp = components[key];
if (comp === CURRENT_STORY) {
const comps: Record<string, Component> = {};
const name = getComponentName(doc.component);
if (name) {
const component = getComponent(name);
if (component) {
comps[name] = component;
}
}
if (doc.subcomponents) {
Object.keys(doc.subcomponents).forEach(subKey => {
const name = getComponentName(doc.subcomponents?.[subKey]);
if (name) {
const component = getComponent(name);
if (component) {
comps[name] = component;
}
}
});
}
return { ...acc, ...comps };
}
const keys = doc.componentsLookup
? Object.keys(doc.componentsLookup)
: [];
const name = keys.length === 1 ? keys[0] : getComponentName(comp);
if (name) {
const component = getComponent(name);
if (component) {
comps[name] = component;
return { ...acc, [key]: component };
}
}
if (doc.subcomponents) {
Object.keys(doc.subcomponents).forEach(subKey => {
const name = getComponentName(doc.subcomponents?.[subKey]);
if (name) {
const component = getComponent(name);
if (component) {
comps[name] = component;
}
}
});
}
return { ...acc, ...comps };
}
const keys = doc.componentsLookup
? Object.keys(doc.componentsLookup)
: [];
const name = keys.length === 1 ? keys[0] : getComponentName(comp);
if (name) {
const component = getComponent(name);
if (component) {
return { ...acc, [key]: component };
}
}
return acc;
}, {})
: {};
};
if (of === CURRENT_STORY && story) {
if (component) {
const name = getComponentName(component);
if (name) {
components = {
[name]: component,
...getComponents(story.subcomponents),
};
return acc;
}, {})
: {};
};
if (of === CURRENT_STORY && story) {
if (component) {
const name = getComponentName(component);
if (name) {
components = {
[name]: component,
...getComponents(story.subcomponents),
};
} else {
components = getComponents(story.subcomponents);
}
} else {
components = getComponents(story.subcomponents);
}
} else {
components = getComponents(story.subcomponents);
components = getComponents({ of });
}
} else {
components = getComponents({ of });
}
return components;
return components;
}, [currentDoc, of, store, story]);
};

/**
Expand All @@ -118,17 +121,19 @@ export const useComponent = ({
const story = useStory({ id: name });
const currentDoc = useCurrentDocument();
const store = useStore();
const doc = story && story.doc ? store.docs[story.doc] : currentDoc;
let component;
if (of === CURRENT_STORY) {
component = story ? story.component : doc?.component;
} else {
component = of;
}
const componentName = getComponentName(component);
return componentName && doc && doc.componentsLookup
? store.components[doc.componentsLookup[componentName]]
: undefined;
return useMemo(() => {
const doc = story && story.doc ? store.docs[story.doc] : currentDoc;
let component;
if (of === CURRENT_STORY) {
component = story ? story.component : doc?.component;
} else {
component = of;
}
const componentName = getComponentName(component);
return componentName && doc && doc.componentsLookup
? store.components[doc.componentsLookup[componentName]]
: undefined;
}, [currentDoc, of, store, story]);
};

/**
Expand All @@ -141,12 +146,16 @@ export const useCurrentPropsCount = (): number => {
const story = useCurrentStory();
const components = useComponents({ name: story?.id });
const doc = useCurrentDocument();
return components && doc
? Object.keys(components).reduce((acc, key) => {
const component = doc.componentsLookup
? store.components[doc.componentsLookup[key]]
: undefined;
return acc + Object.keys(component?.info?.props || {}).length;
}, 0)
: 0;
return useMemo(
() =>
components && doc
? Object.keys(components).reduce((acc, key) => {
const component = doc.componentsLookup
? store.components[doc.componentsLookup[key]]
: undefined;
return acc + Object.keys(component?.info?.props || {}).length;
}, 0)
: 0,
[components, doc, store],
);
};
28 changes: 15 additions & 13 deletions core/store/src/state/context/document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,26 +129,28 @@ export const useDocSort = (
return [sort[type] || 'date', newSort => setSort(type, newSort)];
};

const getDocsByType = (docs: Documents, type: DocType) =>
Object.keys(docs).reduce((acc: Pages, key: string) => {
const doc: Document | undefined = docs[key];
if (doc) {
const { type: docType = defDocType } = doc;
if (docType === type) {
return [...acc, { ...doc }];
}
}
return acc;
}, []);
/**
* Returns an array of all documents of a specific doc type
*/
export const useDocByType = (type: DocType): Pages => {
return useGetDocByType()(type);
const docs = useDocs();
return useMemo(() => getDocsByType(docs, type), [docs, type]);
};

export const useGetDocByType = (): ((type: DocType) => Pages) => {
const docs = useDocs();
return (type: DocType) =>
Object.keys(docs).reduce((acc: Pages, key: string) => {
const doc: Document | undefined = docs[key];
if (doc) {
const { type: docType = defDocType } = doc;
if (docType === type) {
return [...acc, { ...doc }];
}
}
return acc;
}, []);
return (type: DocType) => getDocsByType(docs, type);
};

/**
Expand All @@ -157,7 +159,7 @@ export const useGetDocByType = (): ((type: DocType) => Pages) => {
export const useSortedDocByType = (type: DocType): Pages => {
const docs = useDocByType(type);
const [sort] = useDocSort(type);
return [...docs].sort(docSortFn(sort));
return useMemo(() => [...docs].sort(docSortFn(sort)), [docs, sort]);
};

export type DocCountType = Record<DocType, { count: number; home?: Document }>;
Expand Down
41 changes: 24 additions & 17 deletions core/store/src/state/context/story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, {
FC,
createContext,
useContext,
useMemo,
useState,
useEffect,
} from 'react';
Expand Down Expand Up @@ -103,16 +104,18 @@ export const useStoryById = (storyId: string): Story | undefined => {
*/
export const useStoryIdFromName = (name?: string): string | undefined => {
const store = useStore();
if (name) {
for (const docId in store.docs) {
const doc = store.docs[docId];
const storyId = docStoryToId(docId, name);
if (doc.stories && doc.stories.indexOf(storyId) > -1) {
return storyId;
return useMemo(() => {
if (name) {
for (const docId in store.docs) {
const doc = store.docs[docId];
const storyId = docStoryToId(docId, name);
if (doc.stories && doc.stories.indexOf(storyId) > -1) {
return storyId;
}
}
}
}
return undefined;
return undefined;
}, [name, store.docs]);
};

export interface StoryInputProps {
Expand Down Expand Up @@ -166,16 +169,20 @@ export const useStoryComponent = (
): Component | undefined => {
const storyId = useStoryId(props);
const store = useStore();
const story: Story | undefined = storyId ? store.stories[storyId] : undefined;
const storyComponent: any = story?.component;

const componentName = getComponentName(storyComponent);
const doc = story && story.doc ? store.docs[story.doc] : undefined;
const component =
componentName && doc?.componentsLookup?.[componentName]
? store.components[doc.componentsLookup[componentName]]
return useMemo(() => {
const story: Story | undefined = storyId
? store.stories[storyId]
: undefined;
return component;
const storyComponent: any = story?.component;

const componentName = getComponentName(storyComponent);
const doc = story && story.doc ? store.docs[story.doc] : undefined;
const component =
componentName && doc?.componentsLookup?.[componentName]
? store.components[doc.componentsLookup[componentName]]
: undefined;
return component;
}, [store, storyId]);
};

/**
Expand Down

0 comments on commit 6a8af1d

Please sign in to comment.