Skip to content

Commit

Permalink
Fix Beacon API and page lifecycle event guidance (#2866)
Browse files Browse the repository at this point in the history
* Issue 2692: Update Beacon API docs

* Issue 2692: Update event pages

* Issue 2692: delete 'Using the Beacon API'

* Fix _redirects file

* Fix _redirects.txt

Ran `yarn content fix-redirects en-us` and it fixed the _redirects.txt
file — by moving the /en-US/docs/Web/API/Beacon_API/Using_the_Beacon_API
line where it’s apparently expected.

From that I infer the problem was that the linter expects the file to be
sorted, and the /en-US/docs/Web/API/Beacon_API/Using_the_Beacon_API line
was out of sort order.

* Copy-edit: improve wording

Co-authored-by: Michael[tm] Smith <[email protected]>

* Copy-edit: improve wording

Co-authored-by: Michael[tm] Smith <[email protected]>

* Use an ordered list for a series of linked steps

Co-authored-by: Michael[tm] Smith <[email protected]>

* Use an ordered list for a series of linked steps

Co-authored-by: Michael[tm] Smith <[email protected]>

* Use en-US spelling

Co-authored-by: Michael[tm] Smith <[email protected]>

* Use an ordered list for a series of linked steps

Co-authored-by: Michael[tm] Smith <[email protected]>

* Copy-edit: improve wording

Co-authored-by: Michael[tm] Smith <[email protected]>

* Use an ordered list for a series of linked steps

Co-authored-by: Michael[tm] Smith <[email protected]>

* Copy-edit: improve wording

Co-authored-by: Michael[tm] Smith <[email protected]>

Co-authored-by: Michael[tm] Smith <[email protected]>
  • Loading branch information
wbamberg and sideshowbarker authored Mar 5, 2021
1 parent 10a2e1d commit 7920663
Show file tree
Hide file tree
Showing 9 changed files with 221 additions and 204 deletions.
1 change: 1 addition & 0 deletions files/en-us/_redirects.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7202,6 +7202,7 @@
/en-US/docs/Web/API/BatteryManager.onchargingtimechange /en-US/docs/Web/API/BatteryManager/onchargingtimechange
/en-US/docs/Web/API/BatteryManager.ondischargingtimechange /en-US/docs/Web/API/BatteryManager/ondischargingtimechange
/en-US/docs/Web/API/BatteryManager.onlevelchange /en-US/docs/Web/API/BatteryManager/onlevelchange
/en-US/docs/Web/API/Beacon_API/Using_the_Beacon_API /en-US/docs/Web/API/Beacon_API
/en-US/docs/Web/API/BeforeInstallPromptEvent/BeforeInstallPromptEvent.prompt() /en-US/docs/Web/API/BeforeInstallPromptEvent/prompt
/en-US/docs/Web/API/BiquadFilterNode.Q /en-US/docs/Web/API/BiquadFilterNode/Q
/en-US/docs/Web/API/BiquadFilterNode.detune /en-US/docs/Web/API/BiquadFilterNode/detune
Expand Down
13 changes: 0 additions & 13 deletions files/en-us/_wikihistory.json
Original file line number Diff line number Diff line change
Expand Up @@ -32847,19 +32847,6 @@
"AFBarstow"
]
},
"Web/API/Beacon_API/Using_the_Beacon_API": {
"modified": "2020-04-22T12:33:34.173Z",
"contributors": [
"benbot",
"Tigt",
"kulturbande",
"JorritSchippers",
"jhard",
"Rowno",
"rolfedh",
"AFBarstow"
]
},
"Web/API/BeforeInstallPromptEvent": {
"modified": "2020-10-15T21:36:26.724Z",
"contributors": [
Expand Down
45 changes: 27 additions & 18 deletions files/en-us/web/api/beacon_api/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,54 @@
- Guide
- Overview
- Web Performance
- user behavior tracker
- user tracker
---
<div>{{DefaultAPISidebar("Beacon")}}</div>

<p>The <strong><code>Beacon</code></strong> interface is used to schedule an asynchronous and non-blocking request to a web server. Beacon requests use the HTTP POST method and requests typically do not require a response. Requests are guaranteed to be initiated before a page is unloaded and they are run to completion, without requiring a blocking request (for example {{domxref("XMLHttpRequest")}}).</p>
<p>The <strong><code>Beacon</code></strong> API is used to send an asynchronous and non-blocking request to a web server. The request does not expect a response. Unlike requests made using {{domxref("XMLHttpRequest")}} or the <a href="/en-US/docs/Web/API/Fetch_API">Fetch API</a>, the browser guarantees to initiate beacon requests before the page is unloaded and to run them to completion.</p>

<p>The main use case for the Beacon API is to send analytics such as client-side events or session data to the server. Historically, websites have used {{domxref("XMLHttpRequest")}} for this, but browsers do not guarantee to send these asynchronous requests in some circumstances (for example, if the page is about to be unloaded). To combat this, websites have resorted to various techniques, such as making the request synchronous, that have a bad effect on responsiveness. Because beacon requests are both asynchronous and guaranteed to be sent, they combine good performance characteristics and reliability.</p>

<p>For more details about the motivation for and usage of this API, see the documentation for the {{domxref("navigator.sendBeacon()")}} method.</p>

<div class="notecard note">
<p><strong>Note:</strong> This API is <em>not available</em> in <a href="/en-US/docs/Web/API/Web_Workers_API">Web Workers</a> (not exposed via {{domxref("WorkerNavigator")}}).</p>
</div>

<p>Example use cases of the Beacon API are logging activity and sending analytics data to the server.</p>

<p>Example code of the interfaces described in this document is included in <em><a href="/en-US/docs/Web/API/Beacon_API/Using_the_Beacon_API">Using the Beacon API</a></em>.</p>

<h2 id="Why_use_Beacon">Why use Beacon?</h2>

<p>The <code>Beacon</code> interface addresses the needs of analytics and diagnostics code that typically attempts to send data to a web server before unloading the document. Sending the data any sooner may result in a missed opportunity to gather data. However, ensuring that the data is sent during the unloading of a document is something that has traditionally been difficult for developers.</p>

<p>User agents will typically ignore asynchronous {{domxref("XMLHttpRequest","XMLHttpRequests")}} made in an unload handler. To solve this problem, analytics and diagnostics code will typically make a synchronous {{domxref("XMLHttpRequest")}} in an {{event("unload")}} or {{event("beforeunload")}} handler to submit the data. The synchronous {{domxref("XMLHttpRequest")}} forces the browser to delay unloading the document, and makes the next navigation appear to be slower. There is nothing the next page can do to avoid this perception of poor page load performance.</p>
<h2>Interfaces</h2>

<p>There are other techniques used to ensure that data is submitted. One such technique is to delay the unload to submit data by creating an Image element and setting its <code>src</code> attribute within the unload handler. As most user agents will delay the unload to complete the pending image load, data can be submitted during the unload. Another technique is to create a no-op loop for several seconds within the unload handler to delay the unload and submit data to a server.</p>
<p>This API defines a single method: {{domxref("navigator.sendBeacon()")}}.</p>

<p>Not only do these techniques represent poor coding patterns, some of them are unreliable and result in the perception of poor page load performance for the next navigation. The Beacon API provides a standard way to address these issues.</p>
<p>The method takes two arguments, the URL and the data to send in the request. The data argument is optional and its type may be an {{domxref("ArrayBufferView")}}, {{domxref("Blob")}}, {{domxref("DOMString")}}, or {{domxref("FormData")}}. If the browser successfully queues the request for delivery, the method returns "<code>true</code>"; otherwise, it returns "<code>false</code>".</p>

<h2 id="Global_context">Global context</h2>
<h2 id="Specifications">Specifications</h2>

<p>The Beacon API's {{domxref("Navigator.sendBeacon()")}} method is used to send a <em>beacon</em> of data to the server in the <em>global browsing context</em>. The method takes two arguments, the URL and the data to send in the request. The data argument is optional and its type may be an {{domxref("ArrayBufferView")}}, {{domxref("Blob")}}, {{domxref("DOMString")}}, or {{domxref("FormData")}}. If the browser successfully queues the request for delivery, the method returns "<code>true</code>" and returns "<code>false</code>" otherwise.</p>
<table class="standard-table">
<thead>
<tr>
<th scope="col">Specification</th>
<th scope="col">Status</th>
<th scope="col">Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{SpecName('Beacon')}}</td>
<td>{{Spec2('Beacon')}}</td>
<td>Initial definition</td>
</tr>
</tbody>
</table>

<h2 id="Browser_compatibility">Browser compatibility</h2>

<p>The {{domxref("Navigator.sendBeacon","Navigator.sendBeacon()","Browser_compatibility")}} table indicates that method has relatively broad implementation.</p>
<p>{{Compat("api.Navigator.sendBeacon")}}</p>

<h2 id="See_also">See also</h2>

<ul>
<li>{{domxref("WorkerGlobalScope")}}</li>
<li><a href="https://w3c.github.io/beacon/">Beacon standard</a></li>
<li><a href="https://caniuse.com/#search=beacon">Beacon CanIUse data</a></li>
<li><a href="https://ehsanakhgari.org/blog/2015-04-08/intercepting-beacons-through-service-workers">Intercepting beacons through service workers</a>; Ehsan Akhgari; 2015-Apr-08</li>
<li><a href="https://webkit.org/blog/8821/link-click-analytics-and-privacy/">https://webkit.org/blog/8821/link-click-analytics-and-privacy/</a></li>
<li><a href="https://calendar.perfplanet.com/2020/beaconing-in-practice/">Beaconing in Practice</a></li>
</ul>
60 changes: 0 additions & 60 deletions files/en-us/web/api/beacon_api/using_the_beacon_api/index.html

This file was deleted.

25 changes: 18 additions & 7 deletions files/en-us/web/api/document/visibilitychange_event/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
---
<div>{{APIRef}}</div>

<p>The <code>visibilitychange</code> event is fired at the document when the content of its tab have become visible or have been hidden.</p>
<p>The <code>visibilitychange</code> event is fired at the document when the contents of its tab have become visible or have been hidden.</p>

<table class="properties">
<tbody>
Expand All @@ -39,16 +39,14 @@ <h2 id="Usage_notes">Usage notes</h2>

<p>The event doesn't include the document's updated visibility status, but you can get that information from the document's {{domxref("Document.visibilityState", "visibilityState")}} property.</p>

<div class="notecard warning">
<p>Safari doesn’t fire <code>visibilitychange</code> as expected when the value of the <code><a href="/en-US/docs/Web/API/Document/visibilityState">visibilityState</a></code> property transitions to <code>hidden</code>; so for that case, you need to also include code to listen for the <code><a href="/en-US/docs/Web/API/Window/pagehide_event">pagehide</a></code> event.</p>
</div>
<p>This event fires with a <code>visibilityState</code> of <code>hidden</code> when a user navigates to a new page, switches tabs, closes the tab, minimizes or closes the browser, or, on mobile, switches from the browser to a different app. Transitioning to <code>hidden</code> is the last event that's reliably observable by the page, so developers should treat it as the likely end of the user's session (for example, for <a href="/en-US/docs/Web/API/Navigator.sendBeacon">sending analytics data</a>).</p>

<div class="notecard warning">
<p>For compatibility reasons, make sure to use <code>document.addEventListener</code> to register the callback and not <code>window.addEventListener</code>. Safari &lt; 14.0 only supports the former.</p>
</div>
<p>The transition to <code>hidden</code> is also a good point at which pages can stop making UI updates and stop any tasks that the user doesn't want to have running in the background.</p>

<h2 id="Examples">Examples</h2>

<h3>Pausing music on transitioning to hidden</h3>

<p>This example begins playing a music track when the document becomes visible, and pauses the music when the document is no longer visible.</p>

<pre class="brush:js">document.addEventListener("visibilitychange", function() {
Expand All @@ -60,6 +58,17 @@ <h2 id="Examples">Examples</h2>
});
</pre>

<h3>Sending end-of-session analytics on transitioning to hidden</h3>

<p>This example treats the transition to <code>hidden</code> as the end of the user's session, and sends the appropriate analytics using the {{domxref("Navigator.sendBeacon()")}}
API:</p>

<pre class="brush: js">document.addEventListener('visibilitychange', function logData() {
if (document.visibilityState === 'hidden') {
navigator.sendBeacon('/log', analyticsData);
}
});</pre>

<h2 id="Specifications">Specifications</h2>

<table class="standard-table">
Expand Down Expand Up @@ -88,4 +97,6 @@ <h2 id="See_also">See also</h2>
<ul>
<li><a href="/en-US/docs/Web/API/Page_Visibility_API">Page Visibility API</a></li>
<li>{{domxref("Document.visibilityState")}}</li>
<li><a href="https://www.igvita.com/2015/11/20/dont-lose-user-and-app-state-use-page-visibility/">Don't lose user and app state, use Page Visibility</a> explains in detail why you should use <code>visibilitychange</code>, not <code>beforeunload</code>/<code>unload</code>.</li>
<li><a href="https://developers.google.com/web/updates/2018/07/page-lifecycle-api#developer-recommendations-for-each-state">Page Lifecycle API</a> gives best-practices guidance on handling page lifecyle behavior in your web applications.</li>
</ul>
Loading

0 comments on commit 7920663

Please sign in to comment.