User Interactions
Time user-driven flows — form submissions, multi-step actions, and nested backend calls — with timeUserInteraction(...) and the unified PerformanceCallBuilder.
A "backend call" is a single trip to Apex. A "user interaction" is everything that happens between the user clicking a button and seeing the result — which may involve several backend calls, some client-side work, and a final UI update.
timeUserInteraction(interactionName, fn) is the umbrella timer for those higher-level flows. It uses the same PerformanceCallBuilder as Backend Calls, so the error-handling story is identical (default, withoutRethrow, custom handler, both). The only difference is the log type — interactions land as TYPE.USER_INTERACTION and the error context exposes interactionName instead of methodName.
Basic Usage
import Triton from 'c/triton';
import submitFormData from '@salesforce/apex/FormController.submitFormData';
import validateFormData from '@salesforce/apex/FormController.validateFormData';
export default class FormHandler extends LightningElement {
triton;
formData = {};
connectedCallback() {
this.triton = new Triton().bindToComponent('FormHandler');
this.triton.trackComponentLifecycle('connected');
}
async handleSubmit() {
await this.triton.timeUserInteraction('form-submit', async () => {
const data = this.collectFormData();
const validation = await this.triton.timeBackendCall(
'validateFormData',
() => validateFormData({ data })
).execute();
if (!validation.isValid) {
throw new Error(`Form validation failed: ${validation.errors.join(', ')}`);
}
const result = await this.triton.timeBackendCall(
'submitFormData',
() => submitFormData({ data })
).execute();
this.showSuccessMessage(result);
return result;
}).execute();
}
}What you get out of this:
One
User interaction started: form-submitlog when the user clicks.Two
Backend call started/completedpairs for the validate + submit Apex methods.One
User interaction completed: form-submitlog at the end, with the total duration including both backend calls and any client-side work in between.
That parent-child relationship — interaction with nested backend calls — is the key reason to use timeUserInteraction even when "it's just one Apex call". It gives you a single record per user click that aggregates the whole experience.
Nested Calls With Per-Step Resilience
Real-world flows often want different error policies per step. Here's a payment flow where notification failures don't kill the transaction:
Validation and processing rethrow (so a failure short-circuits the flow), notifications swallow their own errors, and the outer interaction wrap catches everything that escaped — surfacing a single user-facing error and a single top-level failure log.
Custom Handler Context
Custom error handlers on user interactions receive:
Contrast with backend calls, which use methodName instead of interactionName. The duration is measured from timeUserInteraction(...) to the moment the error was thrown.
When to Use Interactions vs. Backend Calls
A single Apex round trip
A user-triggered flow with one or more Apex calls and client-side logic
timeUserInteraction (often wrapping timeBackendCall inside)
Purely client-side timing (DOM work, animations, sync work)
Component mount / unmount / re-render telemetry
Best Practices
Use a stable, descriptive
interactionName. Treat it like an event name ('checkout-submit','opportunity-clone') — it'll become a primary grouping key in dashboards.When nesting, let inner failures rethrow by default. The outer interaction will record the failure and you don't need to duplicate logging at every level.
Don't reach for
timeUserInteractionwhen there's no user. For background or lifecycle work, the more specific helpers below give better signal.
Last updated