Performance: getEntriesByName() method - Web APIs

Performance: getEntriesByName() method
======================================

The **`getEntriesByName()`** method returns an array of `PerformanceEntry` objects currently present in the performance timeline with the given *name* and *type*.

If you are interested in performance entries of certain types, see `getEntriesByType()`. For all performance entries, see `getEntries()`.

**Note:** This method does not notify you about new performance entries; you will only get entries that are present in the performance timeline at the time you call this method.
 To receive notifications about entries as they become available, use a `PerformanceObserver`.

The following entry types are not supported by this method at all and won't be returned even if entries for these types might exist:

* `"element"` (`PerformanceElementTiming`)
* `"event"` (`PerformanceEventTiming`)
* `"largest-contentful-paint"` (`LargestContentfulPaint`)
* `"layout-shift"` (`LayoutShift`)
* `"longtask"` (`PerformanceLongTaskTiming`)

To access entries of these types, you must use a `PerformanceObserver` instead.

Syntax
------

```js
getEntriesByName(name)
getEntriesByName(name, type)
```

### Parameters

`name`

The name of the entries to retrieve.

`type` Optional

 The type of entries to retrieve such as "`mark`". The valid entry types are
 listed in `PerformanceEntry.entryType`.

### Return value

 An `Array` of `PerformanceEntry` objects that have the specified `name` and `type`.
 The items will be in chronological order based on the entries' `startTime`. If no objects meet the
 specified criteria, an empty array is returned.

Examples
--------

### Logging performance markers

The following example logs all `PerformanceMark` objects named "`debug-mark`".

```js
const debugMarks = performance.getEntriesByName("debug-mark", "mark");
debugMarks.forEach((entry) => {
  console.log(`${entry.name}'s startTime: ${entry.startTime}`);
});
```

Specifications
--------------

| Specification |
| --- |
| Performance Timeline # dom-performance-getentriesbyname |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Performance.getEntries()`
* `Performance.getEntriesByType()`


Performance: clearMeasures() method - Web APIs

Performance: clearMeasures() method
===================================

The **`clearMeasures()`** method removes all or specific `PerformanceMeasure` objects from the browser's performance timeline.

Syntax
------

```js
clearMeasures()
clearMeasures(name)
```

### Parameters

`name` Optional

A string representing the `name` of the `PerformanceMeasure` object. If this argument is omitted, all entries with an `entryType` of "`measure`" will be removed.

### Return value

None (`undefined`).

Examples
--------

### Removing measures

To clean up all performance measure, or just specific entries, use the `clearMeasures()` method like this:

```js
// Create a bunch of measures
performance.measure("from navigation");
performance.mark("a");
performance.measure("from mark a", "a");
performance.measure("from navigation");
performance.measure("from mark a", "a");
performance.mark("b");
performance.measure("between a and b", "a", "b");

performance.getEntriesByType("measure").length; // 5

// Delete just the "from navigation" measure entries
performance.clearMeasures("from navigation");
performance.getEntriesByType("measure").length; // 3

// Delete all of the measure entries
performance.clearMeasures();
performance.getEntriesByType("measure").length; // 0
```

Specifications
--------------

| Specification |
| --- |
| User Timing # dom-performance-clearmeasures |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `PerformanceMeasure`


Performance: eventCounts property - Web APIs

Performance: eventCounts property
=================================

The read-only `performance.eventCounts` property is an `EventCounts` map containing the number of events which have been dispatched per event type.

Not all event types are exposed. You can only get counts for event types supported by the `PerformanceEventTiming` interface.

Value
-----

 An `EventCounts` map.
 (A read-only `Map` without the `clear()`, `delete()`, and `set()` methods).

Examples
--------

### Reporting event types and their counts

If you like to send event counts to your analytics, you may want to implement a function like `sendToEventAnalytics` which takes the event counts from the `performance.eventCounts` map and then uses the Fetch API to post the data to your endpoint.

```js
// Report all exposed events
for (entry of performance.eventCounts.entries()) {
  const type = entry[0];
  const count = entry[1];
  // sendToEventAnalytics(type, count);
}

// Report a specific event
const clickCount = performance.eventCounts.get("click");
// sendToEventAnalytics("click", clickCount);

// Check if an event count is exposed for a type
const isExposed = performance.eventCounts.has("mousemove"); // false
```

Specifications
--------------

| Specification |
| --- |
| Event Timing API # dom-performance-eventcounts |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `EventCounts`
* `PerformanceEventTiming`
* `Map`


Performance: clearMarks() method - Web APIs

Performance: clearMarks() method
================================

The **`clearMarks()`** method removes all or specific `PerformanceMark` objects from the browser's performance timeline.

Syntax
------

```js
clearMarks()
clearMarks(name)
```

### Parameters

`name` Optional

A string representing the `name` of the `PerformanceMark` object. If this argument is omitted, all entries with an `entryType` of "`mark`" will be removed.

### Return value

None (`undefined`).

Examples
--------

### Removing markers

To clean up all performance marks, or just specific entries, use the `clearMarks()` method like this:

```js
// Create a bunch of marks
performance.mark("login-started");
performance.mark("login-started");
performance.mark("login-finished");
performance.mark("form-sent");
performance.mark("video-loaded");
performance.mark("video-loaded");

performance.getEntriesByType("mark").length; // 6

// Delete just the "login-started" mark entries
performance.clearMarks("login-started");
performance.getEntriesByType("mark").length; // 4

// Delete all of the mark entries
performance.clearMarks();
performance.getEntriesByType("mark").length; // 0
```

Specifications
--------------

| Specification |
| --- |
| User Timing # dom-performance-clearmarks |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `PerformanceMark`


Performance: timeOrigin property - Web APIs

Performance: timeOrigin property
================================

The **`timeOrigin`** read-only property of the `Performance` interface returns the high resolution timestamp that is used as the baseline for performance-related timestamps.

In Window contexts, this value represents the time when navigation has started. In `Worker` and `ServiceWorker` contexts, this value represents the time when the worker is run. You can use this property to synchronize the time origins between the contexts (see example below).

**Note:** The value of `performance.timeOrigin` may differ from the value returned by `Date.now()` executed at the time origin, because `Date.now()` may have been impacted by system and user clock adjustments, clock skew, etc. The `timeOrigin` property is a monotonic clock which current time never decreases and which isn't subject to these adjustments.

Value
-----

A high resolution timestamp which considered to be the beginning of the current document's lifetime. It's calculated like this:

* If the script's global object is a `Window`, the time origin is determined as follows:
    + If the current `Document` is the first one loaded in the `Window`, the time origin is the time at which the browser context was created.
    + If during the process of unloading the previous document which was loaded in the window, a confirmation dialog was displayed to let the user confirm whether or not to leave the previous page, the time origin is the time at which the user confirmed that navigating to the new page was acceptable.
    + If neither of the above determines the time origin, then the time origin is the time at which the navigation responsible for creating the window's current `Document` took place.
* If the script's global object is a `WorkerGlobalScope` (that is, the script is running as a web worker), the time origin is the moment at which the worker was created.
* In all other cases, the time origin is undefined.
Examples
--------

### Synchronizing time between contexts

To account for the different time origins in window and worker contexts, you can translate the timestamps coming from worker scripts with the help of the `timeOrigin` property, so the timings synchronize for the entire application.

In worker.js

```js
self.addEventListener("connect", (event) => {
  const port = event.ports[0];

  port.onmessage = function (event) {
    const workerTaskStart = performance.now();
    // doSomeWork()
    const workerTaskEnd = performance.now();
  };

  // Convert worker-relative timestamps to absolute timestamps, then send to the window
  port.postMessage({
    startTime: workerTaskStart + performance.timeOrigin,
    endTime: workerTaskEnd + performance.timeOrigin,
  });
});
```

In main.js

```js
const worker = new SharedWorker("worker.js");
worker.port.addEventListener("message", (event) => {
  // Convert absolute timestamps into window-relative timestamps
  const workerTaskStart = event.data.startTime - performance.timeOrigin;
  const workerTaskEnd = event.data.endTime - performance.timeOrigin;

  console.log("Worker task start: ", workerTaskStart);
  console.log("Worker task end: ", workerTaskEnd);
});
```

Specifications
--------------

| Specification |
| --- |
| High Resolution Time # dom-performance-timeorigin |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Performance: setResourceTimingBufferSize() method - Web APIs

Performance: setResourceTimingBufferSize() method
=================================================

The **`setResourceTimingBufferSize()`** method sets the desired size of the browser's resource timing buffer which stores the "`resource`" performance entries.

The specification requires the resource timing buffer initially to be 250 or greater.

 To clear the browser's performance resource data buffer, use the
 `Performance.clearResourceTimings()` method.

To get notified when the browser's resource timing buffer is full, listen for the `resourcetimingbufferfull` event.

Syntax
------

```js
setResourceTimingBufferSize(maxSize)
```

### Parameters

`maxSize`

A `number` representing the maximum number of `performance entry` objects the browser should hold in its performance entry buffer.

### Return value

None (`undefined`).

Examples
--------

### Setting a resource timing buffer size

The following call allows 500 "`resource`" performance entries in the browser's performance timeline.

```js
performance.setResourceTimingBufferSize(500);
```

If you set the buffer size to a number lower than the amount of current entries in the buffer, no entries will be removed. Instead, to clear the buffer, call `Performance.clearResourceTimings()`.

```js
performance.getEntriesByType("resource").length; // 20
performance.setResourceTimingBufferSize(10);
performance.getEntriesByType("resource").length; // 20

performance.clearResourceTimings();
performance.getEntriesByType("resource").length; // 0
```

Specifications
--------------

| Specification |
| --- |
| Resource Timing # dom-performance-setresourcetimingbuffersize |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Performance.clearResourceTimings()`
* `resourcetimingbufferfull`


Performance: getEntriesByType() method - Web APIs

Performance: getEntriesByType() method
======================================

The **`getEntriesByType()`** method returns an array of `PerformanceEntry` objects currently present in the performance timeline for a given *type*.

If you are interested in performance entries of certain name, see `getEntriesByName()`. For all performance entries, see `getEntries()`.

**Note:** This method does not notify you about new performance entries; you will only get entries that are present in the performance timeline at the time you call this method.
 To receive notifications about entries as they become available, use a `PerformanceObserver`.

The following entry types are not supported by this method at all and won't be returned even if entries for these types might exist:

* `"element"` (`PerformanceElementTiming`)
* `"event"` (`PerformanceEventTiming`)
* `"largest-contentful-paint"` (`LargestContentfulPaint`)
* `"layout-shift"` (`LayoutShift`)
* `"longtask"` (`PerformanceLongTaskTiming`)

To access entries of these types, you must use a `PerformanceObserver` instead.

Syntax
------

```js
getEntriesByType(type)
```

### Parameters

`type`

The type of entry to retrieve such as "`mark`". The valid entry types are listed in `PerformanceEntry.entryType`. The supported `entryTypes` can be retrieved using the static property `PerformanceObserver.supportedEntryTypes`.

### Return value

An `Array` of `PerformanceEntry` objects that have the specified `type`. The items will be in chronological order based on the entries' `startTime`. If no objects have the specified `type`, or no argument is provided, an empty array is returned.

Examples
--------

### Logging resource entries

The following example logs all entries with the type "`resource`".

```js
const resources = performance.getEntriesByType("resource");
resources.forEach((entry) => {
  console.log(`${entry.name}'s startTime: ${entry.startTime}`);
});
```

Specifications
--------------

| Specification |
| --- |
| Performance Timeline # dom-performance-getentriesbytype |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Performance.getEntries()`
* `Performance.getEntriesByName()`
* `PerformanceObserver.supportedEntryTypes`


Performance: getEntries() method - Web APIs

Performance: getEntries() method
================================

The **`getEntries()`** method returns an array of all `PerformanceEntry` objects currently present in the performance timeline.

If you are only interested in performance entries of certain types or that have certain names, see `getEntriesByType()` and `getEntriesByName()`.

**Note:** This method does not notify you about new performance entries; you will only get entries that are present in the performance timeline at the time you call this method.
 To receive notifications about entries as they become available, use a `PerformanceObserver`.

The following entry types are not supported by this method at all and won't be returned even if entries for these types might exist:

* `"element"` (`PerformanceElementTiming`)
* `"event"` (`PerformanceEventTiming`)
* `"largest-contentful-paint"` (`LargestContentfulPaint`)
* `"layout-shift"` (`LayoutShift`)
* `"longtask"` (`PerformanceLongTaskTiming`)

To access entries of these types, you must use a `PerformanceObserver` instead.

Syntax
------

```js
getEntries()
```

### Parameters

None.

### Return value

An `Array` of `PerformanceEntry` objects. The items will be in chronological order based on the entries' `startTime`.

Examples
--------

### Logging all performance markers and measures

Assuming you created your own `PerformanceMark` and `PerformanceMeasure` objects at appropriate places in your code, you might want to log all them to the console like this:

```js
// Example markers/measures
performance.mark("login-started");
performance.mark("login-finished");
performance.mark("form-sent");
performance.mark("video-loaded");
performance.measure("login-duration", "login-started", "login-finished");

const entries = performance.getEntries();

entries.forEach((entry) => {
  if (entry.entryType === "mark") {
    console.log(`${entry.name}'s startTime: ${entry.startTime}`);
  }
  if (entry.entryType === "measure") {
    console.log(`${entry.name}'s duration: ${entry.duration}`);
  }
});
```

Specifications
--------------

| Specification |
| --- |
| Performance Timeline # dom-performance-getentries |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Performance.getEntriesByType()`
* `Performance.getEntriesByName()`


Performance: toJSON() method - Web APIs

Performance: toJSON() method
============================

The **`toJSON()`** method of the `Performance` interface is a serializer; it returns a JSON representation of the `Performance` object.

Syntax
------

```js
toJSON()
```

### Parameters

None.

### Return value

A `JSON` object that is the serialization of the `Performance` object.

The returned JSON doesn't contain the `eventCounts` property because it is of type `EventCounts`, which doesn't provide a `toJSON()` operation.

**Note:** The JSON object contains the serialization of the deprecated `performance.timing` and `performance.navigation` properties. To get a JSON representation of the newer `PerformanceNavigationTiming` interface, call `PerformanceNavigationTiming.toJSON()` instead.

Examples
--------

### Using the toJSON method

In this example, calling `performance.toJSON()` returns a JSON representation of the `Performance` object.

```js
performance.toJSON();
```

This would log a JSON object like so:

```json
{
  "timeOrigin": 1668077531367.4,
  "timing": {
    "connectStart": 1668077531372,
    "navigationStart": 1668077531367,
    "secureConnectionStart": 0,
    "fetchStart": 1668077531372,
    "domContentLoadedEventStart": 1668077531580,
    "responseStart": 1668077531372,
    "domInteractive": 1668077531524,
    "domainLookupEnd": 1668077531372,
    "responseEnd": 1668077531500,
    "redirectStart": 0,
    "requestStart": 1668077531372,
    "unloadEventEnd": 0,
    "unloadEventStart": 0,
    "domLoading": 1668077531512,
    "domComplete": 1668077531585,
    "domainLookupStart": 1668077531372,
    "loadEventStart": 1668077531585,
    "domContentLoadedEventEnd": 1668077531580,
    "loadEventEnd": 1668077531585,
    "redirectEnd": 0,
    "connectEnd": 1668077531372
  },
  "navigation": {
    "type": 0,
    "redirectCount": 0
  }
}
```

To get a JSON string, you can use `JSON.stringify(performance)` directly; it will call `toJSON()` automatically.

Specifications
--------------

| Specification |
| --- |
| High Resolution Time # dom-performance-tojson |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `JSON`


Performance: memory property - Web APIs

Performance: memory property
============================

**Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

**Non-standard:** This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

The non-standard and legacy `performance.memory` property returns the size of the JavaScript heap which can be helpful to measure and reduce the memory footprint of websites.

Note that the information this API provides is unreliable as it might overestimate actual memory usage if web pages share the same heap, or might underestimate actual memory usage if web pages use workers and/or cross-site iframes that are allocated in separate heaps. It is not standardized what "heap" means exactly. The API is only available in Chromium-based browsers.

A new API aiming to replace `performance.memory` is `Performance.measureUserAgentSpecificMemory()`. It tries to estimate the memory used by a web page.

Value
-----

The read-only `performance.memory` property is an object with the following properties:

`jsHeapSizeLimit`

The maximum size of the heap, in bytes, that is available to the context.

`totalJSHeapSize`

The total allocated heap size, in bytes.

`usedJSHeapSize`

The currently active segment of JS heap, in bytes.

Examples
--------

### Getting JavaScript heap sizes

Calling `performance.memory` returns an object like this:

```js
{
  totalJSHeapSize: 39973671,
  usedJSHeapSize: 39127515,
  jsHeapSizeLimit: 4294705152
}
```

Specifications
--------------

None.

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Performance.measureUserAgentSpecificMemory()`


Performance: now() method - Web APIs

Performance: now() method
=========================

The **`performance.now()`** method returns a high resolution timestamp in milliseconds. It represents the time elapsed since `Performance.timeOrigin` (the time when navigation has started in window contexts, or the time when the worker is run in `Worker` and `ServiceWorker` contexts).

Syntax
------

```js
now()
```

### Parameters

None.

### Return value

Returns a `DOMHighResTimeStamp` measured in milliseconds.

Description
-----------

### `Performance.now` vs. `Date.now`

Unlike `Date.now`, the timestamps returned by `performance.now()` are not limited to one-millisecond resolution. Instead, they represent times as floating-point numbers with up to microsecond precision.

 Also, `Date.now()` may have been impacted by system and user clock adjustments, clock skew, etc. as it is relative to the Unix epoch (1970-01-01T00:00:00Z) and dependent on the system clock.
 The `performance.now()` method on the other hand is relative to the `timeOrigin` property which is a monotonic clock: its current time never decreases and isn't subject to adjustments.

### `performance.now` specification changes

The semantics of the `performance.now()` method changed between High Resolution Time Level 1 and Level 2.

| Changes | Level 1 | Level 2 |
| --- | --- | --- |
| Relative to | `performance.timing.navigationStart` | `Performance.timeOrigin` |
| Triggering conditions | Document fetch or unload prompt (if any). | Creation of the browsing context (if no prior document), unload prompt (if any), or start of the navigation (as defined in HTML, a few steps before fetch). |

The `performance.now()` method used to be relative to `performance.timing.navigationStart` property from the Navigation Timing specification. This changed and `performance.now()` is now relative to `Performance.timeOrigin` which avoids clock change risks when comparing timestamps across webpages.

```js
// Level 1 (clock change risks)
currentTime = performance.timing.navigationStart + performance.now();

// Level 2 (no clock change risks)
currentTime = performance.timeOrigin + performance.now();
```

### Ticking during sleep

The specification (Level 2) requires that `performance.now()` should tick during sleep. It appears that only Firefox on Windows, and Chromiums on Windows keep ticking during sleep. Relevant browser bugs for other operating systems:

* Chrome/Chromium (bug)
* Firefox (bug)
* Safari/WebKit (bug)

More details can also be found in the specification issue hr-time#115.

Examples
--------

### Using `performance.now()`

To determine how much time has elapsed since a particular point in your code, you can do something like this:

```js
const t0 = performance.now();
doSomething();
const t1 = performance.now();
console.log(`Call to doSomething took ${t1 - t0} milliseconds.`);
```

Security requirements
---------------------

To offer protection against timing attacks and fingerprinting, `performance.now()` is coarsened based on site isolation status.

* Resolution in isolated contexts: 5 microseconds
* Resolution in non-isolated contexts: 100 microseconds

 Cross-origin isolate your site using the `Cross-Origin-Opener-Policy` and
 `Cross-Origin-Embedder-Policy` headers:

```http
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
```

 These headers ensure a top-level document does not share a browsing context group with
 cross-origin documents. COOP process-isolates your document and potential attackers
 can't access to your global object if they were opening it in a popup, preventing a set
 of cross-origin attacks dubbed XS-Leaks.

Specifications
--------------

| Specification |
| --- |
| High Resolution Time # dom-performance-now |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Performance.timeOrigin`


Performance: resourcetimingbufferfull event - Web APIs

Performance: resourcetimingbufferfull event
===========================================

The `resourcetimingbufferfull` event is fired when the browser's resource timing buffer is full.

Syntax
------

Use the event name in methods like `addEventListener()`, or set an event handler property.

```js
addEventListener("resourcetimingbufferfull", (event) => {});

onresourcetimingbufferfull = (event) => {};
```

Event type
----------

A generic `Event`.

Examples
--------

### Increasing size when buffer is full

The following example listens for the `resourcetimingbufferfull` event and increases the buffer size using the `setResourceTimingBufferSize()` method.

```js
function increaseFilledBufferSize(event) {
  console.log(
    "WARNING: Resource Timing Buffer is FULL! Increasing buffer size to 500.",
  );
  performance.setResourceTimingBufferSize(500);
}

performance.addEventListener(
  "resourcetimingbufferfull",
  increaseFilledBufferSize,
);
```

Specifications
--------------

| Specification |
| --- |
| Resource Timing # dom-performance-onresourcetimingbufferfull |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Performance.clearResourceTimings()`
* `Performance.setResourceTimingBufferSize()`


Performance: clearResourceTimings() method - Web APIs

Performance: clearResourceTimings() method
==========================================

The **`clearResourceTimings()`** method removes all performance entries with an `entryType` of "`resource`" from the browser's performance timeline and sets the size of the performance resource data buffer to zero.

 To set the size of the browser's performance resource data buffer, use the
 `Performance.setResourceTimingBufferSize()` method.

To get notified when the browser's resource timing buffer is full, listen for the `resourcetimingbufferfull` event.

Syntax
------

```js
clearResourceTimings()
```

### Parameters

None.

### Return value

None (`undefined`).

Examples
--------

### Clearing the performance resource data buffer

To remove all resource performance entries from the buffer, call the `clearResourceTimings()` at an appropriate point in your code or paste it into the console.

```js
performance.clearResourceTimings();
performance.getEntriesByType("resource").length; // 0
```

### Taking records and emptying performance observers

When using `PerformanceObserver` objects (especially with the `buffered` flag set to `true`), the performance resource buffer might get full quickly. However, instead of clearing the buffer, you can also store the current list of performance entries and empty the performance observer using the `PerformanceObserver.takeRecords()` method. This works with all kinds of performance entry types, not just "`resource`" entries.

```js
function perfObserver(list, observer) {
  list.getEntries().forEach((entry) => {
    // do something with the entries
  });
}
const observer = new PerformanceObserver(perfObserver);
observer.observe({ type: "resource", buffered: true });

// Store entries and empty performance observer
const records = observer.takeRecords();
```

Specifications
--------------

| Specification |
| --- |
| Resource Timing # dom-performance-clearresourcetimings |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Performance.setResourceTimingBufferSize()`
* `resourcetimingbufferfull`


Performance: timing property - Web APIs

Performance: timing property
============================

**Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

 The legacy
 **`Performance.timing`** read-only
 property returns a `PerformanceTiming` object containing latency-related
 performance information.

This property is not available in workers.

**Warning:** This property is deprecated in the Navigation Timing Level 2 specification. Please use the `PerformanceNavigationTiming`
 interface instead.

Value
-----

A `PerformanceTiming` object.

Specifications
--------------

 This feature is no longer on track to become a standard, as the Navigation Timing specification has marked it as deprecated.
 Use the `PerformanceNavigationTiming` interface instead.

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The `Performance` interface it belongs to.


XRDepthInformation: rawValueToMeters property - Web APIs

XRDepthInformation: rawValueToMeters property
=============================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The *read-only* **`rawValueToMeters`** property of the `XRDepthInformation` interface contains the scale factor by which the raw depth values must be multiplied in order to get the depths in meters.

For CPU depth information, see also the `XRCPUDepthInformation.getDepthInMeters()` method.

Value
-----

A number.

Examples
--------

Use `XRFrame.getDepthInformation()` (CPU) or `XRWebGLBinding.getDepthInformation()` (WebGL) to obtain depth information. The returned objects will contain the `rawValueToMeters` scale factor, which can be used for further calculations.

For CPU depth information and a buffer that has "luminance-alpha" format:

```js
const uint16 = new Uint16Array(depthInfo.data);
const index = column + row \* depthInfo.width;
const depthInMeters = uint16[index] \* depthInfo.rawValueToMeters;
```

(Use `Float32Array` for a "float32" data format.)

Note that the depth in meters is in depth-buffer coordinates. Additional steps are needed to convert them to normalized view coordinates, or the `XRCPUDepthInformation.getDepthInMeters()` method can be used.

Specifications
--------------

| Specification |
| --- |
| WebXR Depth Sensing Module # dom-xrdepthinformation-rawvaluetometers |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


XRDepthInformation: normDepthBufferFromNormView property - Web APIs

XRDepthInformation: normDepthBufferFromNormView property
========================================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The *read-only* **`normDepthBufferFromNormView`** property of the `XRDepthInformation` interface contains the 3D geometric transform that needs to be applied when indexing into the depth buffer.

Value
-----

An `XRRigidTransform` that needs to be applied when indexing into the depth buffer. The transformation that the matrix represents changes the coordinate system from normalized view coordinates to normalized depth-buffer coordinates that can then be scaled by depth buffer's `width` and `height` to obtain the absolute depth buffer coordinates.

Examples
--------

Use `XRFrame.getDepthInformation()` (CPU) or `XRWebGLBinding.getDepthInformation()` (WebGL) to obtain depth information. The returned objects will contain the `normDepthBufferFromNormView` of the depth buffer, which you can use for further calculations.

```js
const normDepthFromNormViewMatrix =
  depthData.normDepthBufferFromNormView.matrix;
const normViewFromNormDepth =
  depthData.normDepthBufferFromNormView.inverse.matrix;
```

Specifications
--------------

| Specification |
| --- |
| WebXR Depth Sensing Module # dom-xrdepthinformation-normdepthbufferfromnormview |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


XRDepthInformation: width property - Web APIs

XRDepthInformation: width property
==================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The *read-only* **`width`** property of the `XRDepthInformation` interface contains the width of the depth buffer (number of columns).

Value
-----

An unsigned long integer.

Examples
--------

Use `XRFrame.getDepthInformation()` (CPU) or `XRWebGLBinding.getDepthInformation()` (WebGL) to obtain depth information. The returned objects will contain the `width` of the depth buffer, which you can use for further calculations.

```js
const smallerDepthDimension = Math.min(depthInfo.width, depthInfo.height);
const largerDepthDimension = Math.max(depthInfo.width, depthInfo.height);
```

Specifications
--------------

| Specification |
| --- |
| WebXR Depth Sensing Module # dom-xrdepthinformation-width |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


XRDepthInformation: height property - Web APIs

XRDepthInformation: height property
===================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The *read-only* **`height`** property of the `XRDepthInformation` interface contains the height of the depth buffer (number of rows).

Value
-----

An unsigned long integer.

Examples
--------

Use `XRFrame.getDepthInformation()` (CPU) or `XRWebGLBinding.getDepthInformation()` (WebGL) to obtain depth information. The returned objects will contain the `height` of the depth buffer, which you can use for further calculations.

```js
const smallerDepthDimension = Math.min(depthInfo.width, depthInfo.height);
const largerDepthDimension = Math.max(depthInfo.width, depthInfo.height);
```

Specifications
--------------

| Specification |
| --- |
| WebXR Depth Sensing Module # dom-xrdepthinformation-height |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Using the Notifications API - Web APIs

Using the Notifications API
===========================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

The Notifications API lets a web page or app send notifications that are displayed outside the page at the system level; this lets web apps send information to a user even if the application is idle or in the background. This article looks at the basics of using this API in your own apps.

Typically, system notifications refer to the operating system's standard notification mechanism: think for example of how a typical desktop system or mobile device broadcasts notifications.

![Desktop notification: To do list via mdn.github.io HEY! Your task "Go shopping" is now overdue](/en-US/docs/Web/API/Notifications_API/Using_the_Notifications_API/desktop-notification.png)

The system notification system will vary of course by platform and browser, but this is OK, and the Notifications API is written to be general enough for compatibility with most system notification systems.

**Note:** This feature is available in Web Workers

Examples
--------

One of the most obvious use cases for web notifications is a web-based mail or IRC application that needs to notify the user when a new message is received, even if the user is doing something else with another application. Many examples of this now exist, such as Slack.

We've written a real-world example — a to-do list app — to give more of an idea of how web notifications can be used. It stores data locally using IndexedDB and notifies users when tasks are due using system notifications. Download the To-do list code, or view the app running live.

Requesting permission
---------------------

Before an app can send a notification, the user must grant the application the right to do so. This is a common requirement when an API tries to interact with something outside a web page — at least once, the user needs to specifically grant that application permission to present notifications, thereby letting the user control which apps/sites are allowed to display notifications.

Because of abuses of push notifications in the past, web browsers and developers have begun to implement strategies to help mitigate this problem. You should only request consent to display notifications in response to a user gesture (e.g. clicking a button). This is not only best practice — you should not be spamming users with notifications they didn't agree to — but going forward browsers will explicitly disallow notification permission requests not triggered in response to a user gesture. Firefox is already doing this from version 72, for example, and Safari has done it for some time.

In addition, In Chrome and Firefox you cannot request notifications at all unless the site is a secure context (i.e. HTTPS), and you can no longer allow notification permissions to be requested from cross-origin `<iframe>`s.

### Checking current permission status

You can check to see if you already have permission by checking the value of the `Notification.permission` read only property. It can have one of three possible values:

`default`

The user hasn't been asked for permission yet, so notifications won't be displayed.

`granted`

The user has granted permission to display notifications, after having been asked previously.

`denied`

The user has explicitly declined permission to show notifications.

### Getting permission

If permission to display notifications hasn't been granted yet, the application needs to use the `Notification.requestPermission()` method to request this from the user. In its simplest form, we just include the following:

```js
Notification.requestPermission().then((result) => {
  console.log(result);
});
```

This uses the promise-based version of the method. If you want to support older versions, you might have to use the older callback version, which looks like this:

```js
Notification.requestPermission((result) => {
  console.log(result);
});
```

The callback version optionally accepts a callback function that is called once the user has responded to the request to display permissions.

**Note:** There's no way to reliably feature-test whether `Notification.requestPermission` supports the promise-based version. If you need to support older browsers, just use the callback-based version—although this is deprecated, it still works in new browsers. Check the browser compatibility table for more information.

### Example

In our todo list demo, we include an "Enable notifications" button that, when pressed, requests notification permissions for the app.

```html
<button id="enable">Enable notifications</button>
```

Clicking this calls the `askNotificationPermission()` function:

```js
function askNotificationPermission() {
  // function to actually ask the permissions
  function handlePermission(permission) {
    // set the button to shown or hidden, depending on what the user answers
    notificationBtn.style.display =
      Notification.permission === "granted" ? "none" : "block";
  }

  // Let's check if the browser supports notifications
  if (!("Notification" in window)) {
    console.log("This browser does not support notifications.");
  } else {
    Notification.requestPermission().then((permission) => {
      handlePermission(permission);
    });
  }
}
```

Looking at the second main block first, you'll see that we first check to see if Notifications are supported. If they are, we run the promise-based version of `Notification.requestPermission()`, and if not, we log a message to the console.

To avoid duplicating code, we have stored a few bits of housekeeping code inside the `handlePermission()` function, which is the first main block inside this snippet. Inside here we explicitly set the `Notification.permission` value (some old versions of Chrome failed to do this automatically), and show or hide the button depending on what the user chose in the permission dialog. We don't want to show it if permission has already been granted, but if the user chose to deny permission, we want to give them the chance to change their mind later on.

Creating a notification
-----------------------

Creating a notification is easy; just use the `Notification` constructor. This constructor expects a title to display within the notification and some options to enhance the notification such as an `icon` or a text `body`.

For example, in the to-do-list example we use the following snippet to create a notification when required (found inside the `createNotification()` function):

```js
const img = "/to-do-notifications/img/icon-128.png";
const text = `HEY! Your task "${title}" is now overdue.`;
const notification = new Notification("To do list", { body: text, icon: img });
```

Closing notifications
---------------------

Use `close()` to remove a notification that is no longer relevant to the user (e.g. the user already read the notification on the webpage, in the case of a messaging app, or the following song is already playing in a music app to notifies upon song changes). Most modern browsers dismiss notifications automatically after a few moments (around four seconds) but this isn't something you should generally be concerned about as it's up to the user and user agent. The dismissal may also happen at the operating system level and users should remain in control of this. Old versions of Chrome didn't remove notifications automatically so you can do so after a `setTimeout()` only for those legacy versions in order to not remove notifications from notification trays on other browsers.

```js
const n = new Notification("My Great Song");
document.addEventListener("visibilitychange", () => {
  if (document.visibilityState === "visible") {
    // The tab has become visible so clear the now-stale Notification.
    n.close();
  }
});
```

**Note:** This API shouldn't be used just to have the notification removed from the screen after a fixed delay (on modern browsers) since this method will also remove the notification from any notification tray, preventing users from interacting with it after it was initially shown.

**Note:** When you receive a "close" event, there is no guarantee that it's the user who closed the notification. This is in line with the specification, which states: "When a notification is closed, either by the underlying notifications platform or by the user, the close steps for it must be run."

Notification events
-------------------

There are four events that are triggered on the `Notification` instance:

`click`

Triggered when the user clicks on the notification.

`close`

Triggered once the notification is closed.

`error`

Triggered if something goes wrong with the notification; this is usually because the notification couldn't be displayed for some reason.

`show`

Triggered when the notification is displayed to the user.

These events can be tracked using the `onclick`, `onclose`, `onerror`, and `onshow` handlers. Because `Notification` also inherits from `EventTarget`, it's possible to use the `addEventListener()` method on it.

Replacing existing notifications
--------------------------------

It is usually undesirable for a user to receive a lot of notifications in a short space of time — for example, what if a messenger application notified a user for each incoming message, and they were being sent a lot? To avoid spamming the user with too many notifications, it's possible to modify the pending notifications queue, replacing single or multiple pending notifications with a new one.

To do this, it's possible to add a tag to any new notification. If a notification already has the same tag and has not been displayed yet, the new notification replaces that previous notification. If the notification with the same tag has already been displayed, the previous notification is closed and the new one is displayed.

### Tag example

Assume the following basic HTML:

```html
<button>Notify me!</button>
```

It's possible to handle multiple notifications this way:

```js
window.addEventListener("load", () => {
  const button = document.querySelector("button");

  if (window.self !== window.top) {
    // Ensure that if our document is in a frame, we get the user
    // to first open it in its own tab or window. Otherwise, it
    // won't be able to request permission to send notifications.
    button.textContent = "View live result of the example code above";
    button.addEventListener("click", () => window.open(location.href));
    return;
  }

  button.addEventListener("click", () => {
    if (Notification?.permission === "granted") {
      // If the user agreed to get notified
      // Let's try to send ten notifications
      let i = 0;
      // Using an interval cause some browsers (including Firefox) are blocking notifications if there are too much in a certain time.
      const interval = setInterval(() => {
        // Thanks to the tag, we should only see the "Hi! 9" notification
        const n = new Notification(`Hi! ${i}`, { tag: "soManyNotification" });
        if (i === 9) {
          clearInterval(interval);
        }
        i++;
      }, 200);
    } else if (Notification && Notification.permission !== "denied") {
      // If the user hasn't told if they want to be notified or not
      // Note: because of Chrome, we are not sure the permission property
      // is set, therefore it's unsafe to check for the "default" value.
      Notification.requestPermission().then((status) => {
        // If the user said okay
        if (status === "granted") {
          let i = 0;
          // Using an interval cause some browsers (including Firefox) are blocking notifications if there are too much in a certain time.
          const interval = setInterval(() => {
            // Thanks to the tag, we should only see the "Hi! 9" notification
            const n = new Notification(`Hi! ${i}`, {
              tag: "soManyNotification",
            });
            if (i === 9) {
              clearInterval(interval);
            }
            i++;
          }, 200);
        } else {
          // Otherwise, we can fallback to a regular modal alert
          alert("Hi!");
        }
      });
    } else {
      // If the user refuses to get notified, we can fallback to a regular modal alert
      alert("Hi!");
    }
  });
});
```

### Result

Specifications
--------------

| Specification |
| --- |
| Notifications API Standard # api |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Notification`


CanvasPattern: setTransform() method - Web APIs

CanvasPattern: setTransform() method
====================================

The **`CanvasPattern.setTransform()`** method uses a `DOMMatrix` object as the pattern's transformation matrix and invokes it on the pattern.

Syntax
------

```js
setTransform(matrix)
```

### Parameters

`matrix`

A `DOMMatrix` to use as the pattern's transformation matrix.

### Return value

None (`undefined`).

Examples
--------

### Using the `setTransform` method

 This is just a simple code snippet which uses the `setTransform` method to
 create a `CanvasPattern` with the specified pattern transformation from a
 `DOMMatrix`. The pattern gets applied if you set it as the current
 `fillStyle` and gets drawn onto the
 canvas when using the `fillRect()`
 method, for example.

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

const matrix = new DOMMatrix([1, 0.2, 0.8, 1, 0, 0]);

const img = new Image();
img.src = "canvas\_createpattern.png";

img.onload = () => {
  const pattern = ctx.createPattern(img, "repeat");
  pattern.setTransform(matrix.rotate(-45).scale(1.5));
  ctx.fillStyle = pattern;
  ctx.fillRect(0, 0, 400, 400);
};
```

#### Editable demo

Here's an editable demo of the code snippet above. Try changing the argument to `SetTransform()` to see the effect it had.
```

<canvas id="canvas" width="400" height="200" class="playable-canvas"></canvas>
<div class="playable-buttons">
  <input id="edit" type="button" value="Edit" />
  <input id="reset" type="button" value="Reset" />
</div>
<textarea id="code" class="playable-code" style="height:120px">
const img = new Image();
img.src = 'canvas_createpattern.png';
img.onload = () => {
  const pattern = ctx.createPattern(img, 'repeat');
  pattern.setTransform(matrix.rotate(-45).scale(1.5));
  ctx.fillStyle = pattern;
  ctx.fillRect(0, 0, 400, 400);
};
</textarea>
```

```
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const textarea = document.getElementById("code");
const reset = document.getElementById("reset");
const edit = document.getElementById("edit");
const code = textarea.value;

const matrix = new DOMMatrix([1, 0.2, 0.8, 1, 0, 0]);

function drawCanvas() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  eval(textarea.value);
}

reset.addEventListener("click", () => {
  textarea.value = code;
  drawCanvas();
});

edit.addEventListener("click", () => {
  textarea.focus();
});

textarea.addEventListener("input", drawCanvas);
window.addEventListener("load", drawCanvas);
```

Specifications
--------------

| Specification |
| --- |
| HTML Standard # dom-canvaspattern-settransform-dev |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The interface defining this method: `CanvasPattern`
* `DOMMatrix`


CSSMatrixComponent: CSSMatrixComponent() constructor - Web APIs

CSSMatrixComponent: CSSMatrixComponent() constructor
====================================================

 The **`CSSMatrixComponent()`** constructor
 creates a new `CSSMatrixComponent` object representing the matrix() and matrix3d() values of the
 individual `transform` property in CSS.

Syntax
------

```js
new CSSMatrixComponent(matrix)
new CSSMatrixComponent(matrix, options)
```

### Parameters

`matrix`

A 2d or 3d matrix.

Examples
--------

To do

Specifications
--------------

| Specification |
| --- |
| CSS Typed OM Level 1 # dom-cssmatrixcomponent-cssmatrixcomponent |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


CSSMatrixComponent: matrix property - Web APIs

CSSMatrixComponent: matrix property
===================================

 The **`matrix`** property of the
 `CSSMatrixComponent` interface gets and sets a 2d or 3d matrix.

 See the matrix() and matrix3d() pages for
 examples.

Value
-----

a matrix.

Examples
--------

To do.

Specifications
--------------

| Specification |
| --- |
| CSS Typed OM Level 1 # dom-cssmatrixcomponent-matrix |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


ANGLE_instanced_arrays: vertexAttribDivisorANGLE() method - Web APIs

ANGLE\_instanced\_arrays: vertexAttribDivisorANGLE() method
===========================================================

The **ANGLE\_instanced\_arrays.vertexAttribDivisorANGLE()** method of the WebGL API modifies the rate at which generic vertex attributes advance when rendering multiple instances of primitives with `ext.drawArraysInstancedANGLE()` and `ext.drawElementsInstancedANGLE()`.

**Note:** When using `WebGL2`, this method is available as `gl.vertexAttribDivisor()` by default.

Syntax
------

```js
vertexAttribDivisorANGLE(index, divisor)
```

### Parameters

`index`

A `GLuint` specifying the index of the generic vertex attributes.

`divisor`

A `GLuint` specifying the number of instances that will pass between updates of the generic attribute.

### Return value

None (`undefined`).

Examples
--------

```js
const ext = gl.getExtension("ANGLE\_instanced\_arrays");
ext.vertexAttribDivisorANGLE(0, 2);
```

Specifications
--------------

| Specification |
| --- |
| WebGL ANGLE\_instanced\_arrays Khronos Ratified Extension Specification  |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `ext.drawArraysInstancedANGLE()`
* `ext.drawElementsInstancedANGLE()`
* `WebGLRenderingContext.drawArrays()`
* `WebGLRenderingContext.drawElements()`
* `WebGL2RenderingContext.drawArraysInstanced()`
* `WebGL2RenderingContext.drawElementsInstanced()`
* `WebGL2RenderingContext.vertexAttribDivisor()`


ANGLE_instanced_arrays: drawArraysInstancedANGLE() method - Web APIs

ANGLE\_instanced\_arrays: drawArraysInstancedANGLE() method
===========================================================

The **`ANGLE_instanced_arrays.drawArraysInstancedANGLE()`** method of the WebGL API renders primitives from array data like the `gl.drawArrays()` method. In addition, it can execute multiple instances of the range of elements.

**Note:** When using `WebGL2`, this method is available as `gl.drawArraysInstanced()` by default.

Syntax
------

```js
drawArraysInstancedANGLE(mode, first, count, primcount)
```

### Parameters

`mode`

A `GLenum` specifying the type primitive to render. Possible values are:

* `gl.POINTS`: Draws a single dot.
* `gl.LINE_STRIP`: Draws a straight line to the next vertex.
* `gl.LINE_LOOP`: Draws a straight line to the next vertex, and connects the last vertex back to the first.
* `gl.LINES`: Draws a line between a pair of vertices.
* `gl.TRIANGLE_STRIP`
* `gl.TRIANGLE_FAN`
* `gl.TRIANGLES`: Draws a triangle for a group of three vertices.

`first`

A `GLint` specifying the starting index in the array of vector points.

`count`

A `GLsizei` specifying the number of indices to be rendered.

`primcount`

A `GLsizei` specifying the number of instances of the range of elements to execute.

### Return value

None (`undefined`).

### Exceptions

* If `mode` is not one of the accepted values, a `gl.INVALID_ENUM` error is thrown.
* If `first`, `count` or `primcount` are negative, a `gl.INVALID_VALUE` error is thrown.
* if `gl.CURRENT_PROGRAM` is `null`, a `gl.INVALID_OPERATION` error is thrown.
Examples
--------

```js
const ext = gl.getExtension("ANGLE\_instanced\_arrays");
ext.drawArraysInstancedANGLE(gl.POINTS, 0, 8, 4);
```

Specifications
--------------

| Specification |
| --- |
| WebGL ANGLE\_instanced\_arrays Khronos Ratified Extension Specification  |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `ext.drawElementsInstancedANGLE()`
* `ext.vertexAttribDivisorANGLE()`
* `WebGLRenderingContext.drawArrays()`
* `WebGLRenderingContext.drawElements()`
* `WebGL2RenderingContext.drawArraysInstanced()`
* `WebGL2RenderingContext.drawElementsInstanced()`
* `WebGL2RenderingContext.vertexAttribDivisor()`
* `WEBGL_multi_draw.multiDrawArraysInstancedWEBGL()`


ANGLE_instanced_arrays: drawElementsInstancedANGLE() method - Web APIs

ANGLE\_instanced\_arrays: drawElementsInstancedANGLE() method
=============================================================

The **`ANGLE_instanced_arrays.drawElementsInstancedANGLE()`** method of the WebGL API renders primitives from array data like the `gl.drawElements()` method. In addition, it can execute multiple instances of a set of elements.

**Note:** When using `WebGL2`, this method is available as `gl.drawElementsInstanced()` by default.

Syntax
------

```js
drawElementsInstancedANGLE(mode, count, type, offset, primcount)
```

### Parameters

`mode`

A `GLenum` specifying the type primitive to render. Possible values are:

* `gl.POINTS`: Draws a single dot.
* `gl.LINE_STRIP`: Draws a straight line to the next vertex.
* `gl.LINE_LOOP`: Draws a straight line to the next vertex, and connects the last vertex back to the first.
* `gl.LINES`: Draws a line between a pair of vertices.
* `gl.TRIANGLE_STRIP`
* `gl.TRIANGLE_FAN`
* `gl.TRIANGLES`: Draws a triangle for a group of three vertices.

`count`

A `GLsizei` specifying the number of elements to be rendered.

`type`

A `GLenum` specifying the type of the values in the element array buffer. Possible values are:

* `gl.UNSIGNED_BYTE`
* `gl.UNSIGNED_SHORT`
* `gl.UNSIGNED_INT` when using the `OES_element_index_uint` extension.

`offset`

A `GLintptr` specifying an offset in the element array buffer. Must be a valid multiple of the size of the given `type`.

`primcount`

A `GLsizei` specifying the number of instances of the set of elements to execute.

### Return value

None (`undefined`).

### Exceptions

* If `mode` is not one of the accepted values, a `gl.INVALID_ENUM` error is thrown.
* If `offset` is an invalid multiple of the size of the given type, a `gl.INVALID_OPERATION` error is thrown.
* If `count` or `primcount` are negative, a `gl.INVALID_VALUE` error is thrown.
Examples
--------

```js
const ext = gl.getExtension("ANGLE\_instanced\_arrays");
ext.drawElementsInstancedANGLE(gl.POINTS, 2, gl.UNSIGNED\_SHORT, 0, 4);
```

Specifications
--------------

| Specification |
| --- |
| WebGL ANGLE\_instanced\_arrays Khronos Ratified Extension Specification  |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `ext.drawArraysInstancedANGLE()`
* `ext.vertexAttribDivisorANGLE()`
* `WebGLRenderingContext.drawArrays()`
* `WebGLRenderingContext.drawElements()`
* `WebGL2RenderingContext.drawArraysInstanced()`
* `WebGL2RenderingContext.drawElementsInstanced()`
* `WebGL2RenderingContext.vertexAttribDivisor()`
* `WEBGL_multi_draw.multiDrawElementsInstancedWEBGL()`


Transcoding assets for Media Source Extensions - Web APIs

Transcoding assets for Media Source Extensions
==============================================

When working with Media Source Extensions, it is likely that you need to condition your assets before you can stream them. This article takes you through the requirements and shows you a toolchain you can use to encode your assets appropriately.

Getting started
---------------

1. The first and most important step is to ensure that your files are comprised of a container and codec that users' browsers support.
2. Depending on the codec, you might need to fragment the file to comply with the ISO BMFF spec.
3. (Optional) If you decide to use Dynamic Adaptive Streaming over HTTP (DASH) for adaptive bitrate streaming, you need to transcode your assets into multiple resolutions. Most DASH clients expect a corresponding Media Presentation Description (MPD) manifest file, which is typically generated while generating the multiple resolution asset files.

Below we'll cover all of these steps, but first let's look at a toolchain we can use to do this fairly easily.

### Sample Media

If you're looking to follow the steps listed here, but don't have any media to experiment with, you can grab the trailer to Big Buck Bunny. Big Buck Bunny copyrighted by the Blender Foundation and is licensed under the Creative Commons Attribution 3.0 license. Throughout this tutorial, you'll see the filename trailer\_1080p.mov, which is the download.

### Tools required

When working with MSE, the following tools are a must have:

1. ffmpeg — A command-line utility for transcoding your media into the required formats. You can download a version for your system at the Download FFmpeg page. Extract the executable from the archive file and add it's location to your PATH statement. OSX users can also use homebrew to install ffmpeg.
2. Bento4 — A set of command-line utilities for getting asset metadata and creating content for DASH. To install, you'll need to build/compile the application yourself from the provided project files/source files, depending on your OS and preferences. See the Building instructions for more details. The prebuilt file is here. Put the contents of the `bin` directory in the same place as ffmpeg.
3. python2 — Bento4 uses it.

Get these installed successfully before moving to the next step.

Sample media should be placed in the Bento4 `utils` directory and worked here.

**Note:** The prebuilt ffmpeg does not include libfdk\_aac due to licensing reasons. Bento4 uses this by default, so you need to compile ffmpeg if necessary. If you don't need it, add `--audio-codec=aac` to the `mp4-dash-encode.py` command line.

### Container and Codec Support

As specified in section 1.1 of the MSE spec: Goals, MSE is designed not to require support for any particular media format or codec. While this is true on paper, browser support varies for specific container/codec combinations.

To check if the browser supports a particular container, you can pass a string of the MIME type to the `MediaSource.isTypeSupported()` method:

```js
MediaSource.isTypeSupported("audio/mp3"); // false
MediaSource.isTypeSupported("video/mp4"); // true
MediaSource.isTypeSupported('video/mp4; codecs="avc1.4D4028, mp4a.40.2"'); // true
```

The string is the MIME type of the container, optionally followed by a list of codecs. While the MIME type is fairly simple to figure out, we can get the codec string using the mp4info utility.

Currently, MP4 containers with H.264 video and AAC audio codecs have support across all modern browsers, while others don't.

To convert our sample media from a QuickTime MOV container to an MP4 container, we can use ffmpeg. Because the audio codec in the MOV container is already AAC and the video codec is h.264, we can instruct ffmpeg not to perform transcoding. Instead, it will just copy the audio and video tracks over without performing any transcoding, which is relatively faster than having to transcode.

```bash
ffmpeg -i trailer_1080p.mov -c:v copy -c:a copy bunny.mp4
```

### Checking Fragmentation

In order to properly stream MP4, we need the asset to be an ISO BMF format MP4. Without proper fragmentation, any given MP4 file is not guaranteed to work with MSE. This means that metadata within the container is spread out and not lumped together.

To check whether an MP4 file is a proper MP4 stream, you can again use the mp4info utility to list the atoms of an MP4.

**Note:** The fragmented version is slightly larger than the original, due to additional metadata spread throughout the file. This is usually a file size increase of 1 percent or less.

### Fragmenting

If you have an asset that is not already an MP4, ffmpeg can handle emitting a properly fragmented MP4 during the transcode process, with the `-movflags frag_keyframe+empty_moov` command line flag:

```bash
ffmpeg -i trailer_1080p.mov -c:v copy -c:a copy -movflags frag_keyframe+empty_moov bunny_fragmented.mp4
```

If you already have an MP4, but it's not properly fragmented, you can again use ffmpeg:

```bash
ffmpeg -i non_fragmented.mp4 -movflags frag_keyframe+empty_moov fragmented.mp4
```

In both cases, Chrome may require an extra movie flag to be set:

```bash
-movflags frag_keyframe+empty_moov+default_base_moof
```

Having a properly fragmented MP4 file is all you need to get started. If you wish to employ adaptive bitrate streaming, you'll have to create encodings at multiple resolutions. While MSE is flexible enough to allow you to make your implementation, it's highly recommended to use an existing DASH client as DASH is a well-specified application protocol.

### Creating Content for DASH

Given that you have ffmpeg and Bento4's utilities accessible through your $PATH, you can run Bento4's `mp4-dash-encode.py` Python script to generate multiple encodings of your content at various resolutions. Bento4's `mp4-dash.py` Python script can then be used to generate the corresponding MPD file needed by clients.

Run the following commands:

```bash
python mp4-dash-encode.py -b 5 -v bunny_fragmented.mp4
python mp4-dash.py video_0*
```

This should output the following files:
```

output
├── audio
│   └── und
├── stream.mpd
└── video
    ├── 1
    ├── 2
    ├── 3
    ├── 4
    └── 5
```

**Note:** `mp4-dash-encode.py` does not display ffmpeg error messages. You can see it by specifying the `-d` option.

**Note:** If `"Invalid duration specification for force_key_frames: 'expr:eq(mod(n"` is displayed as an error message, modify `mp4-dash-encode.py` and remove two `"'"` from `"-force_key_frames 'expr:eq(mod(n,%d),0)'"`.

Summary
-------

With your video properly encoded and adaptive bitrate media generated, you're now ready to begin adaptive bitrate streaming on the web using DASH and MSE.


RTCInboundRtpStreamStats: fecPacketsDiscarded property - Web APIs

RTCInboundRtpStreamStats: fecPacketsDiscarded property
======================================================

 The **`fecPacketsDiscarded`** property
 of the `RTCInboundRtpStreamStats` dictionary is a numeric value
 indicating the number of RTP Forward Error Correction (FEC) packets
 that have been discarded.

Value
-----

 An unsigned integer value indicating how many FEC packets have been received whose
 error correction payload has been discarded.

 This can happen if all the packets covered by the FEC packet have already been received
 or recovered using another FEC packet, or if the FEC packet arrived outside the recovery
 window and the lost RTP packets have already been skipped during playback as a result.
 The value of `fecPacketsReceived` includes these discarded packets.

Specifications
--------------

| Specification |
| --- |
| Identifiers for WebRTC's Statistics API # dom-rtcinboundrtpstreamstats-fecpacketsdiscarded |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


RTCInboundRtpStreamStats: averageRtcpInterval property - Web APIs

RTCInboundRtpStreamStats: averageRtcpInterval property
======================================================

 The **`averageRtcpInterval`** property
 of the `RTCInboundRtpStreamStats` dictionary is a floating-point value
 indicating the average RTCP transmission interval, in seconds.

 The RTCP interval is the amount of time that should elapse between transmissions of RTCP
 packets.

Value
-----

 A floating-point value indicating the average interval, in seconds, between
 transmissions of RTCP packets. This interval is computed following the formula outlined
 in RFC 1889: A.7.

 Because the interval's value is determined in part by the number of active senders, it
 will be different for each user of a service. Since this value is also used to determine
 the number of seconds after a stream starts to flow before the first RTCP packet should
 be sent, the result is that if many users try to start using the service at the same
 time, the server won't be flooded with RTCP packets coming in all at once.

 The sending endpoint computes this value when sending compound RTCP packets, which must
 contain at least an RTCP RR or SR packet and an SDES packet with the CNAME item.

Specifications
--------------

#### No specification found

No specification data found for `api.RTCInboundRtpStreamStats.averageRtcpInterval`.
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


RTCInboundRtpStreamStats: firCount property - Web APIs

RTCInboundRtpStreamStats: firCount property
===========================================

 The **`firCount`** property of the
 `RTCInboundRtpStreamStats` dictionary indicates the number of
 **Full Intra Request** (**FIR**) packets have been sent by
 the receiver to the sender.

 The receiver sends a FIR packet when the stream
 falls behind and needs to skip frames in order to catch up.

Value
-----

 An integer value indicating how many FIR packets have been received by the sender
 during the current connection. This statistic is available only for video tracks.

 The receiver sends a FIR packet to the sender any time it falls behind or loses packets
 and cannot decode the incoming stream any longer because of the lost data. This tells
 the sender to send a full frame instead of a delta frame, so that the receiver can catch
 up.

 The higher `firCount` is, the more often frames were dropped, which may be
 an indication that the media's bit rate is too high for the available bandwidth, or that
 the receiving device is overburdened and is therefore unable to process the incoming
 data.

Specifications
--------------

#### No specification found

No specification data found for `api.RTCInboundRtpStreamStats.firCount`.
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


RTCInboundRtpStreamStats: remoteId property - Web APIs

RTCInboundRtpStreamStats: remoteId property
===========================================

 The **`remoteId`** property of the
 `RTCInboundRtpStreamStats` dictionary specifies the `id` of the `RTCRemoteOutboundRtpStreamStats` object representing the remote peer's `RTCRtpSender` which is sending the media to the local peer.

Value
-----

 A string containing the ID of the
 `RTCRemoteOutboundRtpStreamStats` object that represents the remote peer's
 `RTCRtpSender` for the synchronization source represented by this stats
 object.

Specifications
--------------

| Specification |
| --- |
| Identifiers for WebRTC's Statistics API # dom-rtcinboundrtpstreamstats-remoteid |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


RTCInboundRtpStreamStats: pliCount property - Web APIs

RTCInboundRtpStreamStats: pliCount property
===========================================

 The **`pliCount`** property of the
 `RTCInboundRtpStreamStats` dictionary states the number of times the
 `RTCRtpReceiver` described by these statistics sent a **Picture
Loss Indication** (**PLI**) packet to the sender.

 A PLI
 packet indicates that some amount of encoded video data has been lost for one or more
 frames.

Value
-----

 An integer value indicating the number of times a PLI packet was sent by the
 `RTCRtpReceiver` to the sender. These are sent by the receiver's decoder to
 notify the encoder (the sender) that an undefined amount of coded video data, which may
 span frame boundaries, has been lost. This information is only available for video
 streams.

 This may trigger the sender to send a full frame in order to allow the receiver to
 re-synchronize, since lost data may be an irrecoverable situation for decoding media.
 However, the primary purpose of this message is to allow the sender to consider
 techniques to mitigate network performance issues. This is often achieved by methods
 such as increasing the compression, lowering resolution, or finding other ways to reduce
 the bit rate of the stream.

Specifications
--------------

#### No specification found

No specification data found for `api.RTCInboundRtpStreamStats.pliCount`.
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* RFC 4585, section 6.3.1: Definition of "PLI messages" in the document *Extended
RTP Profile for Real-time Transport Control Protocol (RTCP)-Based Feedback
(RTP/AVPF)*.


RTCInboundRtpStreamStats: bytesReceived property - Web APIs

RTCInboundRtpStreamStats: bytesReceived property
================================================

 The `RTCInboundRtpStreamStats` dictionary's
 **`bytesReceived`** property is an integer value which
 indicates the total number of bytes received so far from this synchronization source
 (SSRC).

Value
-----

 An unsigned integer value indicating the total number of bytes received so far on this
 RTP stream, not including header and padding bytes. This value can be used to calculate
 an approximation of the average media data rate:

```js
avgDataRate = rtcInboundRtpStreamStats.bytesReceived / elapsedTime;
```

This value gets reset to zero if the sender's SSRC identifier changes for any reason.

Specifications
--------------

| Specification |
| --- |
| Identifiers for WebRTC's Statistics API # dom-rtcinboundrtpstreamstats-bytesreceived |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


RTCInboundRtpStreamStats: type property - Web APIs

RTCInboundRtpStreamStats: type property
=======================================

The **`type`** property of the `RTCInboundRtpStreamStats` dictionary is a string with the value `"inbound-rtp"`.

 Different statistics are obtained by iterating the `RTCStatsReport` object returned by a call to `RTCPeerConnection.getStats()`.
 The type indicates the set of statistics available through the object in a particular iteration step.
 A value of `"inbound-rtp"` indicates that the statistics available in the current step are those defined in `RTCInboundRtpStreamStats`.

Value
-----

A string with the value `"inbound-rtp"`.

Specifications
--------------

| Specification |
| --- |
| Identifiers for WebRTC's Statistics API # dom-rtcstats-type |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


RTCInboundRtpStreamStats: timestamp property - Web APIs

RTCInboundRtpStreamStats: timestamp property
============================================

The **`timestamp`** property of the `RTCInboundRtpStreamStats` dictionary is a `DOMHighResTimeStamp` object specifying the time at which the data in the object was sampled.

Value
-----

A `DOMHighResTimeStamp` value indicating the time at which the activity described by the statistics in this object was recorded, in milliseconds elapsed since the beginning of January 1, 1970, UTC.

The value should be accurate to within a few milliseconds but may not be entirely precise, either because of hardware or operating system limitations or because of fingerprinting protection in the form of reduced clock precision or accuracy.

Specifications
--------------

| Specification |
| --- |
| Identifiers for WebRTC's Statistics API # dom-rtcstats-timestamp |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


RTCInboundRtpStreamStats: packetsDuplicated property - Web APIs

RTCInboundRtpStreamStats: packetsDuplicated property
====================================================

 The **`packetsDuplicated`** property
 of the `RTCInboundRtpStreamStats` dictionary indicates the total number
 of packets discarded because they were duplicates of previously-received
 packets.

 These packets are not counted by the
 `packetsDiscarded` property.

Value
-----

 An integer value which specifies how many duplicate packets have been received by the
 local end of this RTP stream so far. These duplicate packets are not included in the
 `packetsDiscarded` property.

Usage notes
-----------

 Duplicate packets are detected when a packet has the same RTP sequence number as
 another packet that has previously been processed. Each time a packet is repeated, the
 value of `packetsDuplicated` is incremented, even if the same packet is
 received more than twice.

 You can get a more accurate tally of how many packets have been lost on the stream by
 adding `packetsDuplicated` to
 `packetsLost`. The resulting value
 will be positive, although it will not match the count as computed in RFC 3660.

Specifications
--------------

#### No specification found

No specification data found for `api.RTCInboundRtpStreamStats.packetsDuplicated`.
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


RTCInboundRtpStreamStats: framesDecoded property - Web APIs

RTCInboundRtpStreamStats: framesDecoded property
================================================

 The **`framesDecoded`** property of
 the `RTCInboundRtpStreamStats` dictionary indicates the total number of
 frames which have been decoded successfully for this media source.

Value
-----

 An integer value indicating the total number of video frames which have been decoded
 for this stream so far. This represents the number of frames that would have been
 displayed assuming no frames were skipped.

Specifications
--------------

#### No specification found

No specification data found for `api.RTCInboundRtpStreamStats.framesDecoded`.
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


RTCInboundRtpStreamStats: fecPacketsReceived property - Web APIs

RTCInboundRtpStreamStats: fecPacketsReceived property
=====================================================

 The **`fecPacketsReceived`** property
 of the `RTCInboundRtpStreamStats` dictionary indicates how many
 Forward Error Correction (FEC) packets have been received by this RTP receiver
 from the remote peer.

 An FEC packet provides parity information which can
 be used to attempt to reconstruct RTP data packets which have been corrupted in
 transit.

Syntax
------

```js
const fecPacketsReceived = rtcInboundRtpStreamStats.fecPacketsReceived
```

### Value

 An unsigned integer value which indicates the total number of FEC packets which have
 been received from the remote peer during this RTP session. Forward Error Correction
 uses an exclusive-or method to perform parity checks on the received data.

 By using the FEC parity information to attempt to reconstruct damaged packets, it is
 possible to avoid the need to retransmit damaged packets, which in turn helps to
 reduce lag, or the need to skip damaged frames entirely.

**Note:** This counter may also be incremented when FEC packets arrive
 in-band along with media content; this can happen with Opus, for example.

Usage notes
-----------

 It's possible that a subset of the FEC packets which have been received were discarded
 instead of being used. This can happen if the packets covered by the FEC packets have
 already been received successfully or have already been reconstructed using a
 previously-received FEC packet. This may also happen if the FEC packet arrives outside
 the window of time in which the client will attempt to use it.

 If you wish to know how many of the received packets were discarded, you can examine
 the value of `fecPacketsDiscarded`.

Specifications
--------------

| Specification |
| --- |
| Identifiers for WebRTC's Statistics API # dom-rtcinboundrtpstreamstats-fecpacketsreceived |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* RFC 5109 (RTP Payload Format for Generic Forward Error Correction)


RTCInboundRtpStreamStats: qpSum property - Web APIs

RTCInboundRtpStreamStats: qpSum property
========================================

 The **`qpSum`** property of the
 `RTCInboundRtpStreamStats` dictionary is a value generated by adding the
 **Quantization Parameter** (**QP**) values for every frame
 sent or received to date on the video track corresponding to this
 `RTCInboundRtpStreamStats` object.

 In general, the higher this
 number is, the more heavily compressed the video data is.

Value
-----

 An unsigned 64-bit integer value which indicates the sum of the quantization parameter
 (QP) value for every frame sent or received so far on the track described by the
 `RTCInboundRtpStreamStats` object. Since the value of QP is typically
 larger to indicate higher compression factors, the larger this sum is, the more heavily
 compressed the stream generally has been.

**Note:** This value is only available for video media.

Usage notes
-----------

Quantization is the process of applying lossy compression
 to a range of values, resulting in a single **quantum value**. This value
 takes the place of the range of values, thereby reducing the number of different values
 that appear in the overall data set, making the data more compressible. The quantization
 process and the amount of compression can be controlled using one or more parameters.

 It's important to keep in mind that the value of QP can change periodically—even every
 frame—so it's difficult to know for certain how substantial the compression is. The best
 you can do is make an estimate. You can, for example, use the value of
 `RTCReceivedRtpStreamStats.framesDecoded` if receiving the media or
 `RTCSentRtpStreamStats.framesEncoded` if sending it to get the number of
 frames handled so far, and compute an average from there. See Calculating average quantization below for a function that does this.

 Also, the exact meaning of the QP value depends on the codec being
 used. For example, for the VP8 codec, the QP value can be anywhere from 1 to 127 and is
 found in the frame header element `"y_ac_qi"`, whose value is defined in
 RFC 6386, section 19.2. H.264 uses a QP which ranges from 0 to 51; in this case, it's an
 index used to derive a scaling matrix used during the quantization process.
 Additionally, QP is not likely to be the only parameter the codec uses to adjust the
 compression. See the individual codec specifications for details.

Examples
--------

### Calculating average quantization

 The `calculateAverageQP()` function shown below computes the average QP for
 the given `RTCStatsReport` object that contains RTP stream statistics, returning
 0 if the object doesn't describe an RTP stream.

```js
function calculateAverageQP(stats) {
  let frameCount = 0;

  switch (stats.type) {
    case "inbound-rtp":
    case "remote-inbound-rtp":
      frameCount = stats.framesDecoded;
      break;
    case "outbound-rtp":
    case "remote-outbound-rtp":
      frameCount = stats.framesEncoded;
      break;
    default:
      return 0;
  }

  return status.qpSum / frameCount;
}
```

Specifications
--------------

#### No specification found

No specification data found for `api.RTCInboundRtpStreamStats.qpSum`.
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


RTCInboundRtpStreamStats: id property - Web APIs

RTCInboundRtpStreamStats: id property
=====================================

The **`id`** property of the `RTCInboundRtpStreamStats` dictionary is a string that uniquely identifies the object for which this object provides statistics.

Using the `id`, you can correlate this statistics object with others, in order to monitor statistics over time for a given WebRTC object, such as an `RTCPeerConnection`, or an `RTCDataChannel`.

Value
-----

A string that uniquely identifies the object for which this `RTCInboundRtpStreamStats` object provides statistics.

The format of the ID string is not defined by the specification, so you cannot reliably make any assumptions about the contents of the string, or assume that the format of the string will remain unchanged for a given object type.

Specifications
--------------

| Specification |
| --- |
| Identifiers for WebRTC's Statistics API # dom-rtcstats-id |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


RTCInboundRtpStreamStats: nackCount property - Web APIs

RTCInboundRtpStreamStats: nackCount property
============================================

 The **`nackCount`** property of the
 `RTCInboundRtpStreamStats` dictionary is a numeric value indicating the
 number of times the receiver sent a **NACK** packet to the sender.

 A NACK (Negative ACKnowledgement, also called "Generic NACK") packet tells the sender
 that one or more of the RTP packets it sent were lost in transport.

Value
-----

 An integer value indicating how many times the receiver sent a NACK packet to the
 sender after detecting that one or more packets were lost during transport.

Specifications
--------------

| Specification |
| --- |
| Identifiers for WebRTC's Statistics API # dom-rtcinboundrtpstreamstats-nackcount |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


RTCInboundRtpStreamStats: lastPacketReceivedTimestamp property - Web APIs

RTCInboundRtpStreamStats: lastPacketReceivedTimestamp property
==============================================================

The **`lastPacketReceivedTimestamp`** property of the `RTCInboundRtpStreamStats` dictionary indicates the time at which the most recently received packet arrived from this source.

Value
-----

A `DOMHighResTimeStamp` which specifies the time at which the most recently received packet arrived on this RTP stream.

**Note:** This value differs from the `timestamp`,
 which represents the time at which the statistics object was created.

Specifications
--------------

| Specification |
| --- |
| Identifiers for WebRTC's Statistics API # dom-rtcinboundrtpstreamstats-lastpacketreceivedtimestamp |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


RTCInboundRtpStreamStats: trackId property - Web APIs

RTCInboundRtpStreamStats: trackId property
==========================================

**Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

The **`trackId`** property of the `RTCInboundRtpStreamStats` dictionary indicates the `id` of the `RTCReceiverAudioTrackAttachmentStats` or `RTCReceiverVideoTrackAttachmentStats` object representing the `MediaStreamTrack` which is receiving the incoming media.

Value
-----

A string containing the ID of the `RTCReceiverAudioTrackAttachmentStats` or `RTCReceiverVideoTrackAttachmentStats` object representing the track which is receiving the media from this RTP session.

Specifications
--------------

#### No specification found

No specification data found for `api.RTCInboundRtpStreamStats.trackId`.
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


RTCInboundRtpStreamStats: sliCount property - Web APIs

RTCInboundRtpStreamStats: sliCount property
===========================================

 The **`sliCount`** property of the
 `RTCInboundRtpStreamStats` dictionary indicates how many **Slice
Loss Indication** (**SLI**) packets the
 `RTCRtpReceiver` for which this object provides statistics sent to the
 remote `RTCRtpSender`.

 An SLI packet is used by a decoder to let
 the encoder know that it's detected corruption of one or more consecutive macroblocks
 (in scan order) in the received media.

 In general, what's usually of interest is that the higher this number is, the more the
 stream data is becoming corrupted between the sender and the receiver, requiring resends
 or dropping frames.

Value
-----

 An unsigned integer indicating the number of SLI packets this receiver sent to the
 remote sender due to lost runs of macroblocks. A high value of `sliCount` may
 be an indication of an unreliable network.

This is a very technical part of how video codecs work. For details, see RFC 4585: 6.3.2.

**Note:** This value is only present for video media.

Specifications
--------------

#### No specification found

No specification data found for `api.RTCInboundRtpStreamStats.sliCount`.
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* RFC 4585, section 6.3.2: Definition of "Slice Loss Indication" in the document
 *Extended RTP Profile for Real-time Transport Control Protocol (RTCP)-Based
Feedback (RTP/AVPF)*.


RTCInboundRtpStreamStats: perDscpPacketsReceived property - Web APIs

RTCInboundRtpStreamStats: perDscpPacketsReceived property
=========================================================

 The **`perDscpPacketsReceived`**
 property of the `RTCInboundRtpStreamStats` dictionary is a record
 comprised of key/value pairs in which each key is a string representation of a
 Differentiated Services Code Point and the value is the number of packets received for
 that DCSP.

**Note:** Not all operating systems make data available on a per-DSCP
 basis, so this property shouldn't be relied upon on those systems.

Value
-----

 A record comprised of string/value pairs. Each key is the string representation of a
 single Differentiated Services Code Point (DSCP)'s ID number.

**Note:** Due to network bleaching and remapping, the numbers seen on
 this record are not necessarily going to match the values as they were when the data
 was sent.

Specifications
--------------

#### No specification found

No specification data found for `api.RTCInboundRtpStreamStats.perDscpPacketsReceived`.
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* RFC 2474: The Differentiated Service field in IPv4 and IPv6 headers


RTCInboundRtpStreamStats: packetsFailedDecryption property - Web APIs

RTCInboundRtpStreamStats: packetsFailedDecryption property
==========================================================

 The **`packetsFailedDecryption`**
 property of the `RTCInboundRtpStreamStats` dictionary indicates the total
 number of RTP packets which failed to be decrypted successfully after
 being received by the local end of the connection during this session.

Value
-----

 An integer value which indicates how many packets the local end of the RTP connection
 could not be successfully decrypted.

Specifications
--------------

#### No specification found

No specification data found for `api.RTCInboundRtpStreamStats.packetsFailedDecryption`.
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* RFC 3711, section 3.3: Description of the decryption process for secure RTP packets


RTCInboundRtpStreamStats: receiverId property - Web APIs

RTCInboundRtpStreamStats: receiverId property
=============================================

The **`receiverId`** property of the `RTCInboundRtpStreamStats` dictionary specifies the `id` of the `RTCAudioReceiverStats` or `RTCVideoReceiverStats` object representing the `RTCRtpReceiver` receiving the stream.

Value
-----

A string which contains the ID of the `RTCAudioReceiverStats` or `RTCVideoReceiverStats` object which provides information about the `RTCRtpReceiver` which is receiving the streamed media.

Specifications
--------------

#### No specification found

No specification data found for `api.RTCInboundRtpStreamStats.receiverId`.
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


SVGPointList: removeItem() method - Web APIs

SVGPointList: removeItem() method
=================================

The **`removeItem()`** method of the `SVGPointList` interface removes a `point` from the list.

Syntax
------

```js
removeItem(index)
```

### Parameters

`index`

The index of the item to remove.

### Return value

The removed `SVGPoint` object.

### Exceptions

`NoModificationAllowedError` `DOMException`

Thrown if the list is read-only.

`IndexSizeError` `DOMException`

Thrown if the index passed in is greater than the number of items in the list.

Examples
--------

The following example shows an SVG which contains a `<polyline>` with five coordinate pairs. The item at index `2` is removed.

```html
<svg id="svg" viewBox="-10 -10 120 120" xmlns="http://www.w3.org/2000/svg">
  <polyline
 id="example"
 stroke="black"
 fill="none"
 points="50,0 21,90 98,35 2,35 79,90" />
</svg>
```

```js
let example = document.getElementById("example");
console.log(example.points.removeItem(2));
```

Specifications
--------------

| Specification |
| --- |
| Scalable Vector Graphics (SVG) 2 # \_\_svg\_\_SVGNameList\_\_removeItem |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


SVGPointList: clear() method - Web APIs

SVGPointList: clear() method
============================

The **`clear()`** method of the `SVGPointList` interface removes all items from the list.

Syntax
------

```js
clear()
```

### Parameters

None.

### Return value

None (`undefined`).

### Exceptions

`NoModificationAllowedError` `DOMException`

Thrown if the list is read-only.

Examples
--------

The following example shows an SVG which contains a `<polyline>` with five coordinate pairs. Calling `clear()` empties the list. Therefore the polyline no longer displays in the SVG.

```html
<svg id="svg" viewBox="-10 -10 120 120" xmlns="http://www.w3.org/2000/svg">
  <polyline
 id="example"
 stroke="black"
 fill="none"
 points="50,0 21,90 98,35 2,35 79,90" />
</svg>
```

```js
let example = document.getElementById("example");
example.points.clear();
```

Specifications
--------------

| Specification |
| --- |
| Scalable Vector Graphics (SVG) 2 # \_\_svg\_\_SVGNameList\_\_clear |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


SVGPointList: insertItemBefore() method - Web APIs

SVGPointList: insertItemBefore() method
=======================================

The **`insertItemBefore()`** method of the `SVGPointList` interface inserts a `point` before another item in the list.

Syntax
------

```js
insertItemBefore(obj, index)
```

### Parameters

`obj`

An `SVGPoint` object containing the coordinates of the point to be inserted.

`index`

The index of the item the object should be inserted before. If the index passed in is greater than the length of the list, then index will be set to the list length and the item inserted before the last item in the list.

### Return value

The `SVGPoint` object that was inserted.

### Exceptions

`NoModificationAllowedError` `DOMException`

Thrown if the list is read-only.

Examples
--------

The following example shows an SVG which contains a `<polyline>` with five coordinate pairs. A new `SVGPoint` is created, and inserted before the point at index `2`.

```html
<svg id="svg" viewBox="-10 -10 120 120" xmlns="http://www.w3.org/2000/svg">
  <polyline
 id="example"
 stroke="black"
 fill="none"
 points="50,0 21,90 98,35 2,35 79,90" />
</svg>
```

```js
let example = document.getElementById("example");
let svgpoint = document.getElementById("svg").createSVGPoint();
svgpoint.y = 10;
svgpoint.x = 10;
console.log(example.points.insertItemBefore(svgpoint, 2));
```

Specifications
--------------

| Specification |
| --- |
| Scalable Vector Graphics (SVG) 2 # \_\_svg\_\_SVGNameList\_\_insertItemBefore |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.