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

[TSVB] Show the loading spinner while loading in dashboard #114244

Merged
merged 23 commits into from
Oct 25, 2021

Conversation

dej611
Copy link
Contributor

@dej611 dej611 commented Oct 7, 2021

Summary

Fixes #105678

I think this is a partial fix for the related issue as it shows a Loading animation while loading the timeseries component.
Couldn't manage to find out where is the component which is missing the other Loading animation in the process: notice the initial time window, before the Gauge loads where the time series has no animation yet.

With the fix (I've exaggerated the loading time for time series to 10s to better record it):

tsvb_loading_progress

Checklist

Delete any items that are not applicable to this PR.

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:

Risk Probability Severity Mitigation/Notes
Multiple Spaces—unexpected behavior in non-default Kibana Space. Low High Integration tests will verify that all features are still supported in non-default Kibana Space and when user switches between spaces.
Multiple nodes—Elasticsearch polling might have race conditions when multiple Kibana nodes are polling for the same tasks. High Low Tasks are idempotent, so executing them multiple times will not result in logical error, but will degrade performance. To test for this case we add plenty of unit tests around this logic and document manual testing procedure.
Code should gracefully handle cases when feature X or plugin Y are disabled. Medium High Unit tests will verify that any feature flag or plugin combination still results in our service operational.
See more potential risk examples

For maintainers

@dej611 dej611 added Feature:TSVB TSVB (Time Series Visual Builder) Team:Visualizations Visualization editors, elastic-charts and infrastructure auto-backport Deprecated - use backport:version if exact versions are needed v7.16.0 v8.0.0 release_note:skip Skip the PR/issue when compiling release notes labels Oct 7, 2021
@dej611 dej611 marked this pull request as ready for review October 7, 2021 12:35
@dej611 dej611 requested a review from a team as a code owner October 7, 2021 12:35
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-vis-editors (Team:VisEditors)

@dej611
Copy link
Contributor Author

dej611 commented Oct 11, 2021

@elasticmachine merge upstream

Copy link
Contributor

@flash1293 flash1293 left a comment

Choose a reason for hiding this comment

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

I looked at the loading behavior by creating a dashboard, going to the listing page, reloading, then delaying each request by 5s and loading the dashboard. This is what happens in order (omitted irrelevant parts but we should really work on avoiding dependent requests... separate story though):

  • 1 loading visualization embeddable (dashboard shows a spinner for this time)
  • 2 loading TSVB data (no spinner shown during this time)
  • 3 loading some other async TSVB chunks (no spinner shown during this time)
  • 4 loading the vis component (spinner shown)
  • 5 chart shown

I think to cover 3 we need to add the loading fallback here as well - something we could do on this PR as well (or maybe we can collapse the async chunks here into a single one? didn't check it though):

To cover 2, we probably need to move one layer up and render the loading icon once here (other charts will profit as well):

Then let the expression loader take over the dom node once it's ready

@@ -90,7 +90,9 @@ describe('metric_expression', () => {
reportDescription="Fancy chart description"
reportTitle="My fanci metric chart"
>
<AutoScale>
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like the Lens changes ended up in here on accident, do you want to remove them?

@dej611
Copy link
Contributor Author

dej611 commented Oct 12, 2021

I think to cover 3 we need to add the loading fallback here as well - something we could do on this PR as well (or maybe we can collapse the async chunks here into a single one? didn't check it though):

But there's already one there: the VisualizationContainer already contains the loading spinner with Suspense in it.
It seems the VisualizationContainer Suspense is triggered for the first panel and then other are queued like serially (or maybe it's just a reflection of the different size of each plugin)

@dej611
Copy link
Contributor Author

dej611 commented Oct 12, 2021

@elasticmachine merge upstream

@flash1293
Copy link
Contributor

Hm, right, maybe it's the scss import which isn't "suspended"?

await import('./application/index.scss');

Would it make sense to move it one layer deeper?

@dej611
Copy link
Contributor Author

dej611 commented Oct 13, 2021

It seems that fixed it 👍

@dej611
Copy link
Contributor Author

dej611 commented Oct 13, 2021

@elasticmachine merge upstream

@dej611
Copy link
Contributor Author

dej611 commented Oct 14, 2021

@elasticmachine merge upstream

@dej611
Copy link
Contributor Author

dej611 commented Oct 18, 2021

@elasticmachine merge upstream

@flash1293
Copy link
Contributor

This is definitely an improvement (also notice the smaller async bundle size!) but it seems like there is still one stage of async-ness missing:
Kapture 2021-10-18 at 11 54 53

I think the last one is missing here:

const [palettesService, { indexPattern }] = await Promise.all([

While it's resolving this Promise.all, it's not showing a spinner. Could you fix this one as well? I think then it's handled cleanly.

@dej611
Copy link
Contributor Author

dej611 commented Oct 18, 2021

This is definitely an improvement (also notice the smaller async bundle size!) but it seems like there is still one stage of async-ness missing: Kapture 2021-10-18 at 11 54 53

I think the last one is missing here:

const [palettesService, { indexPattern }] = await Promise.all([

While it's resolving this Promise.all, it's not showing a spinner. Could you fix this one as well? I think then it's handled cleanly.

I've recorded the timings and various phases of the loading (also added a loader fallback for the case you've pointed), but it looks like the biggest gap happens between the visualize_embeddable.ts and the render.ts plugin render call, which is not handled with the Load Spinner component.

loading_timeseries_dashboard

Here's a static picture of the logs with some annotations:

Screenshot 2021-10-18 at 18 46 32

Some of those waiting are due to expression data loading upfront, which I suspect they are deferred in the Lens embeddable, for instance, is that right?

The point you want to address is the following, which is relatively fast (few ms on a throttled connection):

{now: 1634575325649, status: '[timeseries_vis_renderer.tsx] Loading', type: 'timeseries'}
{now: 1634575325651, status: '[timeseries_vis_renderer.tsx] Loaded', type: 'timeseries'}

@flash1293
Copy link
Contributor

It would be this place, right?

Could we have spinner there as well? I think it’s worth solving this for all layers, there shouldn’t be so much jumping around when loading the page.

@dej611
Copy link
Contributor Author

dej611 commented Oct 19, 2021

Now the loading phase should be covered by the loader spinner:
loading_timeseries_dashboard_2

<TimeseriesVisualization
// it is mandatory to bind uiSettings because of "this" usage inside "get" method
getConfig={uiSettings.get.bind(uiSettings)}
render(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

should it be unmounted here before render the proper one?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure how important it is, but it should be fairly easy to unmount correctly - just call ReactDOM. unmountComponentAtNode(element) in these places.

@dej611
Copy link
Contributor Author

dej611 commented Oct 20, 2021

@flash1293 do you think it's worth adding 6kb to the visTypeTimeseries bundle size limit to avoid an async chunk round trip?
I can update the metrics config if you're ok with it.

@dej611
Copy link
Contributor Author

dej611 commented Oct 20, 2021

Ok, from the previous message I thought it was only a 6kb change, but 98kb it's another story. Will resolve it 😅

@dej611
Copy link
Contributor Author

dej611 commented Oct 20, 2021

Reversed last commit with the async chunk removal. Will track the issue in another PR.

@kibanamachine
Copy link
Contributor

💚 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
visTypeTimeseries 488.4KB 485.0KB -3.4KB
visualizations 72.8KB 73.0KB +170.0B
total -3.2KB

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
visTypeTimeseries 14.7KB 14.8KB +106.0B
visualizations 36.1KB 36.1KB +11.0B
total +117.0B
Unknown metric groups

async chunk count

id before after diff
visTypeTimeseries 12 11 -1

History

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

Copy link
Contributor

@flash1293 flash1293 left a comment

Choose a reason for hiding this comment

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

Works perfectly, thanks. Left a comment about unmounting the various loading spinners

<TimeseriesVisualization
// it is mandatory to bind uiSettings because of "this" usage inside "get" method
getConfig={uiSettings.get.bind(uiSettings)}
render(
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure how important it is, but it should be fairly easy to unmount correctly - just call ReactDOM. unmountComponentAtNode(element) in these places.

@dej611
Copy link
Contributor Author

dej611 commented Oct 25, 2021

@elasticmachine merge upstream

@kibanamachine
Copy link
Contributor

💚 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
visTypeTimeseries 488.7KB 485.3KB -3.4KB
visualizations 72.8KB 73.0KB +170.0B
total -3.2KB

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
visTypeTimeseries 14.7KB 14.8KB +142.0B
visualizations 36.1KB 36.1KB +11.0B
total +153.0B
Unknown metric groups

async chunk count

id before after diff
visTypeTimeseries 12 11 -1

History

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

@dej611 dej611 merged commit 560cb6f into elastic:master Oct 25, 2021
kibanamachine added a commit to kibanamachine/kibana that referenced this pull request Oct 25, 2021
…14244)

* 🐛 Fix metric rescale

* 📸 Restored old snapshots

* 🐛 Extend the fix to all scenarios

* 📸 Refresh snapshots for new fix

* 💄 Add suspense with loading spinner while waiting for the component to be loaded

* 🐛 Move the styling one level deeper to avoid loading gaps

* 🐛 show loader since the beginning and speed up a bit embeddable load

* 💄 Show the loader while waiting for the palette

* ⚡ Remove one chunk from TSVB async series

* 🐛 Restore previous async chunk

* 👌 Integrate feedback

* 🚨 Fix linting issue

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
@kibanamachine
Copy link
Contributor

💚 Backport successful

Status Branch Result
7.16

This backport PR will be merged automatically after passing CI.

kibanamachine added a commit that referenced this pull request Oct 25, 2021
…116122)

* 🐛 Fix metric rescale

* 📸 Restored old snapshots

* 🐛 Extend the fix to all scenarios

* 📸 Refresh snapshots for new fix

* 💄 Add suspense with loading spinner while waiting for the component to be loaded

* 🐛 Move the styling one level deeper to avoid loading gaps

* 🐛 show loader since the beginning and speed up a bit embeddable load

* 💄 Show the loader while waiting for the palette

* ⚡ Remove one chunk from TSVB async series

* 🐛 Restore previous async chunk

* 👌 Integrate feedback

* 🚨 Fix linting issue

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>

Co-authored-by: Marco Liberati <dej611@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-backport Deprecated - use backport:version if exact versions are needed Feature:TSVB TSVB (Time Series Visual Builder) release_note:skip Skip the PR/issue when compiling release notes Team:Visualizations Visualization editors, elastic-charts and infrastructure v7.16.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[TSVB] Missing loading spinner
4 participants