-
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
[Synthetics UI] Fix infinite scroll in overview page #146570
[Synthetics UI] Fix infinite scroll in overview page #146570
Conversation
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
Pinging @elastic/uptime (Team:uptime) |
💚 Build Succeeded
Metrics [docs]Async chunks
Unknown metric groupsESLint disabled in files
ESLint disabled line counts
Total ESLint disabled count
To update your PR or re-run it, just comment with: |
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. Tested with 100 monitors.
## 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)
💚 All backports created successfully
Note: Successful backport PRs will be merged automatically after passing CI. Questions ?Please refer to the Backport tool documentation |
…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]>
Thank you @dominiqueclarke ! |
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 anIntersectionObserver
(wrapped in a hook) and aref
.Sometimes the
ref
got destroyed, and with it theIntersectionObserver
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.The reason why the
ref
got destroyed was this early return. With the code inmain
there is a brief moment in which the condition holdstrue
, right after the monitors are loaded. In that brief instant thestatus
is present butmonitorsSortedByStatus
is empty.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 withuseEffect
as part of the component lifecycle.This PR uses
useMemo
instead ofuseEffect
, to update themonitorsSortedByStatus
at the same time thatstatus
is present. This prevents the early return from ever firing in the normal load cycle and keeps theref
. Since theref
never gets destroyed there's no race condition anymore.