aspire icon indicating copy to clipboard operation
aspire copied to clipboard

See whether plotly JavaScript can be imported on metrics page

Open JamesNK opened this issue 1 year ago • 1 comments

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:

  • https://github.com/dotnet/aspire/issues/4149
  • https://github.com/dotnet/aspire/issues/4150

JamesNK avatar May 11 '24 05:05 JamesNK

cc @DamianEdwards

JamesNK avatar May 11 '24 05:05 JamesNK

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

leslierichardson95 avatar Jul 02 '24 21:07 leslierichardson95

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.

SteveSandersonMS avatar Jul 03 '24 10:07 SteveSandersonMS

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 avatar Jul 09 '24 02:07 JamesNK

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

  • Split the plotly specific application logic into its own JS file, e.g. app-ploty.js
  • app-ploty.js has import ./scripts/ploty-2.26.0.min.js at the top to bring in big plotly JS file
  • Blazor page then imports app-ploty.js

@SteveSandersonMS what do you think?

JamesNK avatar Jul 09 '24 03:07 JamesNK

@JamesNK Yes exactly.

SteveSandersonMS avatar Jul 09 '24 09:07 SteveSandersonMS