You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The **`DeferredRequestInit`** dictionary of the [`fetchLater()` API](/en-US/docs/Web/API/fetchLater_API) represents the set of options that can be used to configure a deferred fetch request.
12
+
The **`DeferredRequestInit`** dictionary of the [Fetch API](/en-US/docs/Web/API/Fetch_API) represents the set of options that can be used to configure a deferred fetch request.
13
13
14
14
The `DeferredRequestInit` object is passed directly into the {{domxref("window.fetchLater()")}} function call as the second argument.
The Fetch API provides an interface for fetching resources (including across the network). It is a more powerful and flexible replacement for {{DOMxRef("XMLHttpRequest")}}.
11
13
@@ -23,17 +25,34 @@ You can create a request and response directly using the {{DOMxRef("Request.Requ
23
25
24
26
Find out more about using the Fetch API features in [Using Fetch](/en-US/docs/Web/API/Fetch_API/Using_Fetch).
25
27
28
+
### Deferred Fetch
29
+
30
+
The {{domxref("Window/fetchLater", "fetchLater()")}} API enables a developer to request a _deferred fetch_, that can be sent after a specified period of time, or when the page is closed or navigated away from. See [Using Deferred Fetch](/en-US/docs/Web/API/Fetch_API/Using_Deferred_Fetch).
31
+
26
32
## Interfaces
27
33
28
34
- {{domxref("Window.fetch()")}} and {{domxref("WorkerGlobalScope.fetch()")}}
29
35
- : The `fetch()` method used to fetch a resource.
36
+
- {{domxref("Window.fetchLater()")}}
37
+
- : Used to make a deferred fetch request.
38
+
- {{domxref("DeferredRequestInit")}}
39
+
- : Represents the set of options that can be used to configure a deferred fetch request.
40
+
- {{domxref("FetchLaterResult")}}
41
+
- : Represents the result of requesting a deferred fetch.
30
42
- {{DOMxRef("Headers")}}
31
43
- : Represents response/request headers, allowing you to query them and take different actions depending on the results.
Deferred [`fetchLater()` API](/en-US/docs/Web/API/fetchLater_API) fetches are batched and sent once the tab is closed. At this point, there is no way for the user to abort them. To avoid situations where documents abuse this bandwidth to send unlimited amounts of data over the network the API sets quotas on how much data can be deferred to be sent later.
15
-
16
-
These quotas can be managed through {{HTTPHeader("Permissions-Policy/deferred-fetch", "deferred-fetch")}} and {{HTTPHeader("Permissions-Policy/deferred-fetch-minimal", "deferred-fetch-minimal")}} [Permissions Policy](/en-US/docs/Web/HTTP/Guides/Permissions_Policy) directives.
9
+
The **`fetchLater()` API** provides an interface to request a deferred fetch that can be sent after a specified period of time, or when the page is closed or navigated away from.
17
10
18
11
## Overview
19
12
13
+
Developers often need to send (or beacon) data back to the server, particularly at the end of a user's visit to a page — for example, for analytics services. There are several ways to do this: from adding 1 pixel {{HTMLElement("img")}} elements to the page, to {{domxref("XMLHttpRequest")}}, to the dedicated {{domxref("Beacon API", "Beacon API", "", "nocode")}}, and the {{domxref("Fetch API", "Fetch API", "", "nocode")}} itself.
14
+
15
+
The issue is that all of these methods suffer from reliability problems for end-of-visit beaconing. While the Beacon API and the {{domxref("Request.keepalive", "keepalive")}} property of the Fetch API will send data, even if the document is destroyed (to the best efforts that can be made in this scenario), this only solves part of the problem.
16
+
17
+
The other — more difficult — part to solve concerns deciding _when_ to send the data, since there is not an ideal time in a page's lifecycle to make the JavaScript call to send out the beacon:
18
+
19
+
- The {{domxref("Window.unload_event", "unload")}} and {{domxref("Window.beforeunload_event", "beforeunload")}} events are unreliable, and outright ignored by several major browsers.
20
+
- The {{domxref("Window.pagehide_event", "pagehide")}} and {{domxref("document.visibilitychange_event", "visibilitychange")}} events are more reliable, but still have issues on mobile platforms.
21
+
22
+
This means developers looking to reliably send out data via a beacon need to do so more frequently than is ideal. For example, they may send a beacon on each change, even if the final value for the page has not yet been reached. This has costs in network usage, server processing, and merging or discarding outdated beacons on the server.
23
+
24
+
Alternatively, developers can choose to accept some level of missing data — either by:
25
+
26
+
- Beaconing after a designated cut-off time and not collecting later data.
27
+
- Beaconing at the end of the page lifecycle but accepting that sometimes this will not be reliable.
28
+
29
+
The `fetchLater()` API extends the {{domxref("Fetch API", "Fetch API", "", "nocode")}} to allow setting fetch requests up in advance. These deferred fetches can be updated before they have been sent, allowing the payload to reflect the latest data to be beaconed.
30
+
31
+
The browser then sends the beacon when the tab is closed or navigated away from, or after a set time if specified. This avoids sending multiple beacons but still ensures a reliable beacon within reasonable expectations (i.e., excluding when the browser process shuts down unexpectedly during a crash).
32
+
33
+
Deferred fetches can also be aborted using an {{domxref("AbortController")}} if they are no longer required, avoiding further unnecessary costs.
34
+
35
+
## Quotas
36
+
37
+
Deferred fetches are batched and sent once the tab is closed; at this point, there is no way for the user to abort them. To avoid situations where documents abuse this bandwidth to send unlimited amounts of data over the network, the overall quota for a top-level document is capped at 640KiB.
38
+
39
+
Callers of `fetchLater()` should be defensive and catch `QuotaExceededError` errors in almost all cases, especially if they embed third-party JavaScript.
40
+
41
+
Since this cap makes deferred fetch bandwidth a scarce resource, which needs to be shared between multiple reporting origins (for example, several RUM libraries) and subframes from multiple origins, the platform provides a reasonable default division of this quota. In addition, it provides {{HTTPHeader("Permissions-Policy/deferred-fetch", "deferred-fetch")}} and {{HTTPHeader("Permissions-Policy/deferred-fetch-minimal", "deferred-fetch-minimal")}} [Permissions Policy](/en-US/docs/Web/HTTP/Guides/Permissions_Policy) directives to allow dividing it differently when desired.
42
+
20
43
The overall quota for `fetchLater()` is 640KiB per document. By default, this is divided into a 512KiB top-level quota and a 128KiB shared quota:
21
44
22
45
- The 512KiB top-level quota by default is for any `fetchLater()` requests made from the top-level document and direct subframes using that origin.
@@ -26,33 +49,33 @@ The overall quota for `fetchLater()` is 640KiB per document. By default, this is
26
49
27
50
For example, if a top-level `a.com` document includes a `<script>` that makes a `fetchLater()` request to `analytics.example.com`, this request would be bound by the top-level 512KiB limit. Alternatively, if the top-level document embeds an `<iframe>` with a source of `analytics.example.com` that makes a `fetchLater()` request, that request would be bound by the 128KiB limit.
28
51
29
-
## Quota limits by reporting origin and subframe
52
+
###Quota limits by reporting origin and subframe
30
53
31
54
Only 64KiB of the top-level 512KiB quota can be used concurrently for the same reporting origin (the request URL's origin). This prevents third-party libraries from reserving quota opportunistically before they have data to send.
32
55
33
56
Each cross-origin subframe gets an 8KiB quota out of the shared 128KiB quota by default, allocated when the subframe is added to the DOM (whether `fetchLater()` will be used in that subframe or not). This means that, in general, only the first 16 cross-origin subframes added to a page can use `fetchLater()` as they will use up the 128KiB quota.
34
57
35
-
## Increasing subframe quotas by sharing the top-level quota
58
+
###Increasing subframe quotas by sharing the top-level quota
36
59
37
60
The top-level origin can give selected cross-origin subframes an increased quota of 64KiB, taking it out of the larger top-level 512KiB limit. It does this by listing those origins in the {{HTTPHeader("Permissions-Policy/deferred-fetch", "deferred-fetch")}} Permissions Policy directive. This is allocated when the subframe is added to the DOM, leaving less quota for the top-level document and direct same-origin subframes. Multiple same-origin subdomains can each get a 64KiB quota.
38
61
39
-
## Restricting the shared quota
62
+
###Restricting the shared quota
40
63
41
64
The top-level origin can also restrict the 128KiB shared quota to named cross-origin subframes by listing those origins in the {{HTTPHeader("Permissions-Policy/deferred-fetch-minimal", "deferred-fetch-minimal")}} Permissions Policy. It can also revoke the entire 128KiB default subframe quota and instead keep the full 640KiB quota for itself and any named `deferred-fetch` cross-origins by setting the {{HTTPHeader("Permissions-Policy/deferred-fetch-minimal", "deferred-fetch-minimal")}} Permissions Policy to `()`.
42
65
43
-
## Delegating quotes to subframes of subframes
66
+
###Delegating quotes to subframes of subframes
44
67
45
68
By default, subframes of subframes are not allocated a quota and so cannot use `fetchLater()`. Subframes allocated the increased 64KiB quota can delegate the full 64KiB quota to further subframes and allow them to use `fetchLater()` by setting their own `deferred-fetch` Permissions Policy. They can only delegate their full quota to further subframes, not parts of it, and cannot specify new quotas. Subframes using the minimal 8KiB quota cannot delegate quotas to subframes. To be delegated quota, sub-subframes must be included in both the top-level and the subframe `deferred-fetch` {{httpheader('Permissions-Policy')}} directives.
46
69
47
-
## When quotas are exceeded
70
+
###When quotas are exceeded
48
71
49
72
When quotas are exceeded, a `QuotaExceededError` is thrown when the {{domxref('Window.fetchLater()','fetchLater()')}} method is called to initiate the deferred request.
50
73
51
74
Permissions Policy checks are not discernible from quota checks. Calling `fetchLater()` will throw a `QuotaExceededError` both if the quota is actually exceeded and if the quota was restricted for that origin via a Permissions Policy.
52
75
53
76
Callers of `fetchLater()` should be defensive and catch `QuotaExceededError` errors in almost all cases, especially if they embed third-party JavaScript.
54
77
55
-
## Examples
78
+
## Quota examples
56
79
57
80
### Using up the minimal quota
58
81
@@ -212,15 +235,3 @@ Assuming a top-level document at `a.com`, which embeds `<iframe src="https://b.c
212
235
1. The top-level frame of `a.com` has the default 512KiB quota.
213
236
2.`<iframe src="https://b.com/">` receives 8KiB of the default shared quota of 128KiB.
214
237
3. The 8KiB is not transferred to `a.com` when `<iframe src="https://b.com/">` redirects there, but it can share the full top-level quota again, and the previously-allocated 8KiB quota is released.
Copy file name to clipboardExpand all lines: files/en-us/web/api/fetchlaterresult/index.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,9 +7,9 @@ status:
7
7
browser-compat: api.FetchLaterResult
8
8
---
9
9
10
-
{{APIRef("fetchLater API")}}{{SeeCompatTable}}
10
+
{{APIRef("Fetch API")}}{{SeeCompatTable}}
11
11
12
-
The **`FetchLaterResult`** interface of the [`fetchLater()` API](/en-US/docs/Web/API/fetchLater_API) is returned by the {{domxref("Window.fetchLater()")}} method after a deferred fetch has been created.
12
+
The **`FetchLaterResult`** interface of the [Fetch API](/en-US/docs/Web/API/Fetch_API) is returned by the {{domxref("Window.fetchLater()")}} method after a deferred fetch has been created.
13
13
14
14
It contains a single `activated` property that indicates whether the deferred request has been sent out or not.
0 commit comments