Allow lazy-loading AppSignal in Angular#668
Conversation
|
Hi @arturovt, thanks for the contribution. Could you provide more context? What does this change fix or improve on and how? |
|
After reading the changes to the I don't think that means we cannot merge these changes, but it does mean we'd need to still support the non-lazy-loaded approach alongside the lazy one. That said, it's still unclear to me what the benefit of lazy-loading it is -- the |
|
@unflxw I have an off-topic question, how do I build appsignal/javascript locally? Because I ain't able to run |
|
appsignal/mono (this Mono, not the C# interpreter!) should work on Linux just fine, but it should also be possible to manually run the same |
493dec9 to
1e77842
Compare
The previous implementation required an instantiated `AppSignal` object to be passed directly into the error handler, which meant the entire AppSignal bundle had to be eagerly loaded upfront — even if no errors ever occurred.
This change replaces the direct instance with a factory/loader pattern (`() => AppSignal | Promise<AppSignal>`). The AppSignal instance is now resolved lazily via a `defer()` observable that only invokes the factory on the first error, with `shareReplay` ensuring the factory is called exactly once and the result reused for all subsequent errors.
The practical benefit is that consumers can now pass a dynamic import as the loader:
```ts
createErrorHandlerFactory(() => import("@appsignal/javascript").then(m => m.default))
```
This keeps AppSignal out of the main bundle entirely and lets the browser load it on demand, only when something actually goes wrong. For apps where errors are rare or never occur in normal usage, this avoids the network and parse cost of the AppSignal bundle altogether.
Additionally, error reporting is now run outside Angular's zone (`NgZone.runOutsideAngular`) to prevent the async resolution from triggering unnecessary change detection cycles.
1e77842 to
7cb8940
Compare
This comment has been minimized.
This comment has been minimized.
4 similar comments
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
@unflxw ping me if you need anything to be clarified, I've updated git commit description (see PR description). The docs would need to be fixed too, idk if they're public. |
This comment has been minimized.
This comment has been minimized.
1 similar comment
This comment has been minimized.
This comment has been minimized.
|
Thanks @arturovt, and thanks again so much for proposing this improvement! As someone who's admittedly not deeply familiar with Angular, my main question is still this:
That is, by accepting this change, we'd be adding the complexity of an alternative initialisation approach, with the necessary-to-document caveat that it would break certain usage patterns (breadcrumbs, as mentioned above, and also decorators; any usage pattern that is applied before an error is reported to AppSignal) -- so the question is, what is gained in return? I'm interested to know why lazy-loading AppSignal is valuable, what use cases would it enable. |
This comment has been minimized.
This comment has been minimized.
3 similar comments
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
This is a message from the daily scheduled checks. |
The previous implementation required an instantiated
AppSignalobject to be passed directly into the error handler, which meant the entire AppSignal bundle had to be eagerly loaded upfront — even if no errors ever occurred.This change replaces the direct instance with a factory/loader pattern (
() => AppSignal | Promise<AppSignal>). The AppSignal instance is now resolved lazily via adefer()observable that only invokes the factory on the first error, withshareReplayensuring the factory is called exactly once and the result reused for all subsequent errors.The practical benefit is that consumers can now pass a dynamic import as the loader:
This keeps AppSignal out of the main bundle entirely and lets the browser load it on demand, only when something actually goes wrong. For apps where errors are rare or never occur in normal usage, this avoids the network and parse cost of the AppSignal bundle altogether.
Additionally, error reporting is now run outside Angular's zone (
NgZone.runOutsideAngular) to prevent the async resolution from triggering unnecessary change detection cycles.