Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto shutdown in collector-exporter can hurt performance in some browsers #2205

Closed
1 of 2 tasks
kkruk-sumo opened this issue May 13, 2021 · 17 comments
Closed
1 of 2 tasks
Labels
enhancement New feature or request up-for-grabs Good for taking. Extra help will be provided by maintainers

Comments

@kkruk-sumo
Copy link
Contributor

  • This only affects the JavaScript OpenTelemetry library
  • This may affect other libraries, but I would like to get opinions here first

Hi 馃憢

@opentelemtry/exporter-collector by default adds event listener for the unload event on browser platforms.
According to MDN it can hurt website's performance when doing back/forward buttons:

Additionally, the unload event is incompatible with the back/forward cache (bfcache) implemented in modern browsers. Some browsers, such as Firefox, handle this incompatibility by excluding pages from the bfcache if they contain unload handlers, thus hurting performance.
See Avoid unload and beforeunload for more.

Also I'm not sure what's the purpose of this behaviour? shutdown only returns a promise of already exported items, so doing it on unload doesn't make more sense, does it? See the code I'm referring to.

Additionally, onShutdown is empty for node platform, so we could just remove the onInit and onShutdown functionalities. Am I missing something?

@kkruk-sumo
Copy link
Contributor Author

CC @davidwitten and @dyladan

@MSNev
Copy link
Contributor

MSNev commented Jun 11, 2021

Agree we shouldn't "shutdown" on unload, but we should perform a synchronous flush to ensure all telemetry is sent -- unless we have some sort of backing store (disk for node, and LocalStorage / IndexedDb (Slow!!!)) to ensure we can replay any unsent events on reload etc

@vanand-conga
Copy link

Is there any way I can flush synchronously?

@github-actions
Copy link

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days.

@github-actions github-actions bot added the stale label Jun 13, 2022
@legendecas legendecas added up-for-grabs Good for taking. Extra help will be provided by maintainers and removed up-for-grabs Good for taking. Extra help will be provided by maintainers labels Jun 14, 2022
@legendecas
Copy link
Member

Is this still valid after #2243 is landed?

@dyladan
Copy link
Member

dyladan commented Jun 15, 2022

I think we are still using the unload event right? So the performance issue would still be there.

@dyladan dyladan removed the stale label Jun 15, 2022
@dyladan
Copy link
Member

dyladan commented Jun 15, 2022

Is there any way I can flush synchronously?

No sorry

@vipulkv
Copy link

vipulkv commented Jul 25, 2022

Hi - Any update on this? This bug hurting us is causing low score of our website by PageSpeed Insights.

@kkruk-sumo
Copy link
Contributor Author

Is this still valid after #2243 is landed?

It's still valid. #2243 was about BatchSpanProcessor, and the unload listener is still in otlp-exporter https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/otlp-exporter-base/src/platform/browser/OTLPExporterBrowserBase.ts#L60 .

@dyladan
Copy link
Member

dyladan commented Jul 25, 2022

Agree we shouldn't "shutdown" on unload, but we should perform a synchronous flush to ensure all telemetry is sent -- unless we have some sort of backing store (disk for node, and LocalStorage / IndexedDb (Slow!!!)) to ensure we can replay any unsent events on reload etc

@MSNev how would you propose to perform a synchronous flush?

@MSNev
Copy link
Contributor

MSNev commented Jul 25, 2022

For browsers runtimes, there is not a lot of choice to ensure that we can get traces of the box, general options are

  • synchronous XHR (blocks UI, but also getting disabled by modern browsers) -- doesn't have size limits, required for IE
  • sendBeacon -- has 64kb payload limit. And this is "unsent" not per-request (you can't just do lots of sendBeacon requests)
  • fetch (with keep-alive) -- has same issue as sendBeacon
  • XHR / fetch (for larger payloads) -- using these are extremely problematic in that browsers can abort requests before the full payload is sent (resulting in nothing but the headers getting sent -- or nothing). I've seen this many times internally. So really not a viable option.

I don't know, if node (http) suffers from these same issues -- I would assume not.

Resiliency, by using LocalStorage / SessionStorage is really the only option (as IndexedDb is an asynchronous API). But that too can cause storage issues / limits for the domain. eg. If the hosting application (page) also needs to store "lots" of data we can't really store too much.

@dyladan
Copy link
Member

dyladan commented Jul 26, 2022

There are not really similar issues in node, but there are different ones. There is no way to make a synchronous network request in node without hacky solutions like calling a subprocess synchronously.

@dyladan
Copy link
Member

dyladan commented Jul 26, 2022

Isn't sendBeacon and fetch both async? The only sync option is sync XHR which has problems like you mentioned

@vmarchaud
Copy link
Member

Isn't sendBeacon and fetch both async? The only sync option is sync XHR which has problems like you mentioned

I believe sendBeacon API is sync however the data is sent asynchronously, you just never get the callback. It ensentially just push the request into a queue that is handled even if the page is closed.

@dyladan
Copy link
Member

dyladan commented Jul 28, 2022

Got it. So sendBeacon is our best bet on shutdowns and if we have to use xhr we just have to hope

@vmarchaud vmarchaud added the enhancement New feature or request label Jul 30, 2022
@jscherer92
Copy link

jscherer92 commented Aug 31, 2022

just checking, can we use the visibilityChange event instead? This is in the MDN documentation for the sendBeacon. If possible, though this would definitely add to the server handling, you could send over multiple sendBeacon requests. I know not ideal but still possible.

So overall, to the original, we should use the visibilityChange event as this is also helpful for mobile (another reason to avoid `unload).

@pichlermarc
Copy link
Member

Closing this as #4438 has landed. If this is still an issue, please reach out and I'll re-open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request up-for-grabs Good for taking. Extra help will be provided by maintainers
Projects
None yet
10 participants