Skip to content
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

[Synthetics UI] Fix infinite scroll in overview page #146570

Merged
merged 2 commits into from
Nov 30, 2022

Conversation

afgomez
Copy link
Contributor

@afgomez afgomez commented Nov 29, 2022

Summary

Closes #145378.

The overview page has a <EuiSpacer /> at the bottom of the grid to track the user's scroll position. This is done with an IntersectionObserver (wrapped in a hook) and a ref.

Sometimes the ref got destroyed, and with it the IntersectionObserver instance. This causes a race condition in the code that checks for the intersection to determine if the next page should be loaded or not.

Screenshot 2022-11-29 at 16 35 42

The reason why the ref got destroyed was this early return. With the code in main there is a brief moment in which the condition holds true, right after the monitors are loaded. In that brief instant the status is present but monitorsSortedByStatus is empty.

Screenshot 2022-11-29 at 16 44 35

When this happens the ref is destroyed, because the underlying element used to track the intersection is destroyed due of the early return.

This was caused because monitorsSortedByStatus was updated asynchronously with useEffect as part of the component lifecycle.

This PR uses useMemo instead of useEffect, to update the monitorsSortedByStatus at the same time that status is present. This prevents the early return from ever firing in the normal load cycle and keeps the ref. Since the ref never gets destroyed there's no race condition anymore.

Alejandro Fernández Gómez added 2 commits November 29, 2022 14:23
As per [1], phrasing content elements (i.e. a `<span>`) cannot contain
elements categorized as flow content (i.e. a `<div>`).

[1]: https://www.w3.org/TR/2011/WD-html5-20110525/content-models.html#phrasing-content-0
@afgomez afgomez added Team:Uptime - DEPRECATED Synthetics & RUM sub-team of Application Observability release_note:skip Skip the PR/issue when compiling release notes v8.6.0 labels Nov 29, 2022
@afgomez afgomez requested a review from a team as a code owner November 29, 2022 15:50
@elasticmachine
Copy link
Contributor

Pinging @elastic/uptime (Team:uptime)

@kibana-ci
Copy link
Collaborator

💚 Build Succeeded

Metrics [docs]

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
synthetics 1.1MB 1.1MB -150.0B
Unknown metric groups

ESLint disabled in files

id before after diff
osquery 1 2 +1

ESLint disabled line counts

id before after diff
enterpriseSearch 19 21 +2
fleet 59 65 +6
osquery 109 115 +6
securitySolution 442 448 +6
total +20

Total ESLint disabled count

id before after diff
enterpriseSearch 20 22 +2
fleet 68 74 +6
osquery 110 117 +7
securitySolution 519 525 +6
total +21

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

Copy link
Contributor

@dominiqueclarke dominiqueclarke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Tested with 100 monitors.

@afgomez afgomez merged commit 217a040 into elastic:main Nov 30, 2022
kibanamachine pushed a commit to kibanamachine/kibana that referenced this pull request Nov 30, 2022
## Summary

Closes elastic#145378.

The overview page has a [`<EuiSpacer />` at the bottom of the
grid](https://github.com/elastic/kibana/blob/e8d77b3f0f46ac62e9220ffe28eb455880854906/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx#L135-L137)
to track the user's scroll position. This is done [with an
`IntersectionObserver` (wrapped in a hook) and a
`ref`](https://github.com/elastic/kibana/blob/e8d77b3f0f46ac62e9220ffe28eb455880854906/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx#L70-L75).

Sometimes the `ref` got destroyed, and with it the
`IntersectionObserver` instance. This causes a race condition [in the
code that checks for the
intersection](https://github.com/elastic/kibana/blob/e8d77b3f0f46ac62e9220ffe28eb455880854906/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx#L78-L88)
to determine if the next page should be loaded or not.

<img width="1278" alt="Screenshot 2022-11-29 at 16 35 42"
src="https://user-images.githubusercontent.com/57448/204574461-5056391c-e96d-4b38-9c9e-4976e0d14a40.png">

The reason why the `ref` got destroyed was [this early
return](https://github.com/elastic/kibana/blob/e8d77b3f0f46ac62e9220ffe28eb455880854906/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx#L98-L100).
With the code in `main` there is a brief moment in which the condition
holds `true`, right after the monitors are loaded. In that brief instant
the `status` is present but `monitorsSortedByStatus` is empty.

<img width="1084" alt="Screenshot 2022-11-29 at 16 44 35"
src="https://user-images.githubusercontent.com/57448/204575679-de4bc6bf-122b-4c6d-ae75-9c96a7c5fb85.png">

When this happens the `ref` is destroyed, because the underlying element
used to track the intersection is destroyed due of the early return.

This was caused because `monitorsSortedByStatus` was updated
asynchronously [with
`useEffect`](https://github.com/elastic/kibana/blob/2f3313371bc6d992a99accef1289dd035779d3e6/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_monitors_sorted_by_status.tsx#L30-L72)
as part of the component lifecycle.

This PR uses `useMemo` instead of `useEffect`, to update the
`monitorsSortedByStatus` at the same time that `status` is present. This
prevents the early return from ever firing in the normal load cycle and
keeps the `ref`. Since the `ref` never gets destroyed there's no race
condition anymore.

(cherry picked from commit 217a040)
@kibanamachine
Copy link
Contributor

💚 All backports created successfully

Status Branch Result
8.6

Note: Successful backport PRs will be merged automatically after passing CI.

Questions ?

Please refer to the Backport tool documentation

kibanamachine added a commit that referenced this pull request Nov 30, 2022
…146657)

# Backport

This will backport the following commits from `main` to `8.6`:
- [[Synthetics UI] Fix infinite scroll in overview page
(#146570)](#146570)

<!--- Backport version: 8.9.7 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Alejandro Fernández
Gómez","email":"[email protected]"},"sourceCommit":{"committedDate":"2022-11-30T08:23:34Z","message":"[Synthetics
UI] Fix infinite scroll in overview page (#146570)\n\n##
Summary\r\n\r\nCloses #145378.\r\n\r\nThe overview page has a
[`<EuiSpacer />` at the bottom of
the\r\ngrid](https://github.com/elastic/kibana/blob/e8d77b3f0f46ac62e9220ffe28eb455880854906/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx#L135-L137)\r\nto
track the user's scroll position. This is done [with
an\r\n`IntersectionObserver` (wrapped in a hook) and
a\r\n`ref`](https://github.com/elastic/kibana/blob/e8d77b3f0f46ac62e9220ffe28eb455880854906/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx#L70-L75).\r\n\r\nSometimes
the `ref` got destroyed, and with it the\r\n`IntersectionObserver`
instance. This causes a race condition [in the\r\ncode that checks for
the\r\nintersection](https://github.com/elastic/kibana/blob/e8d77b3f0f46ac62e9220ffe28eb455880854906/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx#L78-L88)\r\nto
determine if the next page should be loaded or not.\r\n\r\n<img
width=\"1278\" alt=\"Screenshot 2022-11-29 at 16 35
42\"\r\nsrc=\"https://user-images.githubusercontent.com/57448/204574461-5056391c-e96d-4b38-9c9e-4976e0d14a40.png\">\r\n\r\n\r\nThe
reason why the `ref` got destroyed was [this
early\r\nreturn](https://github.com/elastic/kibana/blob/e8d77b3f0f46ac62e9220ffe28eb455880854906/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx#L98-L100).\r\nWith
the code in `main` there is a brief moment in which the
condition\r\nholds `true`, right after the monitors are loaded. In that
brief instant\r\nthe `status` is present but `monitorsSortedByStatus` is
empty.\r\n\r\n<img width=\"1084\" alt=\"Screenshot 2022-11-29 at 16 44
35\"\r\nsrc=\"https://user-images.githubusercontent.com/57448/204575679-de4bc6bf-122b-4c6d-ae75-9c96a7c5fb85.png\">\r\n\r\nWhen
this happens the `ref` is destroyed, because the underlying
element\r\nused to track the intersection is destroyed due of the early
return.\r\n\r\nThis was caused because `monitorsSortedByStatus` was
updated\r\nasynchronously
[with\r\n`useEffect`](https://github.com/elastic/kibana/blob/2f3313371bc6d992a99accef1289dd035779d3e6/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_monitors_sorted_by_status.tsx#L30-L72)\r\nas
part of the component lifecycle.\r\n\r\nThis PR uses `useMemo` instead
of `useEffect`, to update the\r\n`monitorsSortedByStatus` at the same
time that `status` is present. This\r\nprevents the early return from
ever firing in the normal load cycle and\r\nkeeps the `ref`. Since the
`ref` never gets destroyed there's no race\r\ncondition
anymore.","sha":"217a04078d4f8906feaf555da81aff8ce3d8ffad","branchLabelMapping":{"^v8.7.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:uptime","release_note:skip","v8.6.0","v8.7.0"],"number":146570,"url":"https://github.com/elastic/kibana/pull/146570","mergeCommit":{"message":"[Synthetics
UI] Fix infinite scroll in overview page (#146570)\n\n##
Summary\r\n\r\nCloses #145378.\r\n\r\nThe overview page has a
[`<EuiSpacer />` at the bottom of
the\r\ngrid](https://github.com/elastic/kibana/blob/e8d77b3f0f46ac62e9220ffe28eb455880854906/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx#L135-L137)\r\nto
track the user's scroll position. This is done [with
an\r\n`IntersectionObserver` (wrapped in a hook) and
a\r\n`ref`](https://github.com/elastic/kibana/blob/e8d77b3f0f46ac62e9220ffe28eb455880854906/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx#L70-L75).\r\n\r\nSometimes
the `ref` got destroyed, and with it the\r\n`IntersectionObserver`
instance. This causes a race condition [in the\r\ncode that checks for
the\r\nintersection](https://github.com/elastic/kibana/blob/e8d77b3f0f46ac62e9220ffe28eb455880854906/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx#L78-L88)\r\nto
determine if the next page should be loaded or not.\r\n\r\n<img
width=\"1278\" alt=\"Screenshot 2022-11-29 at 16 35
42\"\r\nsrc=\"https://user-images.githubusercontent.com/57448/204574461-5056391c-e96d-4b38-9c9e-4976e0d14a40.png\">\r\n\r\n\r\nThe
reason why the `ref` got destroyed was [this
early\r\nreturn](https://github.com/elastic/kibana/blob/e8d77b3f0f46ac62e9220ffe28eb455880854906/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx#L98-L100).\r\nWith
the code in `main` there is a brief moment in which the
condition\r\nholds `true`, right after the monitors are loaded. In that
brief instant\r\nthe `status` is present but `monitorsSortedByStatus` is
empty.\r\n\r\n<img width=\"1084\" alt=\"Screenshot 2022-11-29 at 16 44
35\"\r\nsrc=\"https://user-images.githubusercontent.com/57448/204575679-de4bc6bf-122b-4c6d-ae75-9c96a7c5fb85.png\">\r\n\r\nWhen
this happens the `ref` is destroyed, because the underlying
element\r\nused to track the intersection is destroyed due of the early
return.\r\n\r\nThis was caused because `monitorsSortedByStatus` was
updated\r\nasynchronously
[with\r\n`useEffect`](https://github.com/elastic/kibana/blob/2f3313371bc6d992a99accef1289dd035779d3e6/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_monitors_sorted_by_status.tsx#L30-L72)\r\nas
part of the component lifecycle.\r\n\r\nThis PR uses `useMemo` instead
of `useEffect`, to update the\r\n`monitorsSortedByStatus` at the same
time that `status` is present. This\r\nprevents the early return from
ever firing in the normal load cycle and\r\nkeeps the `ref`. Since the
`ref` never gets destroyed there's no race\r\ncondition
anymore.","sha":"217a04078d4f8906feaf555da81aff8ce3d8ffad"}},"sourceBranch":"main","suggestedTargetBranches":["8.6"],"targetPullRequestStates":[{"branch":"8.6","label":"v8.6.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.7.0","labelRegex":"^v8.7.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/146570","number":146570,"mergeCommit":{"message":"[Synthetics
UI] Fix infinite scroll in overview page (#146570)\n\n##
Summary\r\n\r\nCloses #145378.\r\n\r\nThe overview page has a
[`<EuiSpacer />` at the bottom of
the\r\ngrid](https://github.com/elastic/kibana/blob/e8d77b3f0f46ac62e9220ffe28eb455880854906/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx#L135-L137)\r\nto
track the user's scroll position. This is done [with
an\r\n`IntersectionObserver` (wrapped in a hook) and
a\r\n`ref`](https://github.com/elastic/kibana/blob/e8d77b3f0f46ac62e9220ffe28eb455880854906/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx#L70-L75).\r\n\r\nSometimes
the `ref` got destroyed, and with it the\r\n`IntersectionObserver`
instance. This causes a race condition [in the\r\ncode that checks for
the\r\nintersection](https://github.com/elastic/kibana/blob/e8d77b3f0f46ac62e9220ffe28eb455880854906/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx#L78-L88)\r\nto
determine if the next page should be loaded or not.\r\n\r\n<img
width=\"1278\" alt=\"Screenshot 2022-11-29 at 16 35
42\"\r\nsrc=\"https://user-images.githubusercontent.com/57448/204574461-5056391c-e96d-4b38-9c9e-4976e0d14a40.png\">\r\n\r\n\r\nThe
reason why the `ref` got destroyed was [this
early\r\nreturn](https://github.com/elastic/kibana/blob/e8d77b3f0f46ac62e9220ffe28eb455880854906/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx#L98-L100).\r\nWith
the code in `main` there is a brief moment in which the
condition\r\nholds `true`, right after the monitors are loaded. In that
brief instant\r\nthe `status` is present but `monitorsSortedByStatus` is
empty.\r\n\r\n<img width=\"1084\" alt=\"Screenshot 2022-11-29 at 16 44
35\"\r\nsrc=\"https://user-images.githubusercontent.com/57448/204575679-de4bc6bf-122b-4c6d-ae75-9c96a7c5fb85.png\">\r\n\r\nWhen
this happens the `ref` is destroyed, because the underlying
element\r\nused to track the intersection is destroyed due of the early
return.\r\n\r\nThis was caused because `monitorsSortedByStatus` was
updated\r\nasynchronously
[with\r\n`useEffect`](https://github.com/elastic/kibana/blob/2f3313371bc6d992a99accef1289dd035779d3e6/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_monitors_sorted_by_status.tsx#L30-L72)\r\nas
part of the component lifecycle.\r\n\r\nThis PR uses `useMemo` instead
of `useEffect`, to update the\r\n`monitorsSortedByStatus` at the same
time that `status` is present. This\r\nprevents the early return from
ever firing in the normal load cycle and\r\nkeeps the `ref`. Since the
`ref` never gets destroyed there's no race\r\ncondition
anymore.","sha":"217a04078d4f8906feaf555da81aff8ce3d8ffad"}}]}]
BACKPORT-->

Co-authored-by: Alejandro Fernández Gómez <[email protected]>
@afgomez afgomez deleted the 145378-infinite-scroll-monitors-fix branch November 30, 2022 09:56
@afgomez
Copy link
Contributor Author

afgomez commented Nov 30, 2022

Thank you @dominiqueclarke !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release_note:skip Skip the PR/issue when compiling release notes Team:Uptime - DEPRECATED Synthetics & RUM sub-team of Application Observability v8.6.0 v8.7.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Synthetics UI] Lazy loaded overview cards do not always load
5 participants