-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhance Event Fields Browser performance #129861
Enhance Event Fields Browser performance #129861
Conversation
be3d175
to
99556e9
Compare
99556e9
to
37119d5
Compare
...ck/plugins/security_solution/public/common/components/event_details/event_fields_browser.tsx
Outdated
Show resolved
Hide resolved
…t_details/event_fields_browser.tsx Use idiomatic value for EUI's `itemId` field Co-authored-by: Jan Monschke <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this improvement and the great PR description 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
💚 Build SucceededMetrics [docs]Async chunks
Page load bundle
History
To update your PR or re-run it, just comment with: |
💚 All backports created successfully
Note: Successful backport PRs will be merged automatically after passing CI. Questions ?Please refer to the Backport tool documentation |
* Enhance Event Fields Browser performance * fixes checks * Update x-pack/plugins/security_solution/public/common/components/event_details/event_fields_browser.tsx Use idiomatic value for EUI's `itemId` field Co-authored-by: Jan Monschke <[email protected]> Co-authored-by: Gloria Hornero <[email protected]> Co-authored-by: Jan Monschke <[email protected]> (cherry picked from commit 47b62d8)
* Enhance Event Fields Browser performance * fixes checks * Update x-pack/plugins/security_solution/public/common/components/event_details/event_fields_browser.tsx Use idiomatic value for EUI's `itemId` field Co-authored-by: Jan Monschke <[email protected]> Co-authored-by: Gloria Hornero <[email protected]> Co-authored-by: Jan Monschke <[email protected]> (cherry picked from commit 47b62d8)
Summary
This PR enhances the performance of the Event Details 'Table' tab, especially the filtering interaction. This affects users with a Data View that has many fields. Note: the Security app creates a Data View that has one field for each mapping in a list of indices.
Before
before_event_fields_browser_enhancements_trimmed.mov
Chrome dev tools performance profile from before the fix
After
after_event_fields_browser_enhancements.mov
Chrome dev tools performance profile from after the fix
Reproducing the issue
@timestamp
present in any form, then index a single document that has an@timestamp
value.Context: What is the code doing?
The
EventFieldsBrowser
component shows a row for each field. For each row, the component decides which actions a user can take. These actions are represented by small icons. For example, one action allows users to filter by the field with the given value. Another action lets users see the 'Top N' similar events. This action is only available on fields that are 'aggregatable'. Therefore, the component only shows this action for applicable fields.Areas to Enhance
In order to determine whether a given row should have the 'Top N' action, the component does a calculation for each row, up front. This algorithm has a runtime complexity of
O(n*m)
where n is the number of fields in the data view and m is the number of rows/fields shown in the table. This could be enhanced by doing the calculation lazily, only when the user accesses the overflow menu that shows theTop N
action. However that fix will be non-trivial, so we'll postpone it for now.The calculation to determine if each row is 'aggregatable' is also done on every render. This is because it is done using
useMemo
, but one value in the dependencies array changes on each render. This value is calledgetAddToTimelineButton
. It is a function which is bound, via.bind
, to the timeline store on each render. This results in a different function reference being passed to the dependencies array on each render, thereby forcing the calculation to happen on each render. This PR addresses the issue by lazily binding this function to the store, and then saving that reference. When the store is changed, the cached reference is removed.Once the first enhancement was made, a second issue was discovered. The table rows component instances were not being reconciled correctly by React. The
EuiInMemoryTableComponent
will set a Reactkey
property for rows, but only if theitemId
property is passed. If this property is not passed to the table, then each row will use its positional index as a key. This will prevent React from correctly reconciling components. This means that a component may be re-rendered with props that previously belong to a sibling component. This can cause memos to be invalidated unnecessarily. This was corrected by passing theitemId
property. We should consider requesting enhanced documentation about the importance of this property. Also, it may be useful to add a console warning when this property is missing (similar to how React shows a console warning whenkey
properties are missing in certain situations.)What's left
The component should be enhanced so that the calculation to determine which fields can show the 'Top N' action is more efficient. The 'Top N' action is, in practice, only visible from an overflow menu. This means that the calculation could theoretically take place lazily, only when the user accesses the overflow menu. Instead, the component decides whether each field is 'aggregatable' before rendering. It could also be possible to improve the algorithm that determines which fields are aggregatable. Currently this is done by a simple search across all fields in the DataView.
Also, I would like to spend some time explaining the methods I used to find these issues.
Checklist
getAddToTimelineButton
fn. This design is a stop gap fix.Risk Matrix
Delete this section if it is not applicable to this PR.
Before closing this PR, invite QA, stakeholders, and other developers to identify risks that should be tested prior to the change/feature release.
When forming the risk matrix, consider some of the following examples and how they may potentially impact the change:
For maintainers