dotnet / aspire

An opinionated, cloud ready stack for building observable, production ready, distributed applications in .NET
https://learn.microsoft.com/dotnet/aspire
MIT License
3.7k stars 423 forks source link

See whether plotly JavaScript can be imported on metrics page #4155

Closed JamesNK closed 2 months ago

JamesNK commented 4 months ago

Ploty JavaScript file is 3.5MB and is referenced from the root of the dashboard app, and so it must be downloaded before the dashboard page works: https://github.com/dotnet/aspire/blob/68e36e42ec109f7c2aeba48b74b1987547effac0/src/Aspire.Dashboard/Components/App.razor#L32

We might be able to make the plotly file dynamically imported on the metrics page. The goal is to make the file only downloaded if plotly is used.

Related:

JamesNK commented 4 months ago

cc @DamianEdwards

leslierichardson95 commented 3 months ago

@SteveSandersonMS do you know how we can import a JS library in a custom component?

SteveSandersonMS commented 3 months ago

Sure, if Plotly is available as an ES6 module then dynamic imports are a native browser feature. In Blazor you can trigger it by making a JS interop call like:

    var module = await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./scripts/plotly.js");

    // Then later, call its exports:
    var result  = await module.InvokeAsync<string>("someExportedFunction", /* params here */);

If Plotly isn't available as an ES6 module then you can still create your own ES6 module file that imports an arbitrary script: https://lea.verou.me/blog/2020/07/import-non-esm-libraries-in-es-modules-with-client-side-vanilla-js/

The browser is smart enough that once you've used import to import a particular file, you can import it again more times later without it re-downloading it. So there's no need to cache the returned instances for the lifetime of the circuit.

JamesNK commented 2 months ago

I believe Plotly is an ES6 module.

Plotly is being used by another JS file. How does that work if we're calling import on the module in Blazor? Do we pass the module as a parameter to functions in the other JS file when Blazor invokes them?

JamesNK commented 2 months ago

I get the feeling the the right way to do this is:

@SteveSandersonMS what do you think?

SteveSandersonMS commented 2 months ago

@JamesNK Yes exactly.