From f4876d792b9abc5f4837563882ba0ddde4cdc7f0 Mon Sep 17 00:00:00 2001 From: Michael Olorunnisola Date: Wed, 26 Feb 2025 03:49:46 -0500 Subject: [PATCH] improve sourcerer re-rendering performance --- .../public/app/home/index.tsx | 5 +- .../detections/components/user_info/index.tsx | 51 +++++++++++++------ .../public/sourcerer/containers/index.tsx | 5 +- .../containers/use_init_sourcerer.tsx | 17 +++++-- 4 files changed, 51 insertions(+), 27 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/app/home/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/app/home/index.tsx index dfaa8ea7fda6e..fe9cad4701ae9 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/app/home/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/app/home/index.tsx @@ -13,7 +13,6 @@ import { SecuritySolutionAppWrapper } from '../../common/components/page'; import { HelpMenu } from '../../common/components/help_menu'; import { getScopeFromPath } from '../../sourcerer/containers/sourcerer_paths'; -import { useSourcererDataView } from '../../sourcerer/containers'; import { GlobalHeader } from './global_header'; import { ConsoleManager } from '../../management/components/console/components/console_manager'; @@ -34,13 +33,11 @@ interface HomePageProps { const HomePageComponent: React.FC = ({ children }) => { const { pathname } = useLocation(); - useInitSourcerer(getScopeFromPath(pathname)); + const { browserFields } = useInitSourcerer(getScopeFromPath(pathname)); useUrlState(); useUpdateBrowserTitle(); useUpdateExecutionContext(); - const { browserFields } = useSourcererDataView(getScopeFromPath(pathname)); - // side effect: this will attempt to upgrade the endpoint package if it is not up to date // this will run when a user navigates to the Security Solution app and when they navigate between // tabs in the app. This is useful for keeping the endpoint package as up to date as possible until diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/user_info/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/user_info/index.tsx index 7696977bde3d1..c72eb60f75344 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/user_info/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/user_info/index.tsx @@ -7,7 +7,7 @@ import { noop } from 'lodash/fp'; import type { Dispatch } from 'react'; -import React, { useEffect, useReducer, createContext, useContext } from 'react'; +import React, { useEffect, useReducer, createContext, useContext, useMemo } from 'react'; import { useAlertsPrivileges } from '../../containers/detection_engine/alerts/use_alerts_privileges'; import { useSignalIndex } from '../../containers/detection_engine/alerts/use_signal_index'; @@ -353,19 +353,38 @@ export const useUserInfo = (): State => { signalIndexMappingOutdated, ]); - return { - loading, - isSignalIndexExists, - isAuthenticated, - hasEncryptionKey, - canUserCRUD, - canUserREAD, - hasIndexManage, - hasIndexMaintenance, - hasIndexWrite, - hasIndexRead, - hasIndexUpdateDelete, - signalIndexName, - signalIndexMappingOutdated, - }; + const userInfo = useMemo( + () => ({ + loading, + isSignalIndexExists, + isAuthenticated, + hasEncryptionKey, + canUserCRUD, + canUserREAD, + hasIndexManage, + hasIndexMaintenance, + hasIndexWrite, + hasIndexRead, + hasIndexUpdateDelete, + signalIndexName, + signalIndexMappingOutdated, + }), + [ + canUserCRUD, + canUserREAD, + hasEncryptionKey, + hasIndexMaintenance, + hasIndexManage, + hasIndexRead, + hasIndexUpdateDelete, + hasIndexWrite, + isAuthenticated, + isSignalIndexExists, + loading, + signalIndexMappingOutdated, + signalIndexName, + ] + ); + + return userInfo; }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/sourcerer/containers/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/sourcerer/containers/index.tsx index 2ad961fac3c42..ba4e0eced4dd3 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/sourcerer/containers/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/sourcerer/containers/index.tsx @@ -67,10 +67,11 @@ export const useSourcererDataView = ( if (selectedDataView == null || missingPatterns.length > 0) { // old way of fetching indices, legacy timeline setLegacyPatterns(selectedPatterns); - } else { + } else if (legacyPatterns.length > 0) { + // Only create a new array reference if legacyPatterns is not empty setLegacyPatterns([]); } - }, [missingPatterns, selectedDataView, selectedPatterns]); + }, [legacyPatterns.length, missingPatterns, selectedDataView, selectedPatterns]); const sourcererDataView = useMemo(() => { const _dv = diff --git a/x-pack/solutions/security/plugins/security_solution/public/sourcerer/containers/use_init_sourcerer.tsx b/x-pack/solutions/security/plugins/security_solution/public/sourcerer/containers/use_init_sourcerer.tsx index 4bf8de8c74862..86d55cebb831e 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/sourcerer/containers/use_init_sourcerer.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/sourcerer/containers/use_init_sourcerer.tsx @@ -57,7 +57,7 @@ export const useInitSourcerer = ( }, [addWarning, defaultDataView.error]); const getTimelineSelector = useMemo(() => timelineSelectors.getTimelineByIdSelector(), []); - const activeTimeline = useDeepEqualSelector((state) => + const { savedObjectId: timelineSavedObjectId } = useDeepEqualSelector((state) => getTimelineSelector(state, TimelineId.active) ); @@ -178,7 +178,7 @@ export const useInitSourcerer = ( !loadingSignalIndex && signalIndexName != null && signalIndexNameSourcerer == null && - (activeTimeline == null || activeTimeline.savedObjectId == null) && + timelineSavedObjectId == null && initialTimelineSourcerer.current && defaultDataView.id.length > 0 ) { @@ -209,7 +209,7 @@ export const useInitSourcerer = ( ); } else if ( signalIndexNameSourcerer != null && - (activeTimeline == null || activeTimeline.savedObjectId == null) && + timelineSavedObjectId == null && initialTimelineSourcerer.current && defaultDataView.id.length > 0 ) { @@ -240,14 +240,14 @@ export const useInitSourcerer = ( ); } }, [ - activeTimeline, + timelineSavedObjectId, defaultDataView, dispatch, loadingSignalIndex, signalIndexName, signalIndexNameSourcerer, ]); - const { dataViewId } = useSourcererDataView(scopeId); + const { dataViewId, browserFields } = useSourcererDataView(scopeId); const updateSourcererDataView = useCallback( (newSignalsIndex: string) => { @@ -370,4 +370,11 @@ export const useInitSourcerer = ( signalIndexName, signalIndexNameSourcerer, ]); + + return useMemo( + () => ({ + browserFields, + }), + [browserFields] + ); };