We are considering 3 different APIs and would appreciate feedback. I will include some pros and cons but in order for us to correctly weight these, please comment even if it has already been called out as a pro/con and it's important to you.
This issue focuses on how to set new data on the beacon and deal with a beacon that has already sent its data.
Low-level APIs
These are 2 versions of the API in the explainer. Sync vs async is about the API shape, a sync API does not mean that operations will block, waiting for external events, rather it means that the API does not use Promises and that state cannot spontaneously change mid-task.
Sync
We have setData and isPending and if isPending returns true then the beacon has not been sent yet and setData will succeed. We could also remove isPending and have setData throw an exception but that's not fundamentally different.
Pros
- naive code to check and set the data works
Cons
Async
We have only setData and no isPending. setData returns a Promise that will resolve if the beacon has not been sent yet and the data was successfully set. It will reject if the data could not be set.
The reason we drop isPending is because the result could be invalid by the time we try to act on it.
Pros
Cons
- dealing with rejected calls to setData is tricky, especially if multiple calls are in flight, full example in the explainer.
High-level API
There are two straight-forward use cases for the beacon that suggest higher level APIs. Both of these could be implemented using the lower level API above. The real question is whether these 2 high-level APIs are enough or do we need to expose the low-level API?
In both of these, there is no isPending or even a way to tell if data has been sent already.
Appending data
The beacon accumulates data and batches it up for sending. Policies like timeouts etc control how batching occurs (some data may be sent before the page is discarded). It guarantees (to the extent possible) that all data appended will eventually be sent.
The page never needs to check if the beacon has already sent some intermediate batch, it just keeps appending data.
Replacing data
The beacon's data is replaced by calls to setData. It doesn't matter whether the beacon has already sent data, it can always be replaced. Again, policies like timeouts etc control when sending occurs with a guarantee that the last set value will be definitely be sent.
Use case, e.g. reporting LCP values. The page just keeps setting the latest observed LCP, perhaps with a policy that says "don't leave data sitting around unsent for more than 5 minutes".
Discussion
An example of where these APIs might not work well is where the page would like to merge 2 metrics into 1 beacon if possible. With the low-level API, it would check if the beacon has been sent already and if not, replace the data with the combined data. This could reduce network traffic (although arguably connection reuse and header compression makes that a small benefit). It could also reduce processing cost by delivering related data already joined.
It may be that these APIs are capable of doing everything that's needed but impose costs on the backend.
It may also be that there are use-cases that simply cannot be met with these APIs.
Please let us know.
We are considering 3 different APIs and would appreciate feedback. I will include some pros and cons but in order for us to correctly weight these, please comment even if it has already been called out as a pro/con and it's important to you.
This issue focuses on how to set new data on the beacon and deal with a beacon that has already sent its data.
Low-level APIs
These are 2 versions of the API in the explainer. Sync vs async is about the API shape, a sync API does not mean that operations will block, waiting for external events, rather it means that the API does not use Promises and that state cannot spontaneously change mid-task.
Sync
We have
setDataandisPendingand ifisPendingreturnstruethen the beacon has not been sent yet andsetDatawill succeed. We could also removeisPendingand havesetDatathrow an exception but that's not fundamentally different.Pros
Cons
Async
We have only
setDataand noisPending.setDatareturns a Promise that will resolve if the beacon has not been sent yet and the data was successfully set. It will reject if the data could not be set.The reason we drop
isPendingis because the result could be invalid by the time we try to act on it.Pros
Cons
High-level API
There are two straight-forward use cases for the beacon that suggest higher level APIs. Both of these could be implemented using the lower level API above. The real question is whether these 2 high-level APIs are enough or do we need to expose the low-level API?
In both of these, there is no
isPendingor even a way to tell if data has been sent already.Appending data
The beacon accumulates data and batches it up for sending. Policies like timeouts etc control how batching occurs (some data may be sent before the page is discarded). It guarantees (to the extent possible) that all data appended will eventually be sent.
The page never needs to check if the beacon has already sent some intermediate batch, it just keeps appending data.
Replacing data
The beacon's data is replaced by calls to
setData. It doesn't matter whether the beacon has already sent data, it can always be replaced. Again, policies like timeouts etc control when sending occurs with a guarantee that the last set value will be definitely be sent.Use case, e.g. reporting LCP values. The page just keeps setting the latest observed LCP, perhaps with a policy that says "don't leave data sitting around unsent for more than 5 minutes".
Discussion
An example of where these APIs might not work well is where the page would like to merge 2 metrics into 1 beacon if possible. With the low-level API, it would check if the beacon has been sent already and if not, replace the data with the combined data. This could reduce network traffic (although arguably connection reuse and header compression makes that a small benefit). It could also reduce processing cost by delivering related data already joined.
It may be that these APIs are capable of doing everything that's needed but impose costs on the backend.
It may also be that there are use-cases that simply cannot be met with these APIs.
Please let us know.