Skip to content

Commit

Permalink
fix(vue3): avoid strict mode in store creation to fix slow down app
Browse files Browse the repository at this point in the history
  • Loading branch information
joseacabaneros committed Jul 19, 2024
1 parent 3c5161f commit 6e36384
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 130 deletions.
54 changes: 46 additions & 8 deletions packages/x-components/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,51 @@
import { platformAdapter } from '@empathyco/x-adapter-platform';
import App from './App.vue';
import { setupDevtools } from './plugins/devtools/devtools.plugin';
import router from './router';
import { baseInstallXOptions, baseSnippetConfig } from './views/base-config';
import Vue3 from './vue3.vue';
import { XInstaller } from './x-installer/x-installer/x-installer';
import { FilterEntityFactory } from './x-modules/facets/entities/filter-entity.factory';
import { SingleSelectModifier } from './x-modules/facets/entities/single-select.modifier';
import { StickyModifier } from './x-modules/facets/entities/sticky.modifier';
import './tailwind/index.css';

window.initX = baseSnippetConfig;
// Vue.config.productionTip = false;
FilterEntityFactory.instance.registerModifierByFacetId('age_facet', SingleSelectModifier);
FilterEntityFactory.instance.registerModifierByFacetId(
'brand_facet',
StickyModifier,
SingleSelectModifier
);
FilterEntityFactory.instance.registerModifierByFacetId('price', SingleSelectModifier);
FilterEntityFactory.instance.registerModifierByFilterModelName(
'HierarchicalFilter',
SingleSelectModifier
);

new XInstaller({
const installer = new XInstaller({
...baseInstallXOptions,
adapter: platformAdapter,
app: Vue3,
domElement: '#app'
}).init();
app: App,
vueOptions: {
router
},
domElement: '#app',
onCreateApp: initDevtools
});

if (window.initX) {
installer.init();
} else {
installer.init(baseSnippetConfig).then(({ app }) => {
app.use(router);
});
}

/**
* If an app is provided, initialise the devtools.
*
* @param app - The root Vue instance of the application.
*/
function initDevtools(app: any): void {
if (process.env.NODE_ENV !== 'production') {
setupDevtools(app);
}
}
70 changes: 9 additions & 61 deletions packages/x-components/src/plugins/x-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,11 @@ import { createStore, Module, Store } from 'vuex';
import { XComponentsAdapter } from '@empathyco/x-types';
import { EventPayload, SubjectPayload, XBus } from '@empathyco/x-bus';
import { Observable } from 'rxjs';
import { cleanGettersProxyCache } from '../store/utils/getters-proxy.utils';
import { RootXStoreModule } from '../store/x.module';
import { AnyXStoreModule, RootXStoreState } from '../store/store.types';
import { XEvent, XEventsTypes } from '../wiring/events.types';
import { AnyWire, WireMetadata } from '../wiring/wiring.types';
import { deviceXStoreModule } from '../x-modules/device/store/module';
import { empathizeXStoreModule } from '../x-modules/empathize/store/module';
import { experienceControlsXStoreModule } from '../x-modules/experience-controls/store/module';
import { extraParamsXStoreModule } from '../x-modules/extra-params/store/module';
import { facetsXStoreModule } from '../x-modules/facets/store/module';
import { historyQueriesXStoreModule } from '../x-modules/history-queries/store/module';
import { identifierResultsXStoreModule } from '../x-modules/identifier-results/store/module';
import { nextQueriesXStoreModule } from '../x-modules/next-queries/store/module';
import { popularSearchesXStoreModule } from '../x-modules/popular-searches/store/module';
import { queriesPreviewXStoreModule } from '../x-modules/queries-preview/store/module';
import { querySuggestionsXStoreModule } from '../x-modules/query-suggestions/store/module';
import { recommendationsXStoreModule } from '../x-modules/recommendations/store/module';
import { relatedTagsXStoreModule } from '../x-modules/related-tags/store/module';
import { scrollXStoreModule } from '../x-modules/scroll/store/module';
import { searchBoxXStoreModule } from '../x-modules/search-box/store/module';
import { searchXStoreModule } from '../x-modules/search/store/module';
import { semanticQueriesXStoreModule } from '../x-modules/semantic-queries/store/module';
import { taggingXStoreModule } from '../x-modules/tagging/store/module';
import { urlXStoreModule } from '../x-modules/url/store/module';
import { AnyXModule, XModuleName } from '../x-modules/x-modules.types';
import { sendWiringToDevtools } from './devtools/wiring.devtools';
import { bus } from './x-bus';
Expand Down Expand Up @@ -198,6 +181,7 @@ export class XPlugin implements PluginObject<XPluginOptions> {
* @internal
*/
static resetInstance(): void {
cleanGettersProxyCache();
this.instance = undefined;
}

Expand Down Expand Up @@ -247,8 +231,8 @@ export class XPlugin implements PluginObject<XPluginOptions> {
*/
protected registerXModule(xModule: AnyXModule): void {
if (!this.installedXModules.has(xModule.name)) {
// const customizedXModule = this.customizeXModule(xModule);
// this.registerStoreModule(customizedXModule);
const customizedXModule = this.customizeXModule(xModule);
this.registerStoreModule(customizedXModule);
this.registerStoreEmitters(xModule);
this.registerWiring(xModule);
// The wiring must be registered after the store emitters
Expand Down Expand Up @@ -376,51 +360,15 @@ export class XPlugin implements PluginObject<XPluginOptions> {
this.store =
this.options.store ??
createStore({
strict: process.env.NODE_ENV !== 'production',
modules: {
x: {
namespaced: true,
state: () => ({ test: {} }),
mutations: {
increment(state: any) {
const t0 = performance.now();
Array.from(Array(210).keys()).forEach(key => {
console.log(key);
state.test[key] = { a: key };
});
const t1 = performance.now();
console.log(`Loop of 210 with assignation took ${(t1 - t0) / 1000} seconds.`);
}
},
modules: {
device: { namespaced: true, ...deviceXStoreModule },
empathize: { namespaced: true, ...empathizeXStoreModule },
extraParams: { namespaced: true, ...extraParamsXStoreModule },
facets: { namespaced: true, ...facetsXStoreModule },
historyQueries: { namespaced: true, ...historyQueriesXStoreModule },
identifierResults: { namespaced: true, ...identifierResultsXStoreModule },
nextQueries: { namespaced: true, ...nextQueriesXStoreModule },
popularSearches: { namespaced: true, ...popularSearchesXStoreModule },
queriesPreview: { namespaced: true, ...queriesPreviewXStoreModule },
querySuggestions: { namespaced: true, ...querySuggestionsXStoreModule },
recommendations: { namespaced: true, ...recommendationsXStoreModule },
relatedTags: { namespaced: true, ...relatedTagsXStoreModule },
scroll: { namespaced: true, ...scrollXStoreModule },
search: { namespaced: true, ...searchXStoreModule },
searchBox: { namespaced: true, ...searchBoxXStoreModule },
semanticQueries: { namespaced: true, ...semanticQueriesXStoreModule },
tagging: { namespaced: true, ...taggingXStoreModule },
url: { namespaced: true, ...urlXStoreModule },
experienceControls: { namespaced: true, ...experienceControlsXStoreModule }
}
}
} as any
/* strict mode causes slow down app significantly with vuex4 and
registering modules dynamically */
// strict: process.env.NODE_ENV !== 'production'
});
// if (!this.options.store) {
// this.vue.prototype.$store = this.store;
// }
this.vue.use(this.store);
// this.store.registerModule('x', RootXStoreModule);
this.store.registerModule('x', RootXStoreModule);
}

/**
Expand Down
38 changes: 3 additions & 35 deletions packages/x-components/src/store/x.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,7 @@ export type XModuleState = { [Key in keyof RootXStoreState['x']]: null };
*
* @internal
*/
export const RootXStoreModule: Module<XModuleState, any> = {
state: () => ({
device: null,
empathize: null,
extraParams: null,
facets: null,
historyQueries: null,
identifierResults: null,
nextQueries: null,
popularSearches: null,
queriesPreview: null,
querySuggestions: null,
recommendations: null,
relatedTags: null,
scroll: null,
search: null,
searchBox: null,
semanticQueries: null,
tagging: null,
url: null,
experienceControls: null,
test: {}
}),
mutations: {
increment(state) {
const t0 = performance.now();
Array.from(Array(210).keys()).forEach(key => {
console.log(key);
(state as any).test[key] = { a: key };
});
const t1 = performance.now();
console.log(`Loop of 210 with assignation took ${(t1 - t0) / 1000} seconds.`);
}
},
namespaced: true
export const RootXStoreModule: Module<any, any> = {
namespaced: true,
state: () => ({})
};
25 changes: 9 additions & 16 deletions packages/x-components/src/x-modules/facets/store/module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Facet } from '@empathyco/x-types';
import { Facet, Filter } from '@empathyco/x-types';
import { Dictionary } from '@empathyco/x-utils';
import { mergeConfig, setConfig } from '../../../store/utils/config-store.utils';
import { setQuery } from '../../../store/utils/query.utils';
import { facets } from './getters/facets.getter';
Expand Down Expand Up @@ -36,19 +37,15 @@ export const facetsXStoreModule: FacetsXStoreModule = {
state.filters[newFilter.id] = newFilter;
},
setFilters(state, filters) {
console.log('filters.length', filters.length);
const t0 = performance.now();
const a = filters.reduce((acc, current) => {
acc[current.id] = current;
return acc;
}, {} as Record<string, any>);
// filters.forEach(filter => (state.filters[filter.id] = filter));
// Much faster than assign every filter to the state
state.filters = {
...state.filters,
...a
...filters.reduce(
(acc, filter) => ((acc[filter.id] = filter), acc),
{} as Dictionary<Filter>
)
};
// filters.forEach(filter => (state.filters[filter.id] = filter));
const t1 = performance.now();
console.log(`Loop of FILTERS with assignation took ${(t1 - t0) / 1000} seconds.`);
},
setPreselectedFilters(state, filters) {
state.preselectedFilters = filters;
Expand All @@ -57,11 +54,7 @@ export const facetsXStoreModule: FacetsXStoreModule = {
delete state.filters[id];
},
removeFilters(state, filters) {
const copy = { ...state.filters };
filters.forEach(({ id }) => delete copy[id]);

state.filters = copy;
// filters.forEach(({ id }) => delete state.filters[id]);
filters.forEach(({ id }) => delete state.filters[id]);
},
setFacetGroup(state, { facetId, groupId }: FacetGroupEntry) {
state.groups[facetId] = groupId;
Expand Down
10 changes: 1 addition & 9 deletions packages/x-components/src/x-modules/search/store/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ export const searchXStoreModule: SearchXStoreModule = {
},
status: 'initial',
isNoResults: false,
fromNoResultsWithFilters: false,
test: {}
fromNoResultsWithFilters: false
}),
getters: {
request,
Expand All @@ -54,13 +53,6 @@ export const searchXStoreModule: SearchXStoreModule = {
setQuery,
setResults(state, results) {
state.results = results;
const t0 = performance.now();
Array.from(Array(210).keys()).forEach(key => {
console.log(key);
state.test[key] = { a: key };
});
const t1 = performance.now();
console.log(`Loop of 210 with assignation took ${(t1 - t0) / 1000} seconds.`);
},
setPartialResults(state, partialResults) {
state.partialResults = partialResults;
Expand Down
3 changes: 2 additions & 1 deletion packages/x-components/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { resolve } from 'path';
import vue from '@vitejs/plugin-vue';
import { defineConfig } from 'vite';
import Inspector from 'vite-plugin-vue-inspector';

export const vueDocsPlugin = {
name: 'vue-docs',
Expand All @@ -10,7 +11,7 @@ export const vueDocsPlugin = {
};

export default defineConfig({
plugins: [vue(), vueDocsPlugin],
plugins: [vue(), vueDocsPlugin, Inspector()],
resolve: {
alias: {
vue: resolve(__dirname, 'node_modules/vue')
Expand Down

0 comments on commit 6e36384

Please sign in to comment.