Firefox user agent string reference - HTTP

Firefox user agent string reference
===================================

This document describes the user agent string used in Firefox 4 and later and applications based on Gecko 2.0 and later. For a breakdown of changes to the string in Gecko 2.0, see Final User Agent string for Firefox 4 (blog post). See also this document on user agent sniffing and this Hacks blog post.

General form
------------

The UA string of Firefox itself is broken down into four components:

`Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion`

* `Mozilla/5.0` is the general token that says the browser is Mozilla compatible, and is common to almost every browser today.
* `platform` describes the native platform the browser is running on (e.g. Windows, Mac, Linux or Android), and whether or not it's a mobile phone. Firefox OS phones say "`Mobile`"; the web is the platform. Note that `platform` can consist of multiple "; "-separated tokens. See below for further details and examples.
* `rv:geckoversion` indicates the release version of Gecko (such as "`17.0`").
* `Gecko/geckotrail` indicates that the browser is based on Gecko.
* On Desktop, `geckotrail` is the fixed string "`20100101`"
* `Firefox/firefoxversion` indicates the browser is Firefox, and provides the version (such as "`17.0`").
* From Firefox 10 on mobile, `geckotrail` is the same as `firefoxversion`.

**Note:** The recommended way of sniffing for Gecko-based browsers (if you *have to* sniff for the browser engine instead of using feature detection) is by the presence of the "`Gecko`" and "`rv:`" strings, since some other browsers include a "`like Gecko`" token.

For other products based on Gecko, the string can take one of two forms, where the tokens have the same meaning except those noted below:

`Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail appname/appversion`
`Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion appname/appversion`

* `appname/appversion` indicates the application name and version. For instance, this could be "`Camino/2.1.1`", or "`SeaMonkey/2.7.1`".
* `Firefox/firefoxversion` is an optional compatibility token that some Gecko-based browsers may choose to incorporate, to achieve maximum compatibility with websites that expect Firefox. `firefoxversion` will generally represent the equivalent Firefox release corresponding to the given Gecko version. Some Gecko-based browsers may not opt into using this token; for this reason, sniffers should be looking for Gecko — not Firefox!

Prior to Firefox 4 and Gecko 2.0, it was possible for extensions and plug-ins to add user agent parts, but that has not been possible since Firefox bug 581008.

Mobile and Tablet indicators
----------------------------

The `platform` part of the UA string indicates if Firefox is running on a phone-sized or tablet device. When Firefox runs on a device that has the phone form factor, there is a `Mobile;` token in the `platform` part of the UA string. When Firefox runs on a tablet device, there is a `Tablet;` token in the `platform` part of the UA string instead. For example:
```

Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0
Mozilla/5.0 (Android 4.4; Tablet; rv:41.0) Gecko/41.0 Firefox/41.0
```

**Note:** The version numbers are not relevant. Avoid inferring materials based on these.

The preferred way to target content to a device form factor is to use CSS Media Queries. However, if you use UA sniffing to target content to a device form factor, please look for **Mobi** (to include Opera Mobile, which uses "Mobi") for the phone form factor and do **not** assume any correlation between "Android" and the device form factor. This way, your code will work if/when Firefox ships on other phone/tablet operating systems or Android is used for laptops. Also, please use touch detection to find touch devices rather than looking for "Mobi" or "Tablet", since there may be touch devices which are not tablets.

**Note:** Firefox OS devices identify themselves without any operating system indication; for example: "Mozilla/5.0 (Mobile; rv:15.0) Gecko/15.0 Firefox/15.0". The web is the platform.

Windows
-------

Windows user agents have the following variations, where *x.y* is the Windows NT version (for instance, Windows NT 6.1).

Linux
-----

Linux is a more diverse platform. Your distribution of Linux might include an extension that changes your user-agent. A few common examples are given below.

| Linux version | Gecko user agent string |
| --- | --- |
| Linux desktop on i686 CPU | Mozilla/5.0 (X11; Linux i686; rv:10.0) Gecko/20100101 Firefox/10.0 |
| Linux desktop on x86\_64 CPU | Mozilla/5.0 (X11; Linux x86\_64; rv:10.0) Gecko/20100101 Firefox/10.0 |

Android (version 40 and below)
------------------------------

| Form factor | Gecko user agent string |
| --- | --- |
| Phone | Mozilla/5.0 (Android; Mobile; rv:40.0) Gecko/40.0 Firefox/40.0 |
| Tablet | Mozilla/5.0 (Android; Tablet; rv:40.0) Gecko/40.0 Firefox/40.0 |

Android (version 41 and above)
------------------------------

Beginning in version 41, Firefox for Android will contain the Android version as part of the *platform* token. For increased interoperability, if the browser is running on a version below 4 it will report 4.4. Android versions 4 and above will report the version accurately. Note that the same Gecko—with the same capabilities—is shipped to all versions of Android.

| Form factor | Gecko user agent string |
| --- | --- |
| Phone | Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0 |
| Tablet | Mozilla/5.0 (Android 4.4; Tablet; rv:41.0) Gecko/41.0 Firefox/41.0 |

Focus for Android
-----------------

From version 1, Focus is powered by Android WebView and uses the following user agent string format:
```

Mozilla/5.0 (Linux; <Android Version> <Build Tag etc.>) AppleWebKit/<WebKit Rev> (KHTML, like Gecko) Version/4.0 Focus/<focusversion> Chrome/<Chrome Rev> Mobile Safari/<WebKit Rev>
```

Tablet versions on WebView mirror mobile, but do not contain a `Mobile` token.

Starting in Version 6, users can opt into using a GeckoView-based Focus for Android with a hidden preference: it uses a GeckoView UA string to advertise Gecko compatibility.

| Focus Version (Rendering Engine) | User Agent string |
| --- | --- |
| 1.0 (WebView Mobile) | Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/1.0 Chrome/59.0.3029.83 Mobile Safari/537.36 |
| 1.0 (WebView Tablet) | Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/1.0 Chrome/59.0.3029.83 Safari/537.36 |
| 6.0 (GeckoView) | Mozilla/5.0 (Android 7.0; Mobile; rv:62.0) Gecko/62.0 Firefox/62.0 |

Klar for Android
----------------

Since version 4.1, Klar for Android uses the same UA string as Focus for Android. Before version 4.1, it sent a *Klar/<version>* *product/version* token.

| Klar Version (Rendering Engine) | User Agent string |
| --- | --- |
| 1.0 (WebView) | Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Klar/1.0 Chrome/58.0.3029.83 Mobile Safari/537.36 |
| 4.1+ (WebView) | Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/4.1 Chrome/62.0.3029.83 Mobile Safari/537.36 |
| 6.0+ (GeckoView) | Mozilla/5.0 (Android 7.0; Mobile; rv:62.0) Gecko/62.0 Firefox/62.0 |

Focus for iOS
-------------

Version 7 of Focus for iOS uses a user agent string with the following format:
```

Mozilla/5.0 (iPhone; CPU iPhone OS 12_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/7.0.4 Mobile/16B91 Safari/605.1.15
```

Note: this user agent was retrieved from an iPhone XR simulator and may be different on device.

Firefox for Fire TV
-------------------

Version 3 (and probably earlier) of Firefox for Fire TV use a user agent string with the following format:
```

Mozilla/5.0 (Linux; <Android version>) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/<firefoxversion> Chrome/<Chrome Rev> Safari/<WebKit Rev>
```

| Firefox TV version | User Agent string |
| --- | --- |
| v3.0 | Mozilla/5.0 (Linux; Android 7.1.2) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/3.0 Chrome/59.0.3017.125 Safari/537.36 |

Firefox for Echo Show
---------------------

From version 1.1, Firefox for Echo Show uses a user agent string with the following format:
```

Mozilla/5.0 (Linux; <Android version>) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/<firefoxversion> Chrome/<Chrome Rev> Safari/<WebKit Rev>
```

| Firefox for Echo Show version | User agent string |
| --- | --- |
| v1.1 | Mozilla/5.0 (Linux; Android 5.1.1) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Focus/1.1 Chrome/59.0.3017.125 Safari/537.36 |

Firefox OS
----------

| Form factor | Gecko user agent string |
| --- | --- |
| Phone | Mozilla/5.0 (Mobile; rv:26.0) Gecko/26.0 Firefox/26.0 |
| Tablet | Mozilla/5.0 (Tablet; rv:26.0) Gecko/26.0 Firefox/26.0 |
| TV | Mozilla/5.0 (TV; rv:44.0) Gecko/44.0 Firefox/44.0 |
| Device-specific | Mozilla/5.0 (Mobile; ***nnnn;*** rv:26.0) Gecko/26.0 Firefox/26.0 |

### Device-specific user agent strings

Although it is **strongly discouraged** by Mozilla, some handset manufacturers unfortunately include a token in their device's UA string that represents their device id. If this is the case, the Firefox OS UA string will look like the device-specific string in the table above, where ***nnnn;*** is the manufacturer's code for the device (see Guidelines). Some of them we have noticed are of the form "**NexusOne;**", "**ZTEOpen;**", or "**Open C;**" (note that putting space is also discouraged). We provide this information to assist with your UA detection logic, but Mozilla discourages the detection of a device id in UA strings.

Here is a JavaScript regular expression that will detect all mobile devices, including devices with a device id in their UA string:

```js
/mobi/i;
```

The `i` makes it case-insensitive, and `mobi` matches all mobile browsers.

### Firefox OS version number

While the version number for Firefox OS is not included in the UA string, it is possible to infer version information from the Gecko version number present in the UA string.

| Firefox OS version number | Gecko version number |
| --- | --- |
| 1.0.1 | 18.0 |
| 1.1 | 18.1 |
| 1.2 | 26.0 |
| 1.3 | 28.0 |
| 1.4 | 30.0 |
| 2.0 | 32.0 |
| 2.1 | 34.0 |
| 2.2 | 37 |
| 2.5 | 44 |

**Note:** It's easy to find the correspondences by looking at the Mercurial repository names: repositories starting by `mozilla-b2g` are the release repositories for Firefox OS, and have both Firefox OS and Gecko versions in their names.

Firefox OS has a four-digit version number: `X.X.X.Y`. The first two digits are owned by the Mozilla product team and denote versions with new features (eg: v1.1, 1.2, etc.). The third digit is incremented with regular version tags (about every 6 weeks) for security updates, and the fourth is owned by the OEM.

See also
--------

* Recommendations on sniffing the UA string for cross-browser support
* window.navigator.userAgent


CORS errors - HTTP

CORS errors
===========

Cross-Origin Resource Sharing (CORS) is a standard that allows a server to relax the same-origin policy. This is used to explicitly allow some cross-origin requests while rejecting others. For example, if a site offers an embeddable service, it may be necessary to relax certain restrictions. Setting up such a CORS configuration isn't necessarily easy and may present some challenges. In these pages, we'll look into some common CORS error messages and how to resolve them.

If the CORS configuration isn't set up correctly, the browser console will present an error like `"Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at $somesite"` indicating that the request was blocked due to violating the CORS security rules. This might not necessarily be a set-up mistake, though. It's possible that the request is in fact intentionally being disallowed by the user's web application and remote external service. However, If the endpoint is meant to be available, some debugging is needed to succeed.

Identifying the issue
---------------------

To understand the underlying issue with the CORS configuration, you need to find out which request is at fault and why. These steps may help you do so:

1. Navigate to the website or web app in question and open the Developer Tools.
2. Now try to reproduce the failing transaction and check the console if you are seeing a CORS violation error message. It will probably look like this:

![Firefox console showing CORS error](/en-US/docs/Web/HTTP/CORS/Errors/cors-error2.png)

The text of the error message will be something similar to the following:
```

Cross-Origin Request Blocked: The Same Origin Policy disallows
reading the remote resource at https://some-url-here. (Reason:
additional information here).
```

**Note:** For security reasons, specifics about what went wrong with a CORS request *are not available to JavaScript code*. All the code knows is that an error occurred. The only way to determine what specifically went wrong is to look at the browser's console for details.

CORS error messages
-------------------

Firefox's console displays messages in its console when requests fail due to CORS. Part of the error text is a "reason" message that provides added insight into what went wrong. The reason messages are listed below; click the message to open an article explaining the error in more detail and offering possible solutions.

* Reason: CORS disabled
* Reason: CORS request did not succeed
* Reason: CORS header 'Origin' cannot be added
* Reason: CORS request external redirect not allowed
* Reason: CORS request not http
* Reason: CORS header 'Access-Control-Allow-Origin' missing
* Reason: CORS header 'Access-Control-Allow-Origin' does not match 'xyz'
* Reason: Credential is not supported if the CORS header 'Access-Control-Allow-Origin' is '\*'
* Reason: Did not find method in CORS header 'Access-Control-Allow-Methods'
* Reason: expected 'true' in CORS header 'Access-Control-Allow-Credentials'
* Reason: CORS preflight channel did not succeed
* Reason: invalid token 'xyz' in CORS header 'Access-Control-Allow-Methods'
* Reason: invalid token 'xyz' in CORS header 'Access-Control-Allow-Headers'
* Reason: missing token 'xyz' in CORS header 'Access-Control-Allow-Headers' from CORS preflight channel
* Reason: Multiple CORS header 'Access-Control-Allow-Origin' not allowed
See also
--------

* Glossary: CORS
* CORS introduction
* Server-side CORS settings
* CORS enabled image
* CORS settings attributes
* https://www.test-cors.org – page to test CORS requests


Reason: invalid token 'xyz' in CORS header 'Access-Control-Allow-Headers' - HTTP

Reason: invalid token 'xyz' in CORS header 'Access-Control-Allow-Headers'
=========================================================================

Reason
------
```

Reason: invalid token 'xyz' in CORS header 'Access-Control-Allow-Headers'
```

What went wrong?
----------------

 The response to the CORS request that was sent by the server includes
 an `Access-Control-Allow-Headers` header which includes at least one
 invalid header name.

 The `Access-Control-Allow-Headers` header is sent by the server in response
 to a preflight request; it lets the client know which HTTP headers are permitted in CORS requests.
 If the client user agent finds among the comma-delineated values
 provided by the header any header name it does not recognize, this error occurs.

 This is a problem that most likely can only be fixed on the server side, by modifying
 the server's configuration to no longer send the invalid or unknown header name with the
 `Access-Control-Allow-Headers` header. It may also be worth checking to
 ensure that the user agent or HTTP library you're using on the client is up-to-date.

See also
--------

* CORS errors
* Glossary: CORS
* CORS introduction
* HTTP headers


Reason: CORS header 'Access-Control-Allow-Origin' does not match 'xyz' - HTTP

Reason: CORS header 'Access-Control-Allow-Origin' does not match 'xyz'
======================================================================

Reason
------
```

Reason: CORS header 'Access-Control-Allow-Origin' does not match 'xyz'
```

What went wrong?
----------------

The origin making the request does not match the origin permitted by the `Access-Control-Allow-Origin` header. This error can also occur if the response includes more than one `Access-Control-Allow-Origin` header.

 If the service your code is accessing uses a CORS request under your control, make
 sure it is configured to include your origin in its `Access-Control-Allow-Origin` header. In addition, confirm that only one such header is
 included in responses, and that it includes only a single origin.

 For example, in Apache, add a line such as the following to the server's configuration
 (within the appropriate `<Directory>`, `<Location>`,
 `<Files>`, or `<VirtualHost>` section). The
 configuration is typically found in a `.conf` file (`httpd.conf`
 and `apache.conf` are common names for these), or in an
 `.htaccess` file.

**Warning:** You must include the HTTPS or HTTP protocol as part of the origin.

```apacheconf
Header set Access-Control-Allow-Origin 'origin'
```

For Nginx, the command to set up this header is:

```nginx
add_header 'Access-Control-Allow-Origin' 'origin'
```

See also
--------

* CORS errors
* Glossary: CORS
* CORS introduction
* Enable CORS: I want to add CORS support to my server


Reason: CORS request not HTTP - HTTP

Reason: CORS request not HTTP
=============================

Reason
------
```

Reason: CORS request not HTTP
```

What went wrong?
----------------

CORS requests may only use the HTTP or HTTPS URL scheme, but the URL specified by the request is of a different type.
 This often occurs if the URL specifies a local file, using the `file:///` scheme.

To fix this problem, make sure you use HTTPS URLs when issuing requests involving CORS, such as `fetch()`, `XMLHttpRequest`, Web Fonts (`@font-face`), and WebGL textures, and XSL stylesheets.

### Loading a local file

 Local files from the same directory and subdirectories were historically treated as being from the same origin.
 This meant that a file and all its resources could be loaded from a local directory or subdirectory during testing, without triggering a CORS error.

 Unfortunately this had security implications, as noted in this advisory: CVE-2019-11730.
 Many browsers, including Firefox and Chrome, now treat all local files as having *opaque origins* (by default).
 As a result, loading a local file with included local resources will now result in CORS errors.

 Developers who need to perform local testing should now set up a local server.
 As all files are served from the same scheme and domain (`localhost`) they all have the same origin, and do not trigger cross-origin errors.

**Note:** This change is in line with the URL specification, which leaves the origin behavior for files to the implementation, but recommends that file origins are treated as opaque if in doubt.

See also
--------

* CORS errors
* CORS introduction
* What is a URL?


Reason: Credential is not supported if the CORS header 'Access-Control-Allow-Origin' is '*' - HTTP

Reason: Credential is not supported if the CORS header 'Access-Control-Allow-Origin' is '\*'
============================================================================================

Reason
------
```

Reason: Credential is not supported if the CORS header 'Access-Control-Allow-Origin' is '*'
```

What went wrong?
----------------

The CORS request was attempted with the credentials flag set, but the server is configured using the wildcard (`"*"`) as the value of `Access-Control-Allow-Origin`, which doesn't allow the use of credentials.

To correct this problem on the client side, ensure that the credentials flag's value is `false` when issuing your CORS request.

* If using the Fetch API, make sure `Request.credentials` is `"omit"`.
* If the request is being issued using `XMLHttpRequest`, make sure you're not setting `withCredentials` to `true`.
* If using Server-sent events, make sure `EventSource.withCredentials` is `false` (it's the default value).

If, instead, you need to adjust the server's behavior, you'll need to change the value of `Access-Control-Allow-Origin` to grant access to the origin from which the client is loaded.

See also
--------

* CORS errors
* Glossary: CORS
* CORS introduction


Reason: expected 'true' in CORS header 'Access-Control-Allow-Credentials' - HTTP

Reason: expected 'true' in CORS header 'Access-Control-Allow-Credentials'
=========================================================================

Reason
------
```

Reason: expected 'true' in CORS header 'Access-Control-Allow-Credentials'
```

What went wrong?
----------------

 The CORS request requires that the server permit the use of
 credentials, but the server's `Access-Control-Allow-Credentials`
 header's value isn't set to `true` to enable their use.

 To fix this problem on the client side, revise the code to not request the use of
 credentials.

* If using the Fetch API, make sure
 `Request.credentials` is `"omit"`.
* If the request is being issued using `XMLHttpRequest`, make sure you're
 not setting `withCredentials` to
 `true`.
* If using Server-sent events,
 make sure `EventSource.withCredentials` is `false` (it's the
 default value).

 To eliminate this error by changing the server's configuration, adjust the server's
 configuration to set the `Access-Control-Allow-Credentials` header's value to
 `true`.

See also
--------

* CORS errors
* Glossary: CORS
* CORS introduction


Reason: CORS preflight channel did not succeed - HTTP

Reason: CORS preflight channel did not succeed
==============================================

Reason
------
```

Reason: CORS preflight channel did not succeed
```

What went wrong?
----------------

 The CORS request requires preflight, preflighting could not be
 performed. There are a couple of reasons why preflighting might fail:

* A cross-site request has previously been performed that already did a preflight, and
 doing the preflight again is not permitted. Make sure your code only preflights once
 per connection.
* The preflight request suffered any kind of networking error that might ordinarily
 occur.
See also
--------

* CORS errors
* Glossary: CORS
* CORS introduction


Reason: missing token 'xyz' in CORS header 'Access-Control-Allow-Headers' from CORS preflight channel - HTTP

Reason: missing token 'xyz' in CORS header 'Access-Control-Allow-Headers' from CORS preflight channel
=====================================================================================================

Reason
------
```

Reason: missing token 'xyz' in CORS header 'Access-Control-Allow-Headers' from CORS preflight channel
```

What went wrong?
----------------

The `Access-Control-Allow-Headers` header is sent by the server to let the client know which headers it supports for CORS requests. The value of `Access-Control-Allow-Headers` should be a comma-delineated list of header names, such as "`X-Custom-Information`" or any of the standard but non-basic header names (which are always allowed).

This error occurs when attempting to preflight a header that is not expressly allowed (that is, it's not included in the list specified by the `Access-Control-Allow-Headers` header sent by the server). To fix this, the server needs to be updated so that it allows the indicated header, or you need to avoid using that header.

See also
--------

* CORS errors
* Glossary: CORS
* CORS introduction
* HTTP headers


Reason: Did not find method in CORS header 'Access-Control-Allow-Methods' - HTTP

Reason: Did not find method in CORS header 'Access-Control-Allow-Methods'
=========================================================================

Reason
------
```

Reason: Did not find method in CORS header 'Access-Control-Allow-Methods'
```

What went wrong?
----------------

 The HTTP method being used by the CORS request is not included in the
 list of methods specified by the response's
 `Access-Control-Allow-Methods` header. This header specifies a
 comma-delimited list of the HTTP methods which may be used when using CORS to access
 the URL specified in the request; if the request is using any other method, this error
 occurs.

For example, if the response includes:

```http
Access-Control-Allow-Methods: GET,HEAD,POST
```

Trying to use a `PUT` request will fail with this error.

Make sure your code only uses the permitted HTTP methods when accessing the service.

**Note:** If the server includes any unrecognized or undefined method names in its `Access-Control-Allow-methods` header, a different error occurs: `Reason: invalid token 'xyz' in CORS header 'Access-Control-Allow-Methods'`.

See also
--------

* CORS errors
* Glossary: CORS
* CORS introduction
* HTTP request methods


Reason: Multiple CORS header 'Access-Control-Allow-Origin' not allowed - HTTP

Reason: Multiple CORS header 'Access-Control-Allow-Origin' not allowed
======================================================================

Reason
------
```

Reason: Multiple CORS header 'Access-Control-Allow-Origin' not allowed
```

What went wrong?
----------------

 More than one `Access-Control-Allow-Origin` header was sent by the
 server. This isn't allowed.

 If you have access to the server you can change your implementation to echo back an
 origin in the `Access-Control-Allow-Origin` header. You cannot send back a
 list of origins, because browsers only accept a value that is either a single origin or
 null

See also
--------

* CORS errors
* Glossary: CORS
* CORS introduction
* Enable CORS: I want to add CORS support to my server


Reason: CORS request external redirect not allowed - HTTP

Reason: CORS request external redirect not allowed
==================================================

Reason
------
```

Reason: CORS request external redirect not allowed
```

What went wrong?
----------------

 The CORS request was responded to by the server with an HTTP redirect
 to a URL on a different origin than the original request, which is not permitted during
 CORS requests.

 For example, if the page `https://service.tld/fetchdata` were requested, and
 the HTTP response is "301 Moved Permanently", "307 Temporary Redirect", or "308
 Permanent Redirect" with a `Location` of
 `https://anotherservice.net/getdata`, the CORS request will fail in this
 manner.

 To fix the problem, update your code to use the new URL as reported by the redirect,
 thereby avoiding the redirect.

See also
--------

* CORS errors
* Glossary: CORS
* CORS introduction


Reason: invalid token 'xyz' in CORS header 'Access-Control-Allow-Methods' - HTTP

Reason: invalid token 'xyz' in CORS header 'Access-Control-Allow-Methods'
=========================================================================

Reason
------
```

Reason: invalid token 'xyz' in CORS header 'Access-Control-Allow-Methods'
```

What went wrong?
----------------

 The response to the CORS request that was sent by the server includes
 an `Access-Control-Allow-Methods` header which includes at least one
 invalid method name.

 The `Access-Control-Allow-Methods` header is sent by the server to let the
 client know what HTTP request methods it
 supports for CORS requests. The header's value is a comma-delineated string of HTTP
 method names, such as `GET`, `POST`, or
 `HEAD`. If any of the specified values are not recognized by the client
 user agent, this error occurs.

 This is a problem that most likely can only be fixed on the server side, by modifying
 the server's configuration to no longer send the invalid or unknown method name with the
 `Access-Control-Allow-Methods` header. It may also be worth checking to
 ensure that the user agent or HTTP library you're using on the client is up-to-date.

See also
--------

* CORS errors
* Glossary: CORS
* CORS introduction
* HTTP request methods


Reason: CORS header 'Access-Control-Allow-Origin' missing - HTTP

Reason: CORS header 'Access-Control-Allow-Origin' missing
=========================================================

Reason
------
```

Reason: CORS header 'Access-Control-Allow-Origin' missing
```

What went wrong?
----------------

 The response to the CORS request is missing the required
 `Access-Control-Allow-Origin` header, which is used to determine whether
 or not the resource can be accessed by content operating within the current origin.

 If the server is under your control, add the origin of the requesting site to the set
 of domains permitted access by adding it to the `Access-Control-Allow-Origin`
 header's value.

 For example, to allow a site at `https://example.com` to access the resource using CORS,
 the header should be:

```http
Access-Control-Allow-Origin: https://example.com
```

 You can also configure a site to allow any site to access it by using the
 `*` wildcard. You should only use this for public APIs. Private APIs should
 never use `*`, and should instead have a specific domain or domains set. In
 addition, the wildcard only works for requests made with the
 `crossorigin` attribute set to `anonymous`, and it prevents
 sending credentials like cookies in requests.

```http
Access-Control-Allow-Origin: \*
```

**Warning:** Using the wildcard to allow all sites to access a private
 API is a bad idea.

 To allow any site to make CORS requests *without* using the `*`
 wildcard (for example, to enable credentials), your server must read the value of the
 request's `Origin` header and use that value to set
 `Access-Control-Allow-Origin`, and must also set a `Vary: Origin`
 header to indicate that some headers are being set dynamically depending on the origin.

Examples for common web servers
-------------------------------

The exact directive for setting headers depends on your web server.

In the examples below,

 In **Apache** (docs), add a
 line such as the following to the server's configuration (within the appropriate
 `<Directory>`, `<Location>`,
 `<Files>`, or `<VirtualHost>` section). The
 configuration is typically found in a `.conf` file (`httpd.conf`
 and `apache.conf` are common names for these), or in an
 `.htaccess` file:

```apacheconf
Header set Access-Control-Allow-Origin 'https://example.com'
```

For **Nginx** (docs), the command to set up this header is:

```nginx
add\_header 'Access-Control-Allow-Origin' 'https://example.com' always;
```

See also
--------

* CORS errors
* Glossary: CORS
* CORS introduction


Reason: CORS request did not succeed - HTTP

Reason: CORS request did not succeed
====================================

Reason
------
```

Reason: CORS request did not succeed
```

What went wrong?
----------------

 The HTTP request which makes use of CORS failed because the HTTP
 connection failed at either the network or protocol level. The error is not directly
 related to CORS, but is a fundamental network error of some kind.

 In many cases, it is caused by a browser plugin (e.g. an ad blocker or privacy
 protector) blocking the request.

Other possible causes include:

* Trying to access an `https` resource that has an invalid certificate will
 cause this error.
* Trying to access an `http` resource from a page with an
 `https` origin will also cause this error.
* From Firefox 68 to Firefox 84, `https` pages were not permitted to access
 `http://localhost`. This has been changed with Bug 1488740.
* The server did not respond to the actual request (even if it responded to the
 Preflight request). One scenario might be an HTTP service being
 developed that panicked without returning any data.
See also
--------

* CORS errors
* Glossary: CORS
* CORS introduction


Reason: CORS header 'Origin' cannot be added - HTTP

Reason: CORS header 'Origin' cannot be added
============================================

Reason
------
```

Reason: CORS header 'Origin' cannot be added
```

What went wrong?
----------------

 The user agent was unable to add the required `Origin`
 header to the HTTP request. All CORS requests must have an
 `Origin` header.

 This can happen if the JavaScript code is running with enhanced privileges allowing it
 access to multiple domains' content, for example.

See also
--------

* CORS errors
* Glossary: CORS
* CORS introduction


Reason: CORS disabled - HTTP

Reason: CORS disabled
=====================

Reason
------
```

Reason: CORS disabled
```

What went wrong?
----------------

 A request that needs to use CORS was attempted, but CORS is disabled in
 the user's browser. When this happens, the user needs to turn CORS back on in their
 browser.

 In Firefox, the preference that disables CORS is `content.cors.disable`.
 Setting this to `true` disables CORS, so whenever that's the case, CORS
 requests will always fail with this error.

See also
--------

* CORS errors
* Glossary: CORS
* CORS introduction


Critical rendering path - Web performance

Critical rendering path
=======================

 The Critical Rendering Path is the sequence of steps the browser goes through to convert the HTML, CSS, and JavaScript into pixels on the screen. Optimizing the critical render path improves render performance.
 The critical rendering path includes the Document Object Model (DOM), CSS Object Model (CSSOM), render tree and layout.

The document object model is created as the HTML is parsed. The HTML may request JavaScript, which may, in turn, alter the DOM. The HTML includes or makes requests for styles, which in turn builds the CSS object model. The browser engine combines the two to create the Render Tree. Layout determines the size and location of everything on the page. Once layout is determined, pixels are painted to the screen.

Optimizing the critical rendering path improves the time to first render. Understanding and optimizing the critical rendering path is important to ensure reflows and repaints can happen at 60 frames per second, to ensure performant user interactions, and to avoid jank.

Understanding CRP
-----------------

Web performance includes the server requests and responses, loading, scripting, rendering, layout, and the painting of the pixels to the screen.

A request for a web page or app starts with an HTML request. The server returns the HTML - response headers and data. The browser then begins parsing the HTML, converting the received bytes to the DOM tree. The browser initiates requests every time it finds links to external resources, be it stylesheets, scripts, or embedded image references. Some requests are blocking, which means the parsing of the rest of the HTML is halted until the imported asset is handled. The browser continues to parse the HTML making requests and building the DOM, until it gets to the end, at which point it constructs the CSS object model. With the DOM and CSSOM complete, the browser builds the render tree, computing the styles for all the visible content. After the render tree is complete, layout occurs, defining the location and size of all the render tree elements. Once complete, the page is rendered, or 'painted' on the screen.

### Document Object Model

DOM construction is incremental. The HTML response turns into tokens which turns into nodes which turn into the DOM Tree. A single DOM node starts with a startTag token and ends with an endTag token. Nodes contain all relevant information about the HTML element. The information is described using tokens. Nodes are connected into a DOM tree based on token hierarchy. If another set of startTag and endTag tokens come between a set of startTag and endTags, you have a node inside a node, which is how we define the hierarchy of the DOM tree.

The greater the number of nodes, the longer the following events in the critical rendering path will take. Measure! A few extra nodes won't make a big difference, but keep in mind that adding many extra nodes will impact performance.

### CSS Object Model

The DOM contains all the content of the page. The CSSOM contains all the information on how to style the DOM. CSSOM is similar to the DOM, but different. While the DOM construction is incremental, CSSOM is not. CSS is render blocking: the browser blocks page rendering until it receives and processes all the CSS. CSS is render blocking because rules can be overwritten, so the content can't be rendered until the CSSOM is complete.

CSS has its own set of rules for identifying valid tokens. Remember the C in CSS stands for 'Cascade'. CSS rules cascade down. As the parser converts tokens to nodes, descendant nodes will inherit some of the styles of the parent. The incremental processing features don't apply to CSS like they do with HTML, because subsequent rules may override previous ones. The CSS object model gets built as the CSS is parsed, but can't be used to build the render tree until it is completely parsed because styles that are going to be overwritten with later parsing should not be rendered to the screen.

In terms of selector performance, less specific selectors are faster than more specific ones. For example, `.foo {}` is faster than `.bar .foo {}` because when the browser finds `.foo`, in the second scenario, it has to walk up the DOM to check if `.foo` has an ancestor `.bar`. The more specific tag requires more work from the browser, but this penalty is not likely worth optimizing around.

If you measure the time it takes to parse CSS, you'll be amazed at how fast browsers truly are. The more specific rule is more expensive because it has to traverse more nodes in the DOM tree - but that extra expense is generally minimal. Measure first. Optimize as needed. Specificity is likely not your lowest hanging fruit. When it comes to CSS, selector performance optimization improvements will only be in microseconds. There are other ways to optimize CSS, such as minification, and separating deferred CSS into non-blocking requests by using media queries.

### Render Tree

The render tree captures both the content and the styles: the DOM and CSSOM trees are combined into the render tree. To construct the render tree, the browser checks every node, starting from root of the DOM tree, and determines which CSS rules are attached.

The render tree only captures visible content. The head section (generally) doesn't contain any visible information, and is therefore not included in the render tree. If there's a `display: none;` set on an element, neither it, nor any of its descendants, are in the render tree.

### Layout

Once the render tree is built, layout becomes possible. Layout is dependent on the size of screen. The layout step determines where and how the elements are positioned on the page, determining the width and height of each element, and where they are in relation to each other.

What is the width of an element? Block level elements, by definition, have a default width of 100% of the width of their parent. An element with a width of 50%, will be half of the width of its parent. Unless otherwise defined, the body has a width of 100%, meaning it will be 100% of the width of the viewport. This width of the device impacts layout.

The viewport meta tag defines the width of the layout viewport, impacting the layout. Without it, the browser uses the default viewport width, which on by-default full screen browsers is generally 960px. On by-default full screen browsers, like your phone's browser, by setting `<meta name="viewport" content="width=device-width">`, the width will be the width of the device instead of the default viewport width. The device-width changes when a user rotates their phone between landscape and portrait mode. Layout happens every time a device is rotated or browser is otherwise resized.

Layout performance is impacted by the DOM — the greater the number of nodes, the longer layout takes. Layout can become a bottleneck, leading to jank if required during scrolling or other animations. While a 20ms delay on load or orientation change may be fine, it will lead to jank on animation or scroll. Any time the render tree is modified, such as by added nodes, altered content, or updated box model styles on a node, layout occurs.

To reduce the frequency and duration of layout events, batch updates and avoid animating box model properties.

### Paint

The last step is painting the pixels to the screen. Once the render tree is created and layout occurs, the pixels can be painted to the screen. On load, the entire screen is painted. After that, only impacted areas of the screen will be repainted, as browsers are optimized to repaint the minimum area required. Paint time depends on what kind of updates are being applied to the render tree. While painting is a very fast process, and therefore likely not the most impactful place to focus on in improving performance, it is important to remember to allow for both layout and re-paint times when measuring how long an animation frame may take. The styles applied to each node increase the paint time, but removing style that increases the paint by 0.001ms may not give you the biggest bang for your optimization buck. Remember to measure first. Then you can determine whether it should be an optimization priority.

Optimizing for CRP
------------------

Improve page load speed by prioritizing which resources get loaded, controlling the order in which they are loaded, and reducing the file sizes of those resources. Performance tips include 1) minimizing the number of critical resources by deferring non-critical ones' download, marking them as async, or eliminating them altogether, 2) optimizing the number of requests required along with the file size of each request, and 3) optimizing the order in which critical resources are loaded by prioritizing the downloading of critical assets, thereby shortening the critical path length.


Optimizing startup performance - Web performance

Optimizing startup performance
==============================

Improving your startup performance is often one of the highest value performance optimizations that can be made. How long does your app take to start up? Does it seem to lock up the device or the user's browser while the app loads? That makes users worry that your application has crashed, or that something else is wrong. Good user experience includes ensuring your app loads quickly. This article provides performance tips and suggestions for both writing new applications and porting applications to the web from other platforms.

Fast asynchronous loading
-------------------------

Regardless of platform, it's always a good idea to start up as **quickly** as possible. Since that's a universal issue, we won't be focusing on it too much here. Instead, we're going to look at a more important issue when building Web apps: starting up as **asynchronously** as possible. That means not running all your startup code in a single event handler on the app's main thread.

Rather, create a Web worker that does as much as possible in a background thread (for example, fetching and processing data.) Relegating tasks to a Web worker frees up the main thread for tasks requiring it, like user events and rendering UI. In turn, main thread events should consist of many small tasks, also known as micro tasks, rather than larger, more time consuming tasks.

Asynchronous loading helps prevent pages and user interfaces from appearing to be (or actually becoming) unresponsive. By minimizing the time required for any individual loading task, the application's event loop will continue to cycle while it starts up. This will prevent the application, browser, and/or device from appearing frozen.

In the worst case, blocking the main thread can cause users to uninstall your app; for example, if someone launches your app by mistake and they aren't prevented from closing the application, they may want to take action so that doesn't accidentally happen again.

Where there's a will…
---------------------

It is easier to just write everything the "right way" the first time then it is to retrofit for performance (and accessibility). When you are starting from scratch, making appropriate bits of code asynchronous means a retrofit isn't necessary. All pure startup calculations should be performed in background threads, while you keep the run-time of main thread events as short as possible. Instead of including a progress indicator so the user knows what's going on and how long they'll be waiting, make the progress bar unnecessary.

On the other hand, porting an existing app to the Web can be challenging. Native application don't need to be written in an asynchronous fashion because the operating system usually handles loading for you. The source application might have a main loop that can easily be made to operate asynchronously (by running each main loop iteration separately); startup is often just a continuous, monolithic procedure that might periodically update a progress meter.

While you can use Web workers to run even very large, long-duration chunks of JavaScript code asynchronously, there's a huge caveat: Web workers can't directly manipulate the DOM and have limited access to methods and properties of the window object, including no access to WebGL. This all means that unless you can easily pull out the "pure calculation" chunks of your startup process into workers, you'll wind up having to run most or all of your startup code on the main thread.

However, even code like that can be made asynchronous, with a little work.

Getting asynchronous
--------------------

Here are some suggestions for how to build your startup process to be as asynchronous as possible (whether it's a new app or a port):

* Use the `defer` or `async` attribute on script tags needed by the Web application. This allows HTML parsers to continue processing the document, instead of having to wait until the scripts have been downloaded and executed before continuing.
* If you need to decode asset files (for example, decoding JPEG files and turning them into raw texture data for later use by WebGL), that's great to do in workers.
* When dealing with data supported by the browser (for example, decoding image data), use the decoders built into the browser or device rather than rolling your own or using one from the original codebase. The provided one is almost certainly significantly faster, and will reduce your app size to boot. In addition, the browser may automatically parallelize these decoders.
* Any data processing that can be done in parallel should be. Don't do one chunk of data after another; do them all at once when possible!
* Don't include scripts or stylesheets that don't participate in the critical rendering path in your startup HTML file. Load them only when needed.
* Reduce the size of your JavaScript files. Try to send the minified version of the file to the browser and use compression like Gzip or Brotli.
* Utilize resource hints (like preconnect or preload) whenever possible to indicate to the browser which files are more critical for your application.

The more stuff you can do asynchronously, the better advantage your app can take of multicore processors.

### Porting issues

Once the initial loading is done and the app's main code starts to run, it's possible your app has to be single-threaded, especially if it's a port. The most important thing to do to try to help with the main code's startup process is to refactor the code into small pieces. These can then be executed in chunks interspersed across multiple calls to your app's main loop (so that the main thread gets to handle input and the like).

Emscripten provides an API to help with this refactoring; for example, you can use `emscripten_push_main_loop_blocker()` to establish a function to be executed before the main thread is allowed to continue. By establishing a queue of functions to be called in sequence, you can more easily manage running bits of code without blocking the main thread.

That leaves, though, the problem of having to refactor your existing code to actually work that way. That can take some time.

### How asynchronous should I get?

 The faster your site first becomes usable and the more responsive it is to user input, the better it will be perceived.
 A site that takes 1 or 2 seconds before content first appears is usually seen as fast; if you're used to sites taking 3 or 4 seconds, then 7 or 8 seconds feels like a very long time.

In terms of responsiveness, users won't notice a delay of 50ms or less. Any delay of over 200ms and the user will perceive your site as sluggish. When working to improve the loading and responsiveness of your applications, remember that many of your users may have older, slower computer than yours, they may experience longer delays than you do!

Other suggestions
-----------------

There are other things beyond going asynchronous, which can help you improve your app's startup time. Here are a few of them:

Download time

Keep in mind how long it will take the user to download your application's data. If your application is very popular, or has to re-download content frequently, you should try to have as fast a hosting server as possible. Always compress your data to make it as small as you can.

Data size

Do your best to optimize the size of your data; smaller level files will download and be processed faster than larger ones.

Subjective factors

Anything you can do to help keep the user engaged during the startup process will help make the time seem to go by faster. Displaying a mock splash screen can improve perceived performance. For heavy sites, anything you can do to help the user feel like your app is doing something instead of sitting there quietly helps.

See also
--------

* Apps
* Games
* BananaBread (or any compiled codebase) Startup Experience (2012)


Recommended Web Performance Timings: How long is too long? - Web performance

Recommended Web Performance Timings: How long is too long?
==========================================================

There are no clear set rules as to what constitutes a slow pace when loading pages, but there are specific guidelines for indicating content will load (1 second), idling (50ms), animating (16.7ms) and responding to user input (50 to 200ms).

Load goal
---------

The 'Under a second' is often touted as optimal for load, but what does that mean? A second should be considered a rule in the maximum amount of time to indicate to a user that the request for new content was made and will load, such as the browser displaying the page title and the background color of the page displaying.

The first asset retrieved from a request is usually an HTML document, which then makes calls for additional assets. As noted in the description of the critical rendering path, when received, browsers immediately start processing the HTML, rendering the content as it is received rather than waiting for additional assets to load.

Yes, one second for loading is a goal, but it's something few sites achieve. Expectations differ. A 'hello world' on the corporate network would be expected to load in milliseconds, but a user downloading a cat video on a five-year-old device over an edge network in northern Siberia would likely find a 20-second download speedy. If you wait three or four seconds without communicating to the user that a load is happening and showing some progress, the typical site will lose potential visitors, and those visitors will take a long time to come back if they ever do.

In optimizing for performance, do set an ambitious first load goal, such as 5 seconds over the mobile 3G network and 1.5 seconds on an office T1 line, with even more ambitious page load goals for subsequent page loads, leveraging service workers and caching. There are different suggested times for initially loading the page versus loading additional assets, responding to user interaction, and ensuring smooth animations:

Idling goal
-----------

Browsers are single threaded (though background threads are supported for web workers). This means that user interaction, painting, and script execution are all on the same thread. If the thread is busy doing complex JavaScript execution, the main thread will not be available to react to user input, such as pressing a button. For this reason, script execution should be limited in scope, divided into chunks of code that can be executed in 50ms or less. This makes the thread available for user interactions.

Animation goal
--------------

For scrolling and other animations to look smooth and feel responsive, the content repaints should occur at 60 frames per second (60fps), which is once every 16.7ms. The 16.7 milliseconds includes scripting, reflow, and repaint. Realize a document takes about 6ms to render a frame, leaving about 10ms for the rest. Anything less than 60fps, especially an un-even or changing frame rate, will appear janky.

Responsiveness goal
-------------------

When the user interacts with content, it is important to provide feedback and acknowledge the user's response or interaction and to do so within 100ms, preferably within 50ms. 50ms seconds feels immediate. The acknowledgment of user interaction should often feel immediate, such as a hover or button press, but that doesn't mean the completed response should be instantaneous. While a slower than 100ms reaction may create a disconnect between the user interaction and the response, a 100 to 200ms transition for a response may help the user notice the response their interaction initiated, such as a menu opening. If a response takes longer than 100ms to complete, provide some form of feedback to inform the user the interaction has occurred.


Performance fundamentals - Web performance

Performance fundamentals
========================

Performance means efficiency. In the context of Open Web Apps, this document explains in general what performance is, how the browser platform helps improve it, and what tools and processes you can use to test and improve it.

What is performance?
--------------------

Ultimately, user-perceived performance is the only performance that matters. Users provide inputs to the system through touch, movement, and speech. In return, they perceive outputs through sight, touch, and hearing. Performance is the quality of system outputs in response to user inputs.

All other things being equal, code optimized for some target besides user-perceived performance (hereafter UPP) loses when competing against code optimized for UPP. Users prefer, say, a responsive, smooth app that only processes 1,000 database transactions per second, over a choppy, unresponsive app that processes 100,000,000 per second. Of course, it's by no means pointless to optimize other metrics, but real UPP targets come first.

The next few subsections point out and discuss essential performance metrics.

### Responsiveness

Responsiveness means how fast the system provides outputs (possibly multiple ones) in response to user inputs. For example, when a user taps the screen, they expect the pixels to change in a certain way. For this interaction, the responsiveness metric is the time elapsed between the tap and the pixel change.

Responsiveness sometimes involves multiple stages of feedback. Application launch is one particularly important case discussed in more detail below.

Responsiveness is important because people get frustrated and angry when they're ignored. Your app is ignoring the user every second that it fails to respond to the user's input.

### Frame rate

Frame rate is the rate at which the system changes pixels displayed to the user. This is a familiar concept: everyone prefers, say, games that display 60 frames per second over ones that display 10 frames per second, even if they can't explain why.

Frame rate is important as a "quality of service" metric. Computer displays are designed to "fool" user's eyes, by delivering photons to them that mimic reality. For example, paper covered with printed text reflects photons to the user's eyes in some pattern. By manipulating pixels, a reader app emits photons in a similar pattern to "fool" the user's eyes.

As your brain infers, motion is not jerky and discrete, but rather "updates" smoothly and continuously. (Strobe lights are fun because they turn that upside down, starving your brain of inputs to create the illusion of discrete reality). On a computer display, a higher frame rate makes for a more faithful imitation of reality.

**Note:** Humans usually cannot perceive differences in frame rate above 60Hz. That's why most modern electronic displays are designed to refresh at that rate. A television probably looks choppy and unrealistic to a hummingbird, for example.

### Memory usage

**Memory usage** is another key metric. Unlike responsiveness and frame rate, users don't directly perceive memory usage, but memory usage closely approximates "user state". An ideal system would maintain 100% of user state at all times: all applications in the system would run simultaneously, and all applications would retain the state created by the user the last time the user interacted with the application (application state is stored in computer memory, which is why the approximation is close).

From this comes an important but counter-intuitive corollary: a well-designed system does not maximize the amount of **free** memory. Memory is a resource, and free memory is an unused resource. Rather, a well-designed system has been optimized to **use** as much memory as possible to maintain user state, while meeting other UPP goals.

That doesn't mean the system should **waste** memory. When a system uses more memory than necessary to maintain some particular user state, the system is wasting a resource it could use to retain some other user state. In practice, no system can maintain all user states. Intelligently allocating memory to user state is an important concern that we go over in more detail below.

### Power usage

The final metric discussed here is **power usage**. Like memory usage, users perceive power usage only indirectly, by how long their devices can maintain all other UPP goals. In service of meeting UPP goals, the system must use only the minimum power required.

The remainder of this document will discuss performance in terms of these metrics.

Platform performance optimizations
----------------------------------

This section provides a brief overview of how Firefox/Gecko contributes to performance generally, below the level of all applications. From a developer's or user's perspective, this answers the question, "What does the platform do for you?"

### Web technologies

The Web platform provides many tools, some better suited for particular jobs than others. All application logic is written in JavaScript. To display graphics, developers can use HTML or CSS (i.e. high-level declarative languages), or use low-level imperative interfaces offered by the `<canvas>` element (which includes WebGL). Somewhere "in between" HTML/CSS and Canvas is SVG, which offers some benefits of both.

HTML and CSS greatly increase productivity, sometimes at the expense of frame rate or pixel-level control over rendering. Text and images reflow automatically, UI elements automatically receive the system theme, and the system provides "built-in" support for some use cases developers may not think of initially, like different-resolution displays or right-to-left languages.

The `canvas` element offers a pixel buffer directly for developers to draw on. This gives developers pixel-level control over rendering and precise control of frame rate, but now the developers need to deal with multiple resolutions and orientations, right-to-left languages, and so forth. Developers draw to canvases using either a familiar 2D drawing API, or WebGL, a "close to the metal" binding that mostly follows OpenGL ES 2.0.

### Gecko rendering

The Gecko JavaScript engine supports just-in-time (JIT) compilation. This enables application logic to perform comparably to other virtual machines — such as Java virtual machines — and in some cases even close to "native code".

The graphics pipeline in Gecko that underpins HTML, CSS, and Canvas is optimized in several ways. The HTML/CSS layout and graphics code in Gecko reduces invalidation and repainting for common cases like scrolling; developers get this support "for free". Pixel buffers painted by both Gecko "automatically" and applications to `canvas` "manually" minimize copies when being drawn to the display framebuffer. This is done by avoiding intermediate surfaces where they would create overhead (such as per-application "back buffers" in many other operating systems), and by using special memory for graphics buffers that can be directly accessed by the compositor hardware. Complex scenes are rendered using the device's GPU for maximum performance. To improve power usage, simple scenes are rendered using special dedicated composition hardware, while the GPU idles or turns off.

Fully static content is the exception rather than the rule for rich applications. Rich applications use dynamic content with `animation` and `transition` effects. Transitions and animations are particularly important to applications: developers can use CSS to declare complicated behavior with a simple, high-level syntax. In turn, Gecko's graphics pipeline is highly optimized to render common animations efficiently. Common-case animations are "offloaded" to the system compositor, which can render them in a performant, power-efficient fashion.

An app's startup performance matters just as much as its runtime performance. Gecko is optimized to load a wide variety of content efficiently: the entire Web! Many years of improvements targeting this content, like parallel HTML parsing, intelligent scheduling of reflows and image decoding, clever layout algorithms, etc., translate just as well to improving Web applications on Firefox.

Application performance
-----------------------

This section is intended for developers asking the question: "How can I make my app fast"?

### Startup performance

Application startup is punctuated by three user-perceived events, generally speaking:

* The first is the application **first paint** — the point at which sufficient application resources have been loaded to paint an initial frame
* The second is when the application becomes **interactive** — for example, users are able to tap a button and the application responds
* The final event is **full load** — for example when all the user's albums have been listed in a music player

The key to fast startup is to keep two things in mind: UPP is all that matters, and there's a "critical path" to each user-perceived event above. The critical path is exactly and only the code that must run to produce the event.

For example, to paint an application's first frame that comprises visually some HTML and CSS to style that HTML:

1. The HTML must be parsed
2. The DOM for that HTML must be constructed
3. Resources like images in that part of the DOM have to be loaded and decoded
4. The CSS styles must be applied to that DOM
5. The styled document has to be reflowed

Nowhere in that list is "load the JS file needed for an uncommon menu"; "fetch and decode the image for the High Scores list", etc. Those work items are not on the critical path to painting the first frame.

It seems obvious, but to reach a user-perceived startup event more quickly, the main "trick" is run *only the code on the critical path.* Shorten the critical path by simplifying the scene.

The Web platform is highly dynamic. JavaScript is a dynamically-typed language, and the Web platform allows loading code, HTML, CSS, images, and other resources dynamically. These features can be used to defer work that's off the critical path by loading unnecessary content "lazily" some time after startup.

Another problem that can delay startup is idle time, caused by waiting for responses to requests (like database loads). To avoid this problem, applications should issue requests as early as possible in startup (this is called "front-loading"). Then when the data is needed later, hopefully it's already available and the application doesn't have to wait.

**Note:** For much more information on improving startup performance, read Optimizing startup performance.

On the same note, notice that locally-cached, static resources can be loaded much faster than dynamic data fetched over high-latency, low-bandwidth mobile networks. Network requests should never be on the critical path to early application startup. Local caching/offline apps can be achieved via Service Workers. See Offline and background operation for a guide about using service workers for offline and background sync capabilities.

### Frame rate

The first important thing for high frame rate is to choose the right tool. Use HTML and CSS to implement content that's mostly static, scrolled, and infrequently animated. Use Canvas to implement highly dynamic content, like games that need tight control over rendering and don't need theming.

For content drawn using Canvas, it's up to the developer to hit frame rate targets: they have direct control over what's drawn.

For HTML and CSS content, the path to high frame rate is to use the right primitives. Firefox is highly optimized to scroll arbitrary content; this is usually not a concern. But often trading some generality and quality for speed, such as using a static rendering instead of a CSS radial gradient, can push scrolling frame rate over a target. CSS media queries allow these compromises to be restricted only to devices that need them.

Many applications use transitions or animations through "pages", or "panels". For example, the user taps a "Settings" button to transition into an application configuration screen, or a settings menu "pops up". Firefox is highly optimized to transition and animate scenes that:

* use pages/panels approximately the size of the device screen or smaller
* transition/animate the CSS `transform` and `opacity` properties

Transitions and animations that adhere to these guidelines can be offloaded to the system compositor and run maximally efficiently.

### Memory and power usage

Improving memory and power usage is a similar problem to speeding up startup: don't do unneeded work or lazily load uncommonly-used UI resources. Do use efficient data structures and ensure resources like images are optimized well.

Modern CPUs can enter a lower-power mode when mostly idle. Applications that constantly fire timers or keep unnecessary animations running prevent CPUs from entering low-power mode. Power-efficient applications shouldn't do that.

When applications are sent to the background, a `visibilitychange` event is fired on their documents. This event is a developer's friend; applications should listen for it.

### Specific coding tips for application performance

The following practical tips will help improve one or more of the Application performance factors discussed above.

#### Use CSS animations and transitions

Instead of using some library's `animate()` function, which probably currently uses many badly performing technologies (`setTimeout()` or `top`/`left` positioning, for example) use CSS animations. In many cases, you can actually use CSS Transitions to get the job done. This works well because the browser is designed to optimize these effects and use the GPU to handle them smoothly with minimal impact on processor performance. Another benefit is that you can define these effects in CSS along with the rest of your app's look-and-feel, using a standardized syntax.

CSS animations give you very granular control over your effects using keyframes, and you can even watch events fired during the animation process in order to handle other tasks that need to be performed at set points in the animation process. You can easily trigger these animations with the `:hover`, `:focus`, or `:target`, or by dynamically adding and removing classes on parent elements.

If you want to create animations on the fly or modify them in JavaScript, James Long has written a simple library for that called CSS-animations.js.

#### Use CSS transforms

Instead of tweaking absolute positioning and fiddling with all that math yourself, use the `transform` CSS property to adjust the position, scale, and so forth of your content. Alternatively, you can use the individual transformation properties of `translate`, `scale`, and `rotate`. The reason is, once again, hardware acceleration. The browser can do these tasks on your GPU, letting the CPU handle other things.

In addition, transforms give you capabilities you might not otherwise have. Not only can you translate elements in 2D space, but you can transform in three dimensions, skew and rotate, and so forth. Paul Irish has an in-depth analysis of the benefits of `translate()` (2012) from a performance point of view. In general, however, you have the same benefits you get from using CSS animations: you use the right tool for the job and leave the optimization to the browser. You also use an easily extensible way of positioning elements — something that needs a lot of extra code if you simulate translation with `top` and `left` positioning. Another bonus is that this is just like working in a `canvas` element.

**Note:** You may need to attach a `translateZ(0.1)` transform if you wish to get hardware acceleration on your CSS animations, depending on platform. As noted above, this can improve performance. When overused, it can have memory consumption issues. What you do in this regard is up to you — do some testing and find out what's best for your particular app.

#### Use `requestAnimationFrame()` instead of `setInterval()`

Calls to `setInterval()` run code at a presumed frame rate that may or may not be possible under current circumstances. It tells the browser to render results even while the browser isn't actually drawing; that is, while the video hardware hasn't reached the next display cycle. This wastes processor time and can even lead to reduced battery life on the user's device.

Instead, you should try to use `window.requestAnimationFrame()`. This waits until the browser is actually ready to start building the next frame of your animation, and won't bother if the hardware isn't going to actually draw anything. Another benefit to this API is that animations won't run while your app isn't visible on the screen (such as if it's in the background and some other task is operating). This will save battery life and prevent users from cursing your name into the night sky.

#### Make events immediate

As old-school, accessibility-aware Web developers we love click events since they also support keyboard input. On mobile devices, these are too slow. You should use `touchstart` and `touchend` instead. The reason is that these don't have a delay that makes the interaction with the app appear sluggish. If you test for touch support first, you don't sacrifice accessibility, either. For example, the Financial Times uses a library called fastclick for that purpose, which is available for you to use.

#### Keep your interface simple

One big performance issue we found in HTML apps was that moving lots of DOM elements around makes everything sluggish — especially when they feature lots of gradients and drop shadows. It helps a lot to simplify your look-and-feel and move a proxy element around when you drag and drop.

When, for example, you have a long list of elements (let's say tweets), don't move them all. Instead, keep in your DOM tree only the ones that are visible and a few on either side of the currently visible set of tweets. Hide or remove the rest. Keeping the data in a JavaScript object instead of accessing the DOM can vastly improve your app's performance. Think of the display as a presentation of your data rather than the data itself. That doesn't mean you can't use straight HTML as the source; just read it once and then scroll 10 elements, changing the content of the first and last accordingly to your position in the results list, instead of moving 100 elements that aren't visible. The same trick applies in games to sprites: if they aren't currently on the screen, there is no need to poll them. Instead, re-use elements that scroll off-screen as new ones coming in.

General application performance analysis
----------------------------------------

Firefox, Chrome, and other browsers include built-in tools that can help you diagnose slow page rendering. In particular, Firefox's Network Monitor will display a precise timeline of when each network request on your page happens, how large it is, and how long it takes.

![The Firefox network monitor showing get requests, multiple files, and different times taken to load each resource on a graph.](/en-US/docs/Web/Performance/Fundamentals/network-monitor.jpg)

If your page contains JavaScript code that is taking a long time to run, the JavaScript profiler will pinpoint the slowest lines of code:

![The Firefox JavaScript profiler showing a completed profile 1.](/en-US/docs/Web/Performance/Fundamentals/javascript-profiler.png)

The Built-in Gecko Profiler is a very useful tool that provides even more detailed information about which parts of the browser code are running slowly while the profiler runs. This is a bit more complex to use, but provides a lot of useful details.

![A built-in Gecko profiler windows showing a lot of network information.](/en-US/docs/Web/Performance/Fundamentals/gecko-profiler.png)

**Note:** You can use these tools with the Android browser by running Firefox and enabling about:debugging.

In particular, making dozens or hundreds of network requests takes longer in mobile browsers. Rendering large images and CSS gradients can also take longer. Downloading large files can take longer, even over a fast network, because mobile hardware is sometimes too slow to take advantage of all the available bandwidth. For useful general tips on mobile Web performance, have a look at Maximiliano Firtman's Mobile Web High Performance talk.

### Test cases and submitting bugs

If the Firefox and Chrome developer tools don't help you find a problem, or if they seem to indicate that the Web browser has caused the problem, try to provide a reduced test case that maximally isolates the problem. That often helps in diagnosing problems.

See if you can reproduce the problem by saving and loading a static copy of an HTML page (including any images/stylesheets/scripts it embeds). If so, edit the static files to remove any private information, then send them to others for help (submit a Bugzilla report, for example, or host it on a server and share the URL). You should also share any profiling information you've collected using the tools listed above.


Performance Monitoring: RUM vs. synthetic monitoring - Web performance

Performance Monitoring: RUM vs. synthetic monitoring
====================================================

**Synthetic monitoring** and **real user monitoring (RUM)** are two approaches for monitoring and providing insight into web performance. RUM and synthetic monitoring provide for different views of performance and have benefits, good use cases and shortfalls. RUM is generally best suited for understanding long-term trends whereas synthetic monitoring is very well suited to regression testing and mitigating shorter-term performance issues during development. In this article we define and compare these two performance monitoring approaches.

Synthetic Monitoring
--------------------

Synthetic monitoring involves monitoring the performance of a page in a 'laboratory' environment, typically with automation tooling in a consistent as possible environment. Synthetic Monitoring involves deploying scripts to simulate the path an end user might take through a web application, reporting back the performance the simulator experiences. The traffic measured is not of your actual users, but rather synthetically generated traffic collecting data on page performance.

An example of synthetic monitoring is WebPageTest.org. It is done in a controlled environment where variable like geography, network, device, browser, and cached status are predetermined. It provides waterfall charts for every asset served by the host and CDN as well as every third party asset and asset requests generated by all third party scripts, such as ads and analytic services.

Controlling for environmental variables is helpful in understanding where performance bottlenecks have been occurring and identifying the source of any performance issues. For example, but it isn't reflective of the actual experience of users, especially the long tail.

Synthetic monitoring can be an important component of regression testing and production site monitoring. Test the site at every stage of development and regularly in production. Changes from baseline performance as part of continuous integration should fail a push. If an issue arises in production, synthetic monitoring can provide insight, helping identify, isolate, and resolve problems before they negatively user experience.

Real User Monitoring
--------------------

**Real User Monitoring** or RUM measures the performance of a page from real users' machines. Generally, a third party script injects a script on each page to measure and report back on page load data for every request made. This technique monitors an application's actual user interactions. In real user monitoring, the browsers of real users report back performance metrics experienced. RUM helps identify how an application is being used, including the geographic distribution of users and the impact of that distribution on the end user experience.

Unlike Synthetic monitoring, RUM captures the performance of actual users regardless of device, browser, network or geographic location. As users interact with an application, all performance timings are captured, regardless of what actions are taken or pages viewed. RUM monitors actual use cases, not the synthetic, assumed use cases predefined by an engineer, PM, or marketing team. This is particularly important for large sites or complex apps, where the functionality or content is constantly changing, and where the population accessing the application may differ greatly in life experiences from those creating it.

By leveraging RUM, a business can better understand its users and identify the areas on its site that require the most attention. Moreover, RUM can help to understand the geographic or channel distribution trends of your users. Knowing your user trends helps you better define your business plan and, from a monitoring perspective, allows you to identify key areas to target for optimization and performance improvements.

RUM v Synthetic
---------------

Synthetic is well suited for catching regressions during development life cycles, especially with network throttling. It is fairly easy, inexpensive, and great for spot-checking performance during development as an effective way to measure the effect of code changes, but it doesn't reflect what real users are experiencing and provides only a narrow view of performance.

RUM, on the other hand, provides real metrics from real users using the site or application. While this is more expensive and likely less convenient, it provides vital user experience data.

Performance APIs
----------------

There are many monitoring services. If you do want to roll your own monitoring system, take a look at the performance APIs, mainly `PerformanceNavigationTiming` and `PerformanceResourceTiming`, but also `PerformanceMark`, `PerformanceMeasure`, and `PerformancePaintTiming`.


Performance budgets - Web performance

Performance budgets
===================

A performance budget is a limit to prevent regressions. It can apply to a file, a file type, all files loaded on a page, a specific metric (e.g. Time to Interactive), a custom metric (e.g. Time to Hero Element), or a threshold over a period of time.

Why do I need a performance budget?
-----------------------------------

A budget exists to reflect your reachable goals. It's a tradeoff between user experience, against other performance indicators (e.g. conversion rate).

These goals can be:

* Timing based (e.g. Time to Interactive, First Contentful Paint).
* Quantity-based (e.g. amount of JS files/total image size).
* Rule-based (e.g. PageSpeed index, Lighthouse score).

Their primary goal is to prevent regressions, but they can provide insights to forecast trends (i.e. On September, 50% of the budget was spent in a week).

Additionally, it can uncover development needs (i.e. A large library with smaller alternatives is often picked to solve a common problem).

How do I define a performance budget?
-------------------------------------

A budget should include 2 levels:

* Warning.
* Error.

The warning level allows you to be proactive and plan any tech debt, while not blocking development or deploys.

The error level is an upper bound limit, where changes will have a negative and noticeable impact.

In order to begin, you need to first measure the devices and connection speeds where your users are coming from (e.g. A ~$*200* Android device over a 3G connection), using multiple tools. These time-based metrics will translate into file-size budgets.

A default baseline to reduce bounce rate is to achieve Time to Interactive under 5 seconds in 3G/4G, and under 2 seconds for subsequent loads. However, based on the specific goals and content of your site, you might choose to focus on other metrics.

For a text-heavy site such as a blog or a news site, the First Contentful Paint metric could reflect more closely the user behavior. (i.e. How fast can users start reading), which will inform file specific budgets (e.g. Font size), and their optimizations. (e.g. Using font-display to improve Perceived Performance).

The ultimate value of a Performance Budget is to correlate the impact of Performance on business or product goals. When defining metrics, you should focus on User Experience, which will dictate not only the bounce or conversion rate but how likely is that user to return.

How do I implement a performance budget?
----------------------------------------

During development, there are a few tools to run checks against new or modified assets:

* A module bundler (e.g. webpack), has performance features that will notify you when assets exceed specified limits.
* Bundlesize, allows you to define and run file size checks in your continuous integration (CI) pipeline.

File size checks are the first line of defense against regressions but translating size back into time metrics can be difficult since development environments could be missing 3rd party scripts, and optimizations commonly provided by a CDN.

The first step is to define a development baseline for each branch to compare to and the precision of the difference between development and production can be used as a goal towards better match the live environment.

The Lighthouse Bot integrates with Travis CI and can be used to gather Lighthouse and Webpage Test metrics from a development URL. The bot will pass or fail based on the provided minimum scores.

How do I enforce a performance budget?
--------------------------------------

The sooner that you can identify a potential addition pushing the budget, the better you can analyze the current state of your site, and pinpoint optimizations or unnecessary code.

However, you should have multiple budgets and be dynamic. They are meant to reflect your ongoing goals but allow risks and experiments. For example, you may introduce a feature that increases overall load time but attempts to increase user engagement. (i.e. How long a user stays on a page or site).

A performance budget helps you protect optimal behavior for your current users while enabling you to tap into new markets and deliver custom experiences.

See also
--------

* Start Performance Budgeting by Addy Osmani
* Performance Budgets 101 by Milica Mihajlija
* Performance Budgets That Stick by Tim Kadlec