Scenario · JS interop
JS interop
Every call below goes through the IJSRuntime injected into this component and the JS module it
imports, so BevTools → JS Interop attributes it to Interop with its duration and result. JS → .NET
callbacks are reported by the browser bridge. A service that calls JS itself opts in with
jsRuntime.WithBevToolsTracking(session).
The calls
The functions live in wwwroot/js/interop.js: one measures the box below, one busy-waits for
400 ms, one is called 120 times in a loop, a class is constructed and its property read and written, one
calls back into .NET every 200 ms, one throws, one leaves an error and a rejected promise unhandled, and one
writes to localStorage and sessionStorage.
Measured element
JS Interop: per call and per identifier
The JS Interop panel counts the calls per identifier with their total, average and maximum duration and how many failed, and lists the recent calls with the component that made each one and its result. On the Server renderer every one of those calls is a round trip to the browser.
- → marks a .NET → JS call, ← a call from JS into .NET. Start the callbacks and
OnTickarrives five times a second as ←, reported by the browser bridge. - Calls on the imported module read
module.measure,module.ping…: a module reference obtained through a trackedIJSRuntimeis tracked too. - Create, read and write a JS object uses the .NET 10 interop members:
new module.Tally,get module.countandset module.count, each a row of its own (the object came from the module, so its calls are labelled with it). - JS function throws is a failed call: its result is the
JSException, and the identifier's Failed count goes up.
Diagnostics, Errors and Browser
- Diagnostics: Chatty loop is excessive interop (more than 50 calls to one identifier in a second) and Slow call is slow interop (over 250 ms). The fix for both: batch the work into one JS function.
- Errors: the JS exception the page catches (source js-interop, with the component), and the unhandled error and rejection the browser bridge reports (source javascript).
- Browser → Read localStorage / sessionStorage after Write localStorage/sessionStorage:
demo:themeanddemo:cartare shown,demo:auth_tokenis redacted in the browser before it ever reaches .NET. The same tab shows whether the browser is online and visible, the JS heap, the page load time, and the JS errors and JS → .NET calls it counted.
Calls that are not this page's
The panel shows every tracked call in the app, so the site around this page shows up too: the search box in
the header registers its keyboard shortcut once (bitDemoSite.registerPalette, from
CommandPalette) and locks the page scroll while it is open (bitDemoSite.lockScroll),
and the theme button calls bitDemoTheme.toggle from Header. The framework's own
calls - FocusOnNavigate moving focus after each navigation - are listed as well.