GPURenderPassEncoder: executeBundles() method - Web APIs

GPURenderPassEncoder: executeBundles() method
=============================================

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

 The **`executeBundles()`** method of the
 `GPURenderPassEncoder` interface executes commands previously recorded into the referenced `GPURenderBundle`s, as part of this render pass.

**Note:** After calling `executeBundles()` the currently set vertex buffers, index buffers, bind groups, and pipeline are all cleared, even if no bundles are actually executed.

Syntax
------

```js
executeBundles(bundles)
```

### Parameters

`bundles`

An array of `GPURenderBundle` objects, containing the pre-recorded commands to execute.

### Return value

None (`Undefined`).

### Validation

The following criteria must be met when calling **`executeBundles()`**, otherwise a `GPUValidationError` is generated and the `GPURenderPassEncoder` becomes invalid.

For each `GPURenderBundle`:

* If the render pass's `depthReadOnly` property (as specified in the descriptor of the originating `GPUCommandEncoder.beginRenderPass()` call) is `true`, then the bundle's `depthReadOnly` property (as specified in the descriptor of the `GPUDevice.createRenderBundleEncoder()` call that created the originating `GPURenderBundleEncoder`) is also `true`.
* If the render pass's `stencilReadOnly` property (as specified in the descriptor of the originating `GPUCommandEncoder.beginRenderPass()` call) is `true`, then the bundle's `stencilReadOnly` property (as specified in the descriptor of the `GPUDevice.createRenderBundleEncoder()` call that created the originating `GPURenderBundleEncoder`) is also `true`.
* The layout of the render pipeline specified in `GPURenderPassEncoder.setPipeline()` (as defined in the descriptor of the originating `GPUDevice.createRenderPipeline()` call) equals the layout of the render bundle pipeline specified in `GPURenderBundleEncoder.setPipeline()`.
Examples
--------

In the WebGPU Samples Animometer example, a lot of like operations are done on many different objects simultaneously. `executeBundles()` is used to reuse the work on multiple render passes to improve performance. Study the example code listing for the full context.

```js
// ...

return function doDraw(timestamp) {
  if (startTime === undefined) {
    startTime = timestamp;
  }
  uniformTime[0] = (timestamp - startTime) / 1000;
  device.queue.writeBuffer(uniformBuffer, timeOffset, uniformTime.buffer);

  renderPassDescriptor.colorAttachments[0].view = context
    .getCurrentTexture()
    .createView();

  const commandEncoder = device.createCommandEncoder();
  const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);

  if (settings.renderBundles) {
    passEncoder.executeBundles([renderBundle]);
  } else {
    recordRenderPass(passEncoder);
  }

  passEncoder.end();
  device.queue.submit([commandEncoder.finish()]);
};

// ...
```

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

| Specification |
| --- |
| WebGPU # dom-gpurenderpassencoder-executebundles |

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

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

See also
--------

* The WebGPU API


GPURenderPassEncoder: draw() method - Web APIs

GPURenderPassEncoder: draw() method
===================================

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

 The **`draw()`** method of the
 `GPURenderPassEncoder` interface draws primitives based on the vertex buffers provided by `setVertexBuffer()`.

Syntax
------

```js
draw(vertexCount)
draw(vertexCount, instanceCount)
draw(vertexCount, instanceCount, firstVertex)
draw(vertexCount, instanceCount, firstVertex, firstInstance)
```

### Parameters

`vertexCount`

A number defining the number of vertices to draw.

`instanceCount` Optional

A number defining the number of instances to draw. If omitted, `instanceCount` defaults to 1.

`firstVertex` Optional

A number defining the offset into the vertex buffers, in vertices, to begin drawing from. If omitted, `firstVertex` defaults to 0.

`firstInstance` Optional

A number defining the first instance to draw. If omitted, `firstInstance` defaults to 0.

### Return value

None (`Undefined`).

Examples
--------

In our basic render demo, several commands are recorded via a `GPUCommandEncoder`. Most of these commands originate from the `GPURenderPassEncoder` created via `GPUCommandEncoder.beginRenderPass()`. `draw()` is used to specify that three vertices should be drawn to create our triangle.

```js
// ...

const renderPipeline = device.createRenderPipeline(pipelineDescriptor);

// Create GPUCommandEncoder to issue commands to the GPU
// Note: render pass descriptor, command encoder, etc. are destroyed after use, fresh one needed for each frame.
const commandEncoder = device.createCommandEncoder();

// Create GPURenderPassDescriptor to tell WebGPU which texture to draw into, then initiate render pass
const renderPassDescriptor = {
  colorAttachments: [
    {
      clearValue: clearColor,
      loadOp: "clear",
      storeOp: "store",
      view: context.getCurrentTexture().createView(),
    },
  ],
};

const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);

// Draw the triangle
passEncoder.setPipeline(renderPipeline);
passEncoder.setVertexBuffer(0, vertexBuffer);
passEncoder.draw(3);

// End the render pass
passEncoder.end();

// End frame by passing array of command buffers to command queue for execution
device.queue.submit([commandEncoder.finish()]);

// ...
```

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

| Specification |
| --- |
| WebGPU # dom-gpurendercommandsmixin-draw |

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

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

See also
--------

* The WebGPU API


GPURenderPassEncoder: drawIndirect() method - Web APIs

GPURenderPassEncoder: drawIndirect() method
===========================================

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

 The **`drawIndirect()`** method of the
 `GPURenderPassEncoder` interface draws primitives using parameters read from a `GPUBuffer`.

Syntax
------

```js
drawIndirect(indirectBuffer, indirectOffset)
```

### Parameters

`indirectBuffer`

A `GPUBuffer` containing the `vertexCount`, `instanceCount`, `firstVertex`, and `firstInstance` values needed to carry out the drawing operation. The buffer must contain a tightly packed block of four 32-bit unsigned integer values representing the values (16 bytes total), given in the same order as the arguments for `GPURenderPassEncoder.draw()`. So for example:

```js
const uint32 = new Uint32Array(4);
uint32[0] = 3; // The vertexCount value
uint32[1] = 1; // The instanceCount value
uint32[2] = 0; // The firstVertex value
uint32[3] = 0; // The firstInstance value

// Write values into a GPUBuffer
device.queue.writeBuffer(buffer, 0, uint32, 0, uint32.length);
```

`indirectOffset`

The offset, in bytes, into `indirectBuffer` where the value data begins.

### Return value

None (`Undefined`).

### Validation

The following criteria must be met when calling **`drawIndirect()`**, otherwise a `GPUValidationError` is generated and the `GPURenderPassEncoder` becomes invalid:

* `indirectBuffer`'s `GPUBuffer.usage` contains the `GPUBufferUsage.INDIRECT` flag.
* `indirectOffset` + the total size specified by the value parameters in the `indirectBuffer` is less than or equal to the `indirectBuffer`'s `GPUBuffer.size`.
* `indirectOffset` is a multiple of 4.
Examples
--------

```js
// ...

// Create GPURenderPassEncoder
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);

// Set pipeline and vertex buffer
passEncoder.setPipeline(renderPipeline);
passEncoder.setVertexBuffer(0, vertexBuffer);

// Create drawIndirect values
const uint32 = new Uint32Array(4);
uint32[0] = 3;
uint32[1] = 1;
uint32[2] = 0;
uint32[3] = 0;

// Create a GPUBuffer and write the draw values into it
const drawValues = device.createBuffer({
  size: 16,
  usage: GPUBufferUsage.COPY\_DST | GPUBufferUsage.INDIRECT,
});
device.queue.writeBuffer(drawValues, 0, uint32, 0, uint32.length);

// Draw the vertices
passEncoder.drawIndirect(drawValues, 0);

// End the render pass
passEncoder.end();

// End frame by passing array of GPUCommandBuffers to command queue for execution
device.queue.submit([commandEncoder.finish()]);

// ...
```

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

| Specification |
| --- |
| WebGPU # dom-gpurendercommandsmixin-drawindirect |

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

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

See also
--------

* The WebGPU API


GPURenderPassEncoder: insertDebugMarker() method - Web APIs

GPURenderPassEncoder: insertDebugMarker() method
================================================

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

 The **`insertDebugMarker()`** method of the
 `GPURenderPassEncoder` interface marks a specific point in a series of encoded render pass commands with a label.

This could be used for telemetry, or may be utilized in `GPUError` messages, browser dev tools, or other services in the future to help with debugging.

Syntax
------

```js
insertDebugMarker(markerLabel)
```

### Parameters

`markerLabel`

A string representing the label to insert.

### Return value

None (`Undefined`).

Examples
--------

```js
// ...

passEncoder.insertDebugMarker("mymarker");

// ...
```

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

| Specification |
| --- |
| WebGPU # dom-gpudebugcommandsmixin-insertdebugmarker |

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

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

See also
--------

* The WebGPU API


GPURenderPassEncoder: label property - Web APIs

GPURenderPassEncoder: label property
====================================

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

 The **`label`** read-only property of the
 `GPURenderPassEncoder` interface is a string providing a label that can be used to identify the object, for example in `GPUError` messages or console warnings.

This can be set by providing a `label` property in the descriptor object passed into the originating `GPUCommandEncoder.beginRenderPass()` call, or you can get and set it directly on the `GPURenderPassEncoder` object.

Value
-----

A string. If no label value has previously been set, getting the label returns an empty string.

Examples
--------

Setting and getting a label via `GPURenderPassEncoder.label`:

```js
const commandEncoder = device.createCommandEncoder();

const renderPassDescriptor = {
  colorAttachments: [
    {
      clearValue: clearColor,
      loadOp: "clear",
      storeOp: "store",
      view: context.getCurrentTexture().createView(),
    },
  ],
};

const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
passEncoder.label = "myrenderpassencoder";

console.log(passEncoder.label); // "myrenderpassencoder"
```

Setting a label via the originating `GPUCommandEncoder.beginRenderPass()` call, and then getting it via `GPURenderPassEncoder.label`:

```js
const commandEncoder = device.createCommandEncoder();

const renderPassDescriptor = {
  colorAttachments: [
    {
      clearValue: clearColor,
      loadOp: "clear",
      storeOp: "store",
      view: context.getCurrentTexture().createView(),
    },
  ],
  label: "myrenderpassencoder",
};

const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);

console.log(passEncoder.label); // "myrenderpassencoder"
```

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

| Specification |
| --- |
| WebGPU # dom-gpuobjectbase-label |

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

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

See also
--------

* The WebGPU API


GPURenderPassEncoder: setScissorRect() method - Web APIs

GPURenderPassEncoder: setScissorRect() method
=============================================

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

 The **`setScissorRect()`** method of the
 `GPURenderPassEncoder` interface sets the scissor rectangle used during the rasterization stage. After transformation into viewport coordinates any fragments that fall outside the scissor rectangle will be discarded.

Syntax
------

```js
setScissorRect(x, y, width, height)
```

### Parameters

`x`

A number representing the minimum X value of the scissor rectangle, in pixels.

`y`

A number representing the minimum Y value of the scissor rectangle, in pixels.

`width`

A number representing the width of the scissor rectangle, in pixels.

`height`

A number representing the height of the scissor rectangle, in pixels.

**Note:** If a `setScissorRect()` call is not made, the default values are `(0, 0, attachment width, attachment height)` for each render pass.

### Return value

None (`Undefined`).

### Validation

The following criteria must be met when calling **`setViewport()`**, otherwise a `GPUValidationError` is generated and the `GPURenderPassEncoder` becomes invalid:

* `x` + `width` is less than or equal to the width of the render pass's render attachments (see note below).
* `y` + `height` is less than or equal to the height of the render pass's render attachments (see note below).

**Note:** See the color and depth/stencil attachments specified in the descriptor of `GPUCommandEncoder.beginRenderPass()`; the width and height are based on that of the `GPUTexture` that their `view`s originate from.

Examples
--------

### Basic snippet

In a typical canvas render, the following could be used to discard any rendering outside of the top-left quarter of the canvas:

```js
passEncoder.setScissorRect(0, 0, canvas.width / 2, canvas.height / 2);
```

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

| Specification |
| --- |
| WebGPU # dom-gpurenderpassencoder-setscissorrect |

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

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

See also
--------

* The WebGPU API


GPURenderPassEncoder: setBindGroup() method - Web APIs

GPURenderPassEncoder: setBindGroup() method
===========================================

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

 The **`setBindGroup()`** method of the
 `GPURenderPassEncoder` interface sets the `GPUBindGroup` to use for subsequent render commands, for a given index.

Syntax
------

```js
setBindGroup(index, bindGroup)
setBindGroup(index, bindGroup, dynamicOffsets)
setBindGroup(index, bindGroup, dynamicOffsets, dynamicOffsetsStart,
             dynamicOffsetsLength)
```

#### Parameters

`index`

The index to set the bind group at. This matches the `n` index value of the corresponding `@group(n)` attribute in the shader code (`GPUShaderModule`) used in the related pipeline.

`bindGroup`

The `GPUBindGroup` to use for subsequent render commands.

`dynamicOffsets` Optional

A value specifying the offset, in bytes, for each entry in `bindGroup` with `hasDynamicOffset: true` set (i.e. in the descriptor of the `GPUDevice.createBindGroupLayout()` call that created the `GPUBindGroupLayout` object that the `bindGroup` is based on). This value can be:

* An array of numbers specifying the different offsets.
* A `Uint32Array` containing numbers specifying the offsets.

If a `Uint32Array` value is specified for `dynamicOffsets`, both of the following parameters are also required:

`dynamicOffsetsStart`

A number specifying the offset, in array elements, into `dynamicOffsetsData`, where the dynamic offset data begins.

`dynamicOffsetsLength`

A number specifying the number of dynamic offset values to be read from in `dynamicOffsetsData`.

### Return value

None (`Undefined`).

### Exceptions

For `setBindGroup()` calls that use a `Uint32Array` value for `dynamicOffsets`, the call will throw with a `RangeError` `DOMException` if:

* `dynamicOffsetsStart` is less than 0.
* `dynamicOffsetsStart` + `dynamicOffsetsLength` is greater than `dynamicOffsets.length`.
### Validation

The following criteria must be met when calling **`setBindGroup()`**, otherwise a `GPUValidationError` is generated and the `GPURenderPassEncoder` becomes invalid:

* `index` is less than or equal to the `GPUDevice`'s `maxBindGroups` limit.
* `dynamicOffsets.length` is the same as the number of entries in `bindGroup` with `hasDynamicOffset: true` set.
* For `bindGroup` entries where the bound `buffer`'s `type` is `"uniform"` (see `GPUDevice.createBindGroupLayout()`), each number in `dynamicOffsets` is a multiple of the `GPUDevice`'s `minUniformBufferOffsetAlignment` limit.
* For `bindGroup` entries where the bound `buffer`'s `type` is `"storage"` or `"read-only-storage"` (see `GPUDevice.createBindGroupLayout()`), each number in `dynamicOffsets` is a multiple of the `GPUDevice`'s `minStorageBufferOffsetAlignment` limit.
* For each `bindGroup` entry, the bound `buffer`'s `offset`, plus the corresponding layout entry's `minBindingSize`, plus the corresponding dynamic offset specified in `dynamicOffsets`, is less than or equal to the bound `buffer`'s `size`.
Examples
--------

In the WebGPU Samples Textured Cube example, `setBindGroup()` is used to bind the `uniformBindGroup` to index position 0. Check out the example for the full context.

```js
// ...

const commandEncoder = device.createCommandEncoder();
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
passEncoder.setPipeline(pipeline);
passEncoder.setBindGroup(0, uniformBindGroup);
passEncoder.setVertexBuffer(0, verticesBuffer);
passEncoder.draw(cubeVertexCount, 1, 0, 0);
passEncoder.end();
device.queue.submit([commandEncoder.finish()]);

// ...
```

**Note:** Study the other WebGPU Samples for more examples of `setBindGroup()` usage.

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

| Specification |
| --- |
| WebGPU # programmable-passes-bind-groups |

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

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

See also
--------

* The WebGPU API


GPURenderPassEncoder: setVertexBuffer() method - Web APIs

GPURenderPassEncoder: setVertexBuffer() method
==============================================

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

 The **`setVertexBuffer()`** method of the
 `GPURenderPassEncoder` interface sets or unsets the current `GPUBuffer` for the given slot that will provide vertex data for subsequent drawing commands.

Syntax
------

```js
setVertexBuffer(slot, buffer, offset, size)
```

### Parameters

`slot`

A number referencing the vertex buffer slot to set the vertex buffer for.

`buffer`

A `GPUBuffer` representing the buffer containing the vertex data to use for subsequent drawing commands, or `null`, in which case any previously-set buffer in the given slot is unset.

`offset` Optional

A number representing the offset, in bytes, into `buffer` where the vertex data begins. If omitted, `offset` defaults to 0.

`size` Optional

A number representing the size, in bytes, of the vertex data contained in `buffer`. If omitted, `size` defaults to the `buffer`'s `GPUBuffer.size` - `offset`.

### Return value

None (`Undefined`).

### Validation

The following criteria must be met when calling **`setVertexBuffer()`**, otherwise a `GPUValidationError` is generated and the `GPURenderPassEncoder` becomes invalid:

* `buffer`'s `GPUBuffer.usage` contains the `GPUBufferUsage.VERTEX` flag.
* `slot` is less than the `GPUDevice`'s `maxVertexBuffers` limit.
* `offset` + `size` is less than or equal to the `buffer`'s `GPUBuffer.size`.
* `offset` is a multiple of 4.
Examples
--------

### Set vertex buffer

In our basic render demo, several commands are recorded via a `GPUCommandEncoder`. Most of these commands originate from the `GPURenderPassEncoder` created via `GPUCommandEncoder.beginRenderPass()`. `setVertexBuffer()` is used as appropriate to set the source of vertex data.

```js
// ...

const renderPipeline = device.createRenderPipeline(pipelineDescriptor);

// Create GPUCommandEncoder to issue commands to the GPU
// Note: render pass descriptor, command encoder, etc. are destroyed after use, fresh one needed for each frame.
const commandEncoder = device.createCommandEncoder();

// Create GPURenderPassDescriptor to tell WebGPU which texture to draw into, then initiate render pass
const renderPassDescriptor = {
  colorAttachments: [
    {
      clearValue: clearColor,
      loadOp: "clear",
      storeOp: "store",
      view: context.getCurrentTexture().createView(),
    },
  ],
};

const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);

// Draw the triangle
passEncoder.setPipeline(renderPipeline);
passEncoder.setVertexBuffer(0, vertexBuffer);
passEncoder.draw(3);

// End the render pass
passEncoder.end();

// End frame by passing array of command buffers to command queue for execution
device.queue.submit([commandEncoder.finish()]);

// ...
```

### Unset vertex buffer

```js
// Set vertex buffer in slot 0
passEncoder.setVertexBuffer(0, vertexBuffer);

// Later, unset vertex buffer in slot 0
passEncoder.setVertexBuffer(0, null);
```

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

| Specification |
| --- |
| WebGPU # dom-gpurendercommandsmixin-setvertexbuffer |

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

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

See also
--------

* The WebGPU API


GPURenderPassEncoder: end() method - Web APIs

GPURenderPassEncoder: end() method
==================================

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

 The **`end()`** method of the
 `GPURenderPassEncoder` interface completes recording of the current render pass command sequence.

Syntax
------

```js
end()
```

### Parameters

None.

### Return value

None (`Undefined`).

### Validation

The following criteria must be met when calling **`end()`**, otherwise a `GPUValidationError` is generated and the `GPURenderPassEncoder` becomes invalid:

* The `GPURenderPassEncoder` is open (i.e. not already ended via an `end()` call).
* There is no occlusion query (i.e. started via `beginOcclusionQuery()`) active on the current render pass.
* The debug stack for the current render pass is empty (i.e. no render pass debug group is currently open, as opened by `pushDebugGroup()`).
* The number of draw commands encoded in this render pass is less than or equal to the `maxDrawCount` property set in the `GPUCommandEncoder.beginRenderPass()` descriptor.
Examples
--------

In our basic render demo, several commands are recorded via a `GPUCommandEncoder`. Most of these commands originate from the `GPURenderPassEncoder` created via `GPUCommandEncoder.beginRenderPass()`. `end()` is called in an appropriate place to end the render pass.

```js
// ...

const renderPipeline = device.createRenderPipeline(pipelineDescriptor);

// Create GPUCommandEncoder to issue commands to the GPU
// Note: render pass descriptor, command encoder, etc. are destroyed after use, fresh one needed for each frame.
const commandEncoder = device.createCommandEncoder();

// Create GPURenderPassDescriptor to tell WebGPU which texture to draw into, then initiate render pass
const renderPassDescriptor = {
  colorAttachments: [
    {
      clearValue: clearColor,
      loadOp: "clear",
      storeOp: "store",
      view: context.getCurrentTexture().createView(),
    },
  ],
};

const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);

// Draw the triangle
passEncoder.setPipeline(renderPipeline);
passEncoder.setVertexBuffer(0, vertexBuffer);
passEncoder.draw(3);

// End the render pass
passEncoder.end();

// End frame by passing array of command buffers to command queue for execution
device.queue.submit([commandEncoder.finish()]);

// ...
```

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

| Specification |
| --- |
| WebGPU # dom-gpurenderpassencoder-end |

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

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

See also
--------

* The WebGPU API


GPURenderPassEncoder: setIndexBuffer() method - Web APIs

GPURenderPassEncoder: setIndexBuffer() method
=============================================

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

 The **`setIndexBuffer()`** method of the
 `GPURenderPassEncoder` interface sets the current `GPUBuffer` that will provide index data for subsequent drawing commands.

Syntax
------

```js
setIndexBuffer(buffer, indexFormat, offset, size)
```

### Parameters

`buffer`

A `GPUBuffer` representing the buffer containing the index data to use for subsequent drawing commands.

`indexFormat`

An enumerated value that defines the format of the index data contained in `buffer`. Possible values are:

* `"uint16"`
* `"uint32"`

`offset` Optional

A number representing the offset, in bytes, into `buffer` where the index data begins. If omitted, `offset` defaults to 0.

`size` Optional

A number representing the size, in bytes, of the index data contained in `buffer`. If omitted, `size` defaults to the `buffer`'s `GPUBuffer.size` - `offset`.

#### Note on indexFormat

`indexFormat` determines both the data type of index values in a buffer and, when used with a pipeline that specifies a strip primitive topology (`"line-strip"` or `"triangle-strip"`), also determines the primitive restart value. The primitive restart value is an index value indicating that a new primitive should be started rather than continuing to construct the strip with the prior indexed vertices. The value is `0xFFFF` for `"uint16"`, or `0xFFFFFFFF` for `"uint32"`.

### Return value

None (`Undefined`).

### Validation

The following criteria must be met when calling **`setIndexBuffer()`**, otherwise a `GPUValidationError` is generated and the `GPURenderPassEncoder` becomes invalid:

* `buffer`'s `GPUBuffer.usage` contains the `GPUBufferUsage.INDEX` flag.
* `offset` + `size` is less than or equal to the `buffer`'s `GPUBuffer.size`.
* `offset` is a multiple of `indexFormat`'s byte size (2 for `"uint16"`, 4 for `"uint32"`).
Examples
--------

In the WebGPU Samples Shadow Mapping example, `setIndexBuffer()` is used in two separate render passes in each animation frame, one to draw the main model and one to draw its shadow. Study the example code listing for the full context.

```js
// ...

const commandEncoder = device.createCommandEncoder();
{
  const shadowPass = commandEncoder.beginRenderPass(shadowPassDescriptor);
  shadowPass.setPipeline(shadowPipeline);
  shadowPass.setBindGroup(0, sceneBindGroupForShadow);
  shadowPass.setBindGroup(1, modelBindGroup);
  shadowPass.setVertexBuffer(0, vertexBuffer);
  shadowPass.setIndexBuffer(indexBuffer, "uint16");
  shadowPass.drawIndexed(indexCount);

  shadowPass.end();
}
{
  const renderPass = commandEncoder.beginRenderPass(renderPassDescriptor);
  renderPass.setPipeline(pipeline);
  renderPass.setBindGroup(0, sceneBindGroupForRender);
  renderPass.setBindGroup(1, modelBindGroup);
  renderPass.setVertexBuffer(0, vertexBuffer);
  renderPass.setIndexBuffer(indexBuffer, "uint16");
  renderPass.drawIndexed(indexCount);

  renderPass.end();
}

// ...
```

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

| Specification |
| --- |
| WebGPU # dom-gpurendercommandsmixin-setindexbuffer |

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

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

See also
--------

* The WebGPU API


GPURenderPassEncoder: pushDebugGroup() method - Web APIs

GPURenderPassEncoder: pushDebugGroup() method
=============================================

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

 The **`pushDebugGroup()`** method of the
 `GPURenderPassEncoder` interface begins a render pass debug group, which is marked with a specified label, and will contain all subsequent encoded commands up until a `popDebugGroup()` method is invoked.

This could be used for telemetry, or may be utilized in `GPUError` messages, browser dev tools, or other services in the future to help with debugging.

Syntax
------

```js
pushDebugGroup(groupLabel)
```

### Parameters

`groupLabel`

A string representing the label for the debug group.

### Return value

None (`Undefined`).

Examples
--------

```js
// ...

const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);

passEncoder.pushDebugGroup("mygroupmarker"); // Start labeled debug group

passEncoder.setPipeline(renderPipeline);
passEncoder.setVertexBuffer(0, vertexBuffer);
passEncoder.draw(3);

passEncoder.popDebugGroup();

// ...
```

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

| Specification |
| --- |
| WebGPU # dom-gpudebugcommandsmixin-pushdebuggroup |

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

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

See also
--------

* The WebGPU API


GPURenderPassEncoder: beginOcclusionQuery() method - Web APIs

GPURenderPassEncoder: beginOcclusionQuery() method
==================================================

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

 The **`beginOcclusionQuery()`** method of the
 `GPURenderPassEncoder` interface begins an occlusion query at the specified index of the relevant `GPUQuerySet` (provided as the value of the `occlusionQuerySet` descriptor property when invoking `GPUCommandEncoder.beginRenderPass()` to run the render pass).

Syntax
------

```js
beginOcclusionQuery(queryIndex)
```

### Parameters

`queryIndex`

The index in the `GPUQuerySet` to begin the occlusion query at.

### Return value

None (`Undefined`).

### Validation

The following criteria must be met when calling **`beginOcclusionQuery()`**, otherwise a `GPUValidationError` is generated and the `GPURenderPassEncoder` becomes invalid:

* A `GPUQuerySet` was specified in the `occlusionQuerySet` descriptor property when invoking the originating `GPUCommandEncoder.beginRenderPass()`.
* `queryIndex` is smaller than `GPUQuerySet.count`.
* The `queryIndex` has not already been written to in the same render pass.
* An occlusion query is not already active for this render pass (i.e. via a previous `beginOcclusionQuery()` call).
Examples
--------

```js
// ...

// Create a query set to hold the occlusion queries
const querySet = device.createQuerySet({
  type: "occlusion",
  count: 32,
});

// Render pass descriptor object, including the querySet
const renderPassDescriptor = {
  colorAttachments: [
    {
      clearValue: clearColor,
      loadOp: "clear",
      storeOp: "store",
      view: context.getCurrentTexture().createView(),
    },
  ],
  occlusionQuerySet: querySet,
};

// Begin the render pass
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);

// Begin an occlusion query at index 0
passEncoder.beginOcclusionQuery(0);

// Run some rendering commands
passEncoder.setPipeline(renderPipeline);
passEncoder.setVertexBuffer(0, vertexBuffer);
passEncoder.draw(3);

// End the occlusion query
passEncoder.endOcclusionQuery();

// ...
```

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

| Specification |
| --- |
| WebGPU # dom-gpurenderpassencoder-beginocclusionquery |

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

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

See also
--------

* The WebGPU API


GPURenderPassEncoder: setStencilReference() method - Web APIs

GPURenderPassEncoder: setStencilReference() method
==================================================

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

 The **`setStencilReference()`** method of the
 `GPURenderPassEncoder` interface sets the stencil reference value using during stencil tests with the `"replace"` stencil operation (as set in the descriptor of the `GPUDevice.createRenderPipeline()` method, in the properties defining the various stencil operations).

Syntax
------

```js
setStencilReference(reference)
```

### Parameters

`reference`

A number representing the new stencil reference value to set for the render pass.

**Note:** If a `setStencilReference()` call is not made, the stencil reference value defaults to 0 for each render pass.

### Return value

None (`Undefined`).

Examples
--------

```js
// ...

const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);

passEncoder.setPipeline(renderPipeline);
passEncoder.setVertexBuffer(0, vertexBuffer);
passEncoder.setStencilReference(1);
passEncoder.draw(3);

passEncoder.end();

// ...
```

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

| Specification |
| --- |
| WebGPU # dom-gpurenderpassencoder-setstencilreference |

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

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

See also
--------

* The WebGPU API


GPURenderPassEncoder: drawIndexedIndirect() method - Web APIs

GPURenderPassEncoder: drawIndexedIndirect() method
==================================================

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

 The **`drawIndexedIndirect()`** method of the
 `GPURenderPassEncoder` interface draws indexed primitives using parameters read from a `GPUBuffer`.

Syntax
------

```js
drawIndexedIndirect(indirectBuffer, indirectOffset)
```

### Parameters

`indirectBuffer`

A `GPUBuffer` containing the `indexCount`, `instanceCount`, `firstIndex`, `baseVertex`, and `firstInstance` values needed to carry out the drawing operation. The buffer must contain a tightly packed block of five 32-bit unsigned integer values representing the values (20 bytes total), given in the same order as the arguments for `GPURenderPassEncoder.drawIndexed()`. So for example:

```js
const uint32 = new Uint32Array(5);
uint32[0] = 3; // The indexCount value
uint32[1] = 1; // The instanceCount value
uint32[2] = 0; // The firstIndex value
uint32[3] = 0; // The baseVertex value
uint32[4] = 0; // The firstInstance value

// Write values into a GPUBuffer
device.queue.writeBuffer(buffer, 0, uint32, 0, uint32.length);
```

`indirectOffset`

The offset, in bytes, into `indirectBuffer` where the value data begins.

### Return value

None (`Undefined`).

### Validation

The following criteria must be met when calling **`drawIndirect()`**, otherwise a `GPUValidationError` is generated and the `GPURenderPassEncoder` becomes invalid:

* `indirectBuffer`'s `GPUBuffer.usage` contains the `GPUBufferUsage.INDIRECT` flag.
* `indirectOffset` + the total size specified by the value parameters in the `indirectBuffer` is less than or equal to the `indirectBuffer`'s `GPUBuffer.size`.
* `indirectOffset` is a multiple of 4.
Examples
--------

```js
// ...

// Create GPURenderPassEncoder
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);

// Set pipeline and vertex buffer
passEncoder.setPipeline(renderPipeline);
passEncoder.setVertexBuffer(0, vertexBuffer);
passEncoder.setIndexBuffer(indexBuffer, "uint16");

// Create drawIndexedIndirect values
const uint32 = new Uint32Array(5);
uint32[0] = 3;
uint32[1] = 1;
uint32[2] = 0;
uint32[3] = 0;
uint32[4] = 0;

// Create a GPUBuffer and write the draw values into it
const drawValues = device.createBuffer({
  size: 20,
  usage: GPUBufferUsage.COPY\_DST | GPUBufferUsage.INDIRECT,
});
device.queue.writeBuffer(drawValues, 0, uint32, 0, uint32.length);

// Draw the vertices
passEncoder.drawIndexedIndirect(drawValues, 0);

// End the render pass
passEncoder.end();

// End frame by passing array of GPUCommandBuffers to command queue for execution
device.queue.submit([commandEncoder.finish()]);

// ...
```

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

| Specification |
| --- |
| WebGPU # dom-gpurendercommandsmixin-drawindexedindirect |

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

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

See also
--------

* The WebGPU API


GPURenderPassEncoder: setPipeline() method - Web APIs

GPURenderPassEncoder: setPipeline() method
==========================================

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

 The **`setPipeline()`** method of the
 `GPURenderPassEncoder` interface sets the `GPURenderPipeline` to use for subsequent render pass commands.

Syntax
------

```js
setPipeline(pipeline)
```

### Parameters

`pipeline`

The `GPURenderPipeline` to use for subsequent render pass commands.

### Return value

None (`Undefined`).

### Validation

The following criteria must be met when calling **`setPipeline()`**, otherwise a `GPUValidationError` is generated and the `GPURenderPassEncoder` becomes invalid:

* If the `GPURenderPipeline` writes to the depth component of the depth/stencil attachment, `depthReadOnly` (as specified in the descriptor of the originating `GPUCommandEncoder.beginRenderPass()` call) is `true`.
* If the `GPURenderPipeline` writes to the stencil component of the depth/stencil attachment, `stencilReadOnly` (as specified in the descriptor of the originating `GPUCommandEncoder.beginRenderPass()` call) is `true`.
Examples
--------

In our basic render demo, several commands are recorded via a `GPUCommandEncoder`. Most of these commands originate from the `GPURenderPassEncoder` created via `GPUCommandEncoder.beginRenderPass()`. `setPipeline()` is called in an appropriate place to set the render pipeline.

```js
// ...

const renderPipeline = device.createRenderPipeline(pipelineDescriptor);

// Create GPUCommandEncoder to issue commands to the GPU
// Note: render pass descriptor, command encoder, etc. are destroyed after use, fresh one needed for each frame.
const commandEncoder = device.createCommandEncoder();

// Create GPURenderPassDescriptor to tell WebGPU which texture to draw into, then initiate render pass
const renderPassDescriptor = {
  colorAttachments: [
    {
      clearValue: clearColor,
      loadOp: "clear",
      storeOp: "store",
      view: context.getCurrentTexture().createView(),
    },
  ],
};

const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);

// Draw the triangle
passEncoder.setPipeline(renderPipeline);
passEncoder.setVertexBuffer(0, vertexBuffer);
passEncoder.draw(3);

// End the render pass
passEncoder.end();

// End frame by passing array of command buffers to command queue for execution
device.queue.submit([commandEncoder.finish()]);

// ...
```

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

| Specification |
| --- |
| WebGPU # dom-gpurendercommandsmixin-setpipeline |

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

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

See also
--------

* The WebGPU API


Performance data - Web APIs

Performance data
================

The Performance API measures and exposes performance data that can be collected as performance metrics for your web application. It provides methods to observe aspects of application performance. It doesn't provide performance data analysis, or visualizations. However, the Performance API is integrated well with developer tools in browsers and its data is often sent to analytics end points and libraries to record performance metrics which help you to evaluate the data to find performance bottlenecks affecting your users.

This page provides an overview about what sorts of Performance API data exists, how it is collected, and how it can be accessed.

Collecting data
---------------

Most of the metrics exposed by the Performance API are automatically collected by the browser, and you don't have to tell it to collect them: you just have to retrieve them.

For some metrics you do have to tell the browser what to measure:

* the Element Timing metric measures the time it takes to load and render certain DOM elements. This metric is opt-in: to ask the browser to include metrics for a particular element you must add the `elementtiming` attribute to it.
* the User Timing metric enables you to measure the time between arbitrary points in your program, that might map to application-defined operations (such as logging in a user). To collect these metrics you need to add Performance API calls at the relevant points.
* the Server Timing metric enables you to measure the time taken for application-defined server-side operations. To collect these metrics your server must send the `Server-Timing` HTTP header.
Performance data structure
--------------------------

The Performance API collects performance data for each global object (`window.performance` or `self.performance` in workers). See `self.performance` for which APIs are available in window and worker contexts. If you are collecting performance metrics for multiple contexts, also take a look at `performance.timeOrigin` to synchronize time origins between contexts.

Within these contexts, individual performance data is represented by performance entries.

### Performance entries

A single recorded performance data point is called a *performance entry* and is represented by an instance of the `PerformanceEntry` interface.

The Performance API records various different types of performance data, and the `PerformanceEntry` has an `entryType` property which is a string describing the type of this performance entry:

* `"element"` records how long it takes an element to load and render.
* `"event"` records how long it took the browser to start running an event handler in response to its trigger, and how long the event handler took to run.
* `"first-input"` records the First input delay.
* `"largest-contentful-paint"` records the largest paint during page load.
* `"layout-shift"` records a metric representing how much the page layout has shifted in each animation frame.
* `"longtask"` records tasks that took 50ms or more.
* `"mark"` records a custom timestamp made by the developer.
* `"measure"` records a custom measurement between two timestamps made by the developer.
* `"navigation"` records metrics associated with navigating to and initial load of the page.
* `"paint"` records key moments of rendering during page load.
* `"resource"` records how long it took the browser to fetch a resource.
* `"visibility-state"` records the timing of page visibility state changes, i.e., when a tab changes from the foreground to the background or vice versa.
### Performance entry subclasses

Particular entry types typically include extra type-specific data: for example, the `"resource"` type captures the time at which DNS lookup started and ended. So entries are represented by subclasses that extend the basic `PerformanceEntry` interface. For example, a `"resource"` entry is represented by an instance of `PerformanceResourceTiming`, which inherits from `PerformanceEntry`, and which adds properties to record DNS lookup timestamps.

The subclasses of `PerformanceEntry` also define the semantics of the properties belonging to `PerformanceEntry` itself: for example, `PerformanceEntry` has a `name` property whose meaning depends on the subclass.

The following interfaces inherit from `PerformanceEntry`:

* `LargestContentfulPaint`
* `LayoutShift`
* `PerformanceElementTiming`
* `PerformanceEventTiming`
* `PerformanceLongTaskTiming`
* `PerformanceMark`
* `PerformanceMeasure`
* `PerformancePaintTiming`
* `PerformanceResourceTiming`
    + `PerformanceNavigationTiming` inherits from `PerformanceResourceTiming`
* `TaskAttributionTiming`
* `VisibilityStateEntry`
Accessing data
--------------

You can access performance entries in one of two ways. The preferred way is to use the `PerformanceObserver` interface, which is constructed with a callback function to be called when particular performance entries are recorded. You then call its `observe` method, passing in the types to observe and using the `buffered` option to retrieve entries that occurred before observation.

```js
function logEventDuration(entries) {
  const events = entries.getEntriesByType("event");
  for (const event of events) {
    console.log(
      `Event handler took: ${
 event.processingEnd - event.processingStart
 } milliseconds`,
    );
  }
}

const observer = new PerformanceObserver(logEventDuration);
observer.observe({ type: "event", buffered: true });
```

Alternatively, you can use the `Performance.getEntries()`, `Performance.getEntriesByName()`, and `Performance.getEntriesByType()` methods to retrieve all performance entries for a page, or entries matching the given name or type.

```js
const events = performance.getEntriesByType("event");

for (const event of events) {
  console.log(
    `Event handler took: ${
 event.processingEnd - event.processingStart
 } milliseconds`,
  );
}
```

The `PerformanceObserver` option is preferred because:

* The `getEntries*` methods will always return all relevant entries since the start of the timeline, so if you call it twice, you will see the same entries again and will need to filter out entries that you've seen before.
* Observer notifications are delivered asynchronously, so the browser can dispatch them during idle time to minimize their performance impact.
* Not all entry types work with the `getEntries*` methods. For some you have to use performance observers to access them.
Managing buffer sizes
---------------------

There is a buffer limit for performance entries for each global object. It ensures that the browser doesn't consume indefinite memory when holding performance data. Especially when your website or application fetches a lot of resources (e.g. when using polling), you might need to look into the limits for the buffers:

| `entryType` identifier | Interface | Maximum number of buffer entries |
| --- | --- | --- |
| `"mark"` | `PerformanceMark` | Infinite |
| `"measure"` | `PerformanceMeasure` | Infinite |
| `"navigation"` | `PerformanceNavigationTiming` | Infinite |
| `"resource"` | `PerformanceResourceTiming` | 250 (adjustable, see below) |
| `"longtask"` | `PerformanceLongTaskTiming` | 200 |
| `"paint"` | `PerformancePaintTiming` | 2 (there won't be more) |
| `"element"` | `PerformanceElementTiming` | 150 |
| `"event"` | `PerformanceEventTiming` | 150 |
| `"first-input"` | `PerformanceEventTiming` | 1 (there won't be more) |
| `"layout-shift"` | `LayoutShift` | 150 |
| `"largest-contentful-paint"` | `LargestContentfulPaint` | 150 |
| `"visibility-state"` | `VisibilityStateEntry` | 50 |

Table 1. Buffer sizes (source).

For `"resource"` entry types, see Managing resource buffer sizes for how to set a different buffer size.

For `"first-input"` and `"paint"`, the limitation is inherent in the metric's definition. There won't be more entries than one (or two).

The performance observer callback contains an optional `droppedEntriesCount` parameter that tells you how many entries were lost because the buffer storage was full.

```js
function perfObserver(list, observer, droppedEntriesCount) {
  list.getEntries().forEach((entry) => {
    // do something with the entries
  });
  if (droppedEntriesCount > 0) {
    console.warn(
      `${droppedEntriesCount} entries were dropped because the buffer was full.`,
    );
  }
}
const observer = new PerformanceObserver(perfObserver);
observer.observe({ type: "resource", buffered: true });
```

Another useful method is `PerformanceObserver.takeRecords()` which returns the current list of performance entries stored in the performance observer while also emptying it out.

JSON data
---------

All performance entries provide a `toJSON()` serializer which returns a `JSON` representation of the entry. This can be useful if you want to collect all of the available data and store it somewhere.

```js
const observer = new PerformanceObserver((list) => {
  list.getEntries().forEach((entry) => {
    console.log(entry.toJSON());
  });
});

observer.observe({ type: "event", buffered: true });
```

This would log a JSON object like so:

```json
{
  "name": "dragover",
  "entryType": "event",
  "startTime": 67090751.599999905,
  "duration": 128,
  "processingStart": 67090751.70000005,
  "processingEnd": 67090751.900000095,
  "cancelable": true
}
```

To get a string representation of the entry, you can use `JSON.stringify(entry)` with any `PerformanceEntry` object directly; it will call the entry's `toJSON()` method automatically.

See also
--------

* `PerformanceEntry`
* `PerformanceObserver.observe()`


Server timing - Web APIs

Server timing
=============

Server-Timing is a part of the Performance API and allows servers to communicate metrics about the request-response cycle to the user agent. You can collect this information and act on server-side metrics in the same way as all the other metrics processed with the Performance API.

Sending server metrics
----------------------

The `Server-Timing` HTTP header is used to surface any backend server timing metrics. For example, you might want to send database read/write operation times, CPU time, and file system access.

You can send metrics with or without values. The metrics can optionally contain a description. It is advised to keep names, descriptions, and data as short as possible to minimize the HTTP overhead.

Examples of `Server-Timing` headers:

```http
// Single metric without value
Server-Timing: missedCache

// Single metric with value
Server-Timing: cpu;dur=2.4

// Single metric with description and value
Server-Timing: cache;desc="Cache Read";dur=23.2

// Two metrics with values
Server-Timing: db;dur=53, app;dur=47.2

// Server-Timing as trailer
Trailer: Server-Timing
--- response body ---
Server-Timing: total;dur=123.4
```

To calculate real server-side metrics, consult the documentation of your server-side CMS, framework, or programming language for how to measure performance within the backend application. If your server uses Node.js, the performance measurement APIs will look very familiar to the Performance API in browsers. This is because the Node.js performance module is a subset of the W3C Web Performance APIs as well as additional APIs for Node.js-specific performance measurements. See the Node.js performance documentation for more information.

Note that there is no clock synchronization between the server, the client, and any intermediate proxies. This means that if your server sends timestamps or a `startTime`, the value might not meaningfully map to the `startTime` of the client's timeline.

Once you have calculated your desired metrics, the server needs to send the `Server-Timing` header in its response. See the `Server-Timing` reference page for an example of how to send the header in Node.js.

Retrieving server metrics
-------------------------

The server timing metrics usually appear in the developer tools of the browser, but they are also stored as `PerformanceServerTiming` performance entries that you can access like other performance data. However, there are no `"server-timing"` entries on their own. The `PerformanceServerTiming` objects are observable from `"navigation"` and `"resource"` performance entries. You access the server metrics from the `PerformanceResourceTiming.serverTiming` property, which is an array of `PerformanceServerTiming` objects.

Given a `Server-Timing` like this:

```http
Server-Timing: cache;desc="Cache Read";dur=23.2,db;dur=53,app;dur=47.2
```

A `PerformanceObserver` can log the entries on the client side with the following code:

```js
const observer = new PerformanceObserver((list) => {
  list.getEntries().forEach((entry) => {
    entry.serverTiming.forEach((serverEntry) => {
      console.log(
        `${serverEntry.name} (${serverEntry.description}) duration: ${serverEntry.duration}`,
      );
      // Logs "cache (Cache Read) duration: 23.2"
      // Logs "db () duration: 53"
      // Logs "app () duration: 47.2"
    });
  });
});

["navigation", "resource"].forEach((type) =>
  observer.observe({ type, buffered: true }),
);
```

Privacy and security considerations
-----------------------------------

The `Server-Timing` header may expose potentially sensitive application and infrastructure information. Therefore, you need to control when the metrics are returned and to whom on the server side. For example, you could show metrics only to authenticated users and nothing to the public.

The `PerformanceServerTiming` interface is restricted to the same origin, but you can use the `Timing-Allow-Origin` header to specify the domains that are allowed to access the server metrics. Also, note that this interface is only available in secure contexts (HTTPS) in some browsers.


Navigation timing - Web APIs

Navigation timing
=================

Navigation Timing is part of the Performance API and provides metrics associated with navigating from one page to another. For example, you can determine how much time it takes to load or unload a document, or log the time it took until DOM construction has finished and interaction with the DOM is possible.

Only the current document is included, so usually there is only one `PerformanceNavigationTiming` object to observe. It extends the `PerformanceEntry` interface with the `entryType` of `"navigation"` and also inherits from `PerformanceResourceTiming`, so all of the timestamps from the process of fetching the document are available as well.

PerformanceEntry

PerformanceResourceTiming

PerformanceNavigationTimingNavigation timestamps
---------------------

![Timestamp diagram listing timestamps in the order in which they are recorded for the fetching of a document](/en-US/docs/Web/API/PerformanceNavigationTiming/timestamp-diagram.svg)
 Figure 1. Navigation timestamps (source).

The document navigation timestamps (in addition to those from Resource Timing) are:

1. `startTime`: Always 0.
2. `unloadEventStart`: (if there is a previous document) the timestamp immediately before the current document's `unload` event handler starts.
3. `unloadEventEnd`: (if there is a previous document) the timestamp immediately after the current document's `unload` event handler completes.
4. `domInteractive`: timestamp when DOM construction is finished and interaction with it from JavaScript is possible.
5. `domContentLoadedEventStart`: timestamp immediately before the current document's `DOMContentLoaded` event handler starts.
6. `domContentLoadedEventEnd`: timestamp immediately after the current document's `DOMContentLoaded` event handler completes.
7. `domComplete`: timestamp when the document and all sub-resources have finished loading.
8. `loadEventStart`: timestamp immediately before the current document's `load` event handler starts.
9. `loadEventEnd`: timestamp immediately after the current document's `load` event handler completes.
Other properties
----------------

The `PerformanceNavigationTiming` interface provides additional properties such as `redirectCount` returning the number of redirects and `type` indicating the type of navigation.

Example
-------

The `domContentLoadedEventEnd` and `domContentLoadedEventStart` timestamps can be used to measure how long it takes process the `DOMContentLoaded` event handler.

This example uses a `PerformanceObserver`, which notifies the caller about new `navigation` performance entries as they are recorded in the browser's performance timeline. The example uses the `buffered` option to access entries that were recorded before the observer was created.

```js
const observer = new PerformanceObserver((list) => {
  list.getEntries().forEach((entry) => {
    const domContentLoadedTime =
      entry.domContentLoadedEventEnd - entry.domContentLoadedEventStart;
    console.log(
      `${entry.name}: DOMContentLoaded processing time: ${domContentLoadedTime}ms`,
    );
  });
});

observer.observe({ type: "navigation", buffered: true });
```

For more examples, see the property pages in the `PerformanceNavigationTiming` reference documentation.

See also
--------

* `PerformanceNavigationTiming`
* `PerformanceResourceTiming`


Resource timing - Web APIs

Resource timing
===============

Resource Timing is part of the Performance API and enables retrieving and analyzing detailed network timing data for the loading of an application's resources. An application can use the timing metrics to determine, for example, the length of time it takes to load a specific resource (such as an image or a script) either implicitly as part of page load or explicitly from JavaScript, for example using the `fetch()` API.

Every resource on a document will be represented by a `PerformanceResourceTiming` entry (extending the `PerformanceEntry` interface) with the `entryType` of `"resource"`.

For each `PerformanceResourceTiming` entry, a *resource loading timeline* will be recorded, with high-resolution timestamps for network events such as redirect start and end times, DNS lookup start and end times, request start, response start and end times, and so on. Besides the timestamps, other properties that provide information about the resource are included as well, such the size of the fetched resource, or the type of resource that initiated the fetch.

Resource loading timestamps
---------------------------

![Timestamp diagram listing timestamps in the order in which they are recorded for the fetching of a resource](/en-US/docs/Web/API/PerformanceResourceTiming/timestamp-diagram.svg)
 Figure 1. Resource loading timestamps (source).

An application can get timestamps for the various stages used to load a resource. The timestamps this API provides are:

1. `startTime`: timestamp immediately before the resource loading process begins.
2. `redirectStart`: timestamp of the fetch which initiates the redirect.
3. `redirectEnd`: timestamp immediately after receiving the last byte of the response to the last redirect.
4. `workerStart`: timestamp immediately before starting the Service Worker thread.
5. `fetchStart`: timestamp immediately before the browser starts to fetch the resource.
6. `domainLookupStart`: timestamp immediately before the browser starts the domain name lookup for the resource.
7. `domainLookupEnd`: timestamp immediately after the browser finishes the domain name lookup for the resource.
8. `connectStart`: timestamp immediately before the user agent starts establishing the connection to the server to retrieve the resource.
9. `secureConnectionStart`: If the resource is loaded via a secure connection, timestamp immediately before the browser starts the handshake process to secure the current connection.
10. `connectEnd`: timestamp immediately after the browser finishes establishing the connection to the server to retrieve the resource.
11. `requestStart`: timestamp of the time immediately before the browser starts requesting the resource from the server, cache, or local resource.
12. `responseStart`: timestamp immediately after the browser receives the first byte of the response from the server, cache, or local resource.
13. `responseEnd`: timestamp immediately after the browser receives the last byte of the resource or immediately before the transport connection is closed, whichever comes first.
Resource size
-------------

The `PerformanceResourceTiming` interface has three properties that can be used to obtain size data about a resource. The `transferSize` property returns the size (in bytes) of the fetched resource including the response header fields plus the response payload body.

The `encodedBodySize` property returns the size (in octets) received from the fetch (HTTP or cache), of the *payload body*, **before** removing any applied content-codings. `decodedBodySize` returns the size (in octets) received from the fetch (HTTP or cache) of the *message body*, **after** removing any applied content-codings.

Other properties
----------------

The `PerformanceResourceTiming` interface provides additional resources information. Consult the reference docs for the full list of properties.

Typical resource timing metrics
-------------------------------

The information the `PerformanceResourceTiming` entries provide are often used for calculations like the following:

* Measuring TCP handshake time (`connectEnd` - `connectStart`)
* Measuring DNS lookup time (`domainLookupEnd` - `domainLookupStart`)
* Measuring redirection time (`redirectEnd` - `redirectStart`)
* Measuring request time (`responseStart` - `requestStart`)
* Measuring TLS negotiation time (`requestStart` - `secureConnectionStart`)
* Measuring time to fetch (without redirects) (`responseEnd` - `fetchStart`)
* Measuring ServiceWorker processing time (`fetchStart` - `workerStart`)
* Checking if content was compressed (`decodedBodySize` should not be `encodedBodySize`)
* Checking if local caches were hit (`transferSize` should be `0`)
* Checking if modern and fast protocols are used (`nextHopProtocol` should be HTTP/2 or HTTP/3)
* Checking if the correct resources are render-blocking (`renderBlockingStatus`)

The `PerformanceResourceTiming` reference pages contain example code for measuring all of these metrics. Typically, the code for measuring these metrics looks like this:

```js
const observer = new PerformanceObserver((list) => {
  list.getEntries().forEach((entry) => {
    const request = entry.responseStart - entry.requestStart;
    if (request > 0) {
      console.log(`${entry.name}: Request time: ${request}ms`);
    }
  });
});

observer.observe({ type: "resource", buffered: true });
```

Cross-origin timing information
-------------------------------

When CORS is in effect, many of the timing properties' values are returned as zero unless the server's access policy permits these values to be shared. This requires the server providing the resource to send the `Timing-Allow-Origin` HTTP response header with a value specifying the origin or origins which are allowed to get the restricted timestamp values.

The properties which are returned as 0 by default when loading a resource from an origin other than the one of the web page itself: `redirectStart`, `redirectEnd`, `domainLookupStart`, `domainLookupEnd`, `connectStart`, `connectEnd`, `secureConnectionStart`, `requestStart`, and `responseStart`.

For example, to allow `https://developer.mozilla.org` to see resource timing information, the cross-origin resource should send:

```http
Timing-Allow-Origin: https://developer.mozilla.org
```

Managing resource buffer sizes
------------------------------

If your website or application fetches more than 250 resources and you want to record more than 250 `PerformanceResourceTiming` entries, you need to increase the size of the resource timing buffer.

To set the size of the browser's performance resource data buffer, use the `Performance.setResourceTimingBufferSize()` method, and 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.

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

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

For more information, see also Managing buffer sizes.

See also
--------

* `PerformanceResourceTiming`
* `Timing-Allow-Origin`
* `Performance.setResourceTimingBufferSize()`
* `Performance.clearResourceTimings()`


High precision timing - Web APIs

High precision timing
=====================

The Performance API allows high precision measurements that are based on time in potential sub-millisecond resolution and a stable monotonic clock that is not subject to system clock skew or adjustments. The high resolution timers are needed for accurate benchmarking instead of the less precise and non-monotonic `Date` timestamps.

This page provides an overview about how high precision time works within the Performance API and how it compares to `Date` timestamps.

`DOMHighResTimeStamp`
---------------------

High precision timing is achieved by using the `DOMHighResTimeStamp` type for time values. The unit is milliseconds and should be accurate to 5 µs (microseconds). However, if the browser is unable to provide a time value accurate to 5 microseconds, the browser can represent the value as a time in milliseconds accurate to a millisecond. This might occur because of hardware/software constraints, or security and privacy reasons. For more information, see the section on reduced precision below.

All timestamps in the Performance API use the `DOMHighResTimeStamp` type. Previously, the Performance API (and other Web APIs) used the `EpochTimeStamp` type (previously known as `DOMTimeStamp`). These types are now discouraged.

`Performance.now()` vs. `Date.now()`
------------------------------------

JavaScript defines `Date.now()` as the number of milliseconds elapsed since the epoch, which is defined as the midnight at the beginning of January 1, 1970, UTC. The `performance.now()` method on the other hand is relative to the `Performance.timeOrigin` property. For more information, see the time origins section below.

JavaScript `Date` times are subject to system clock skew or adjustments. This means that the value of time may not always be monotonically increasing. The main purpose of `Date` objects is to display time and date information to the user and so many operating systems run a daemon which regularly synchronizes time. It might be that the clock is tweaked a few milliseconds several times per hour.

The `performance.now()` method (and all other `DOMHighResTimeStamp` values) provide monotonically increasing time values and aren't subject to clock adjustments. This means that it is guaranteed `DOMHighResTimeStamp` values will be at least equal to, if not greater than, the last time you accessed it.

```js
Date.now(); // 1678889977578
performance.now(); // 233936
```

For measuring performance, calculating precise frame rates (FPS), animation loops, etc., use monotonically increasing high resolution time available with `Performance.now()` instead of JavaScript's `Date.now()`.

To summarize:

| - | `Performance.now()` | `Date.now()` |
| --- | --- | --- |
| Resolution | sub-milliseconds | milliseconds |
| Origin | `Performance.timeOrigin` | Unix Epoch (January 1, 1970, UTC) |
| Use clock adjustments | No | Yes |
| Monotonically increasing | Yes | No |

Time origins
------------

The Performance API uses the `Performance.timeOrigin` property to determine the baseline for performance-related timestamps. All `DOMHighResTimeStamp` times are relative to the `timeOrigin` property.

In Window contexts, this time origin is the time when navigation has started. In `Worker` and `ServiceWorker` contexts, the time origin is the time when the worker is run.

In the previous version of the specification (Level 1), the `performance.now()` method used to be relative to `performance.timing.navigationStart` property from the Navigation Timing specification. However, this changed in a later version of the specification (Level 2) 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();
```

### Synchronizing time origins between contexts

To account for the different time origins in window and worker contexts, you should translate the timestamps coming from worker scripts with the help of the `timeOrigin` property, so the timings synchronize for the entire application. See the examples section on the `Performance.timeOrigin` page for example code to synchronize time.

Reduced precision
-----------------

To offer protection against timing attacks and fingerprinting, `DOMHighResTimeStamp` types are coarsened based on site isolation status.

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

 To apply cross-origin isolation to your site, use the `Cross-Origin-Opener-Policy` (COOP) and
 `Cross-Origin-Embedder-Policy` (COEP) 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. `Cross-Origin-Opener-Policy` 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.

See also
--------

* `DOMHighResTimeStamp`
* `Performance.timeOrigin`
* `Performance.now()` / `Date.now()`


User timing - Web APIs

User timing
===========

 User Timing is part of the Performance API and allows you to measure the performance of applications using high-precision timestamps that are part of the browser's performance timeline.
 There are two types of timing performance entries:

* `PerformanceMark` entries are marks that you can name and add at any location in an application.
* `PerformanceMeasure` entries are time measurements between two marks.
What is User Timing?
--------------------

The browser provides certain information (called *performance entries*) to the browser's performance timeline for you. This includes, for example, entries provided by the Resource Timing API that determine the time it takes to fetch a resource like an image.

The browser, however, can not determine what is going on in your application. For example, when a user clicks a button or performs a specific task within your application, there is no high-precision performance measurement. The User Timing API is an extension to the browser's performance timeline and helps you to measure and record performance data that is custom to your application.

The advantage of using this API, over calls to `Date.now()` or `performance.now()`, is that you can give the markers a name and that it integrates well with performance tooling. Browser's developer tools can display performance marks in Performance Panels, and it also works with other performance APIs like `PerformanceObserver` objects.

Adding performance markers
--------------------------

As a first step to start measuring the performance of your app's functionality, you need to add named performance markers at important places in your code. Ideally, you go through your codebase and determine critical paths and important tasks for which you want to ensure they can be performed fast.

The `performance.mark()` method is used to create a `PerformanceMark`. The method takes one argument, the `name` of the mark, as shown in the following example.

```js
// Place at a location in the code that starts login
performance.mark("login-started");

// Place at a location in the code that finishes login
performance.mark("login-finished");
```

If the `name` argument isn't enough, `mark()` is configurable using an options object where you can put additional information in the `detail` property, which can be of any type. You can also set a different `startTime` if needed. In the following code, the `startTime` is set to `12.5`, and additional information, like the HTML element used, is provided with `detail`.

```js
performance.mark("login-started", {
  startTime: 12.5,
  detail: { htmlElement: myElement.id },
});
```

Measuring duration between markers
----------------------------------

Now that you added markers to your application, you can measure the time between them.

The `Performance.measure()` method is used to create a `PerformanceMeasure` object. It accepts a `name` parameter, used to identify the measure, and two marks, `start` and `end`, that it should measure between. The following example creates a `"login-duration"` measure and measures between the start and the finish of the login process.

The object then has a `duration` property which calculates the end mark timestamp minus the start mark timestamp for you. For example, you can log this value or send it to some analytics endpoint.

```js
const loginMeasure = performance.measure(
  "login-duration",
  "login-started",
  "login-finished",
);

console.log(loginMeasure.duration);
```

The `Performance.measure()` method is also configurable using an options object, so you can do more advanced measurements or provide additional information using the `detail` property.

For example, you can use the `event.timestamp` property from a `click` event to know exactly when a user clicked login and measure that to the point in time when the UI was updated, which is the `"login-finished"` marker here.

```js
loginButton.addEventListener("click", (clickEvent) => {
  fetch(loginURL).then((data) => {
    renderLoggedInUser(data);

    const marker = performance.mark("login-finished");

    performance.measure("login-click", {
      detail: { htmlElement: myElement.id },
      start: clickEvent.timeStamp,
      end: marker.startTime,
    });
  });
});
```

Observing performance measures
------------------------------

The preferred way to get notified about your custom performance measures is the use of `PerformanceObserver` objects. Performance observers allow you to subscribe passively to performance marks and measures as they happen.

```js
function perfObserver(list, observer) {
  list.getEntries().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}`);
    }
  });
}
const observer = new PerformanceObserver(perfObserver);
observer.observe({ entryTypes: ["measure", "mark"] });
```

For more information, see `PerformanceObserver`.

Retrieving markers and measures
-------------------------------

There are many different performance entries in the browser's performance timeline. Some are added by the browser, and some might be added by you, like the login markers and measures from the examples above.

To retrieve performance marks and measures at a single point in time, the `Performance` interface provides three methods, as shown below.

**Note:** The methods below do not notify you about new performance markers; you will only get markers that have been created when you call these methods.
 See the section Observing performance measures above for receiving notifications about new metrics as they become available using a `PerformanceObserver`. Usually, using performance observers is the preferred way to get performance markers and measures.

The `performance.getEntries()` method gets all performance entries. You can filter them as needed.

```js
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}`);
  }
});
```

The `performance.getEntriesByType(entryType)` method filters the entries by type already.

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

const measures = performance.getEntriesByType("measure");
measures.forEach((entry) => {
  console.log(`${entry.name}'s duration: ${entry.duration}`);
});
```

The `performance.getEntriesByName(name, entryType)` method allows you to get specific marks or measures by name.

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

Removing markers and measures
-----------------------------

To clean up all performance marks or measures, or just specific entries, the following methods are available:

* `performance.clearMarks()`
* `performance.clearMeasures()`

```js
// Clear all marks
performance.clearMarks();

// Removes the marker with the name "myMarker"
performance.clearMarks("myMarker");

// Clear all measures
performance.clearMeasures();

// Removes the measure with the name "myMeasure"
performance.clearMeasures("myMeasure");
```

See also
--------

* `Performance`
* `PerformanceMark`
* `PerformanceMeasure`
* `PerformanceEntry`
* `PerformanceObserver`


BluetoothRemoteGATTService: getCharacteristic() method - Web APIs

BluetoothRemoteGATTService: getCharacteristic() method
======================================================

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

 The **`BluetoothGATTService.getCharacteristic()`** method
 returns a `Promise` to an instance of
 `BluetoothRemoteGATTCharacteristic` for a given universally unique identifier
 (UUID).

Syntax
------

```js
getCharacteristic(characteristic)
```

### Parameters

`characteristic`

 The UUID of a characteristic, for
 example `'00002a37-0000-1000-8000-00805f9b34fb'` for the Heart Rate
 Measurement characteristic.

### Return value

A `Promise` to an instance of `BluetoothRemoteGATTCharacteristic`

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

| Specification |
| --- |
| Web Bluetooth # dom-bluetoothremotegattservice-getcharacteristic |

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

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


BluetoothRemoteGATTService: device property - Web APIs

BluetoothRemoteGATTService: device property
===========================================

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

 The **`BluetoothGATTService.device`** read-only property
 returns information about a Bluetooth device through an instance of
 `BluetoothDevice`.

Value
-----

An instance of `BluetoothDevice`.

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

| Specification |
| --- |
| Web Bluetooth # dom-bluetoothremotegattservice-device |

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

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


BluetoothRemoteGATTService: isPrimary property - Web APIs

BluetoothRemoteGATTService: isPrimary property
==============================================

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

 The **`BluetoothGATTService.isPrimary`** read-only property
 returns a boolean value that indicates whether this is a primary service. If it
 is not a primary service, it is a secondary service.

Value
-----

A boolean value.

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

| Specification |
| --- |
| Web Bluetooth # dom-bluetoothremotegattservice-isprimary |

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

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


BluetoothRemoteGATTService: getCharacteristics() method - Web APIs

BluetoothRemoteGATTService: getCharacteristics() method
=======================================================

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

 The **`BluetoothGATTService.getCharacteristics()`** method
 returns a `Promise` to a list of `BluetoothRemoteGATTCharacteristic`
 instances for a given universally unique identifier (UUID).

Syntax
------

```js
getCharacteristics(characteristics)
```

### Parameters

`characteristics`

 The UUID of a characteristic, for
 example `'00002a37-0000-1000-8000-00805f9b34fb'` for the Heart Rate
 Measurement characteristic.

### Return value

 A `Promise` to an
 `Array` of `BluetoothRemoteGATTCharacteristic` instances.

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

| Specification |
| --- |
| Web Bluetooth # dom-bluetoothremotegattservice-getcharacteristics |

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

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


BluetoothRemoteGATTService: uuid property - Web APIs

BluetoothRemoteGATTService: uuid property
=========================================

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

 The **`BluetoothGATTService.uuid`** read-only property
 returns a string representing the UUID of this service.

Value
-----

A string.

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

| Specification |
| --- |
| Web Bluetooth # dom-bluetoothremotegattservice-uuid |

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

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


HTMLInputElement: files property - Web APIs

HTMLInputElement: files property
================================

The **`HTMLInputElement.files`** property allows you to access the `FileList` selected with the `<input type="file">` element.

Value
-----

A `FileList` object listing the selected files, if any, or `null` if the **`HTMLInputElement`** is not of `type="file"`.

Examples
--------

The example below shows how you can access the **`HTMLInputElement.files`** property and log the name, date modified, size, and type of each file selected by the user.

### HTML

```html
<input id="files" type="file" multiple />
```

### JavaScript

 Note that **`HTMLInputElement.files`** still returns an instance of `FileList` even if no files are
 selected.
 Therefore it's safe to iterate through it with `for...of` without checking if any files are selected.

```js
const fileInput = document.getElementById("files");

console.log(fileInput.files instanceof FileList); // true even if empty

for (const file of fileInput.files) {
  console.log(file.name); // prints file name
  let fileDate = new Date(file.lastModified);
  console.log(fileDate.toLocaleDateString()); // prints legible date
  console.log(
    file.size < 1000 ? file.size : Math.round(file.size / 1000) + "KB",
  );
  console.log(file.type); // prints MIME type
}
```

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

| Specification |
| --- |
| HTML Standard # dom-input-files-dev |

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

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

See also
--------

* `DataTransfer.files`


HTMLInputElement: stepDown() method - Web APIs

HTMLInputElement: stepDown() method
===================================

 The
 **`HTMLInputElement.stepDown([n])`** method decrements the
 value of a numeric type of `<input>` element by the value of the
 `step` attribute or up
 to `n` multiples of the step attribute if a number is passed as the
 parameter.

 The method, when invoked, decrements the
 `value` by (`step` \* n), where n
 defaults to 1 if not specified, and
 `step` defaults to the
 default value for `step` if not specified.

 Valid on all numeric, date, and time input types that support the step attribute,
 including date, month,
 week, time,
 datetime-local, number, and range.

 Given `<input id="myTime" type="time" max="17:00" step="900" value="17:00">`,
 invoking `myTime.stepDown(3)` will change the value to 16:15, decrementing the
 time by `3 * 900`, or 45 minutes. `myTime.stepDown()`, with no
 parameter, would have resulted in `16:45`, as `n` defaults to
 `1`.

```html
<!-- decrements by intervals of 900 seconds (15 minute) -->
<input type="time" max="17:00" step="900" />

<!-- decrements by intervals of 7 days (one week) -->
<input type="date" max="2019-12-25" step="7" />

<!-- decrements by intervals of 12 months (one year) -->
<input type="month" max="2019-12" step="12" />
```

However, calling `stepDown` on `<input type="time" max="17:00" step="900">` would not set the value to `17:00`, as one would expect — and as it does for `stepUp` when the input is `<input type="time" min="17:00" step="900">`. Instead, the first call to `stepDown` will set the initial value to `23:45` even though the `max` attribute is set. The second call will set the value to `17:00`. And the third call to will set the value to `16:45`.

```js
let input1 = document.createElement("input");
input1.setAttribute("type", "time");
input1.setAttribute("min", "17:00");
input1.setAttribute("step", 900);
console.log(input1.value); // ""
input1.stepUp();
console.log(input1.value); // "17:00"
// However
let input2 = document.createElement("input");
input2.setAttribute("type", "time");
input2.setAttribute("max", "17:00");
input2.setAttribute("step", 900);
console.log(input2.value); // ""
input2.stepDown();
console.log(input2.value); // "23:45"
input2.stepDown();
console.log(input2.value); // "17:00"
input2.stepDown();
console.log(input2.value); // "16:45"
```

 The method, when invoked, changes the form control's value by the value given in the
 `step` attribute, multiplied by the parameter, within the constraints set
 within the form control. The default value for the parameter, if not is passed, is 1.
 The method will not cause the value to go below the
 `min` value set or defy the
 constraints set by the
 `step` attribute. A
 negative value for `n` will increment the value, but will not increment
 beyond the `max` value.

 If the value before invoking the `stepDown()` method is invalid, for
 example, if it doesn't match the constraints set by the `step` attribute,
 invoking the `stepDown()` method will return a value that does match the form
 controls constraints.

 If the form control is non time, date, or numeric in nature, and therefore does not
 support the `step` attribute (see the list of supported input types above), or if the `step` value is set to `any`, an
 `InvalidStateError` exception is thrown.

`HTMLInputElement.stepDown()`

 Decrements the `value` by
 (`step` \* n), where n defaults to 1 if not specified. Throws
 an `InvalidStateError` exception:

* if the method is not applicable to for the current
 `type` value,
* if the element has no `step` value,
* if the `value` cannot be converted to a number,
* if the resulting value is above the `max` or below the
 `min`.

Syntax
------

```js
stepDown()
stepDown(stepDecrement)
```

### Parameters

`stepDecrement` Optional

A numeric value. If no parameter is passed, *stepDecrement* defaults to 1.

 If the value is a float, the value will decrement as if
 `Math.floor(stepDecrement)`
 was passed. If the value is negative, the value will be incremented instead of
 decremented.

### Return value

None (`undefined`).

Examples
--------

Click the button in this example to decrement the number input type:

### HTML

```html
<p>
  <label for="theNumber">
    Enter a number between 0 and 400 that is divisible by 5:
  </label>
  <input type="number" step="5" id="theNumber" min="0" max="400" />
</p>
<p>
  <label for="decrementButton">
    Enter how many values of step you would like to decrement by or leave it
    blank:
  </label>
  <input type="number" step="1" id="decrementInput" min="-2" max="15" />
</p>
<input type="button" value="Decrement" id="theButton" />
```

### JavaScript

```js
/\* make the button call the function \*/
let button = document.getElementById("theButton");
button.addEventListener("click", () => {
  stepOnDown();
});

function stepOnDown() {
  let input = document.getElementById("theNumber");
  let val = document.getElementById("decrementInput").value;

  if (val) {
    // decrement with a parameter
    input.stepDown(val);
  } else {
    // or without a parameter. Try it with 0, 5, -2, etc.
    input.stepDown();
  }
}
```

### CSS

```css
input:invalid {
  border: red solid 3px;
}
```

### Result

 Note if you don't pass a parameter to the `stepDown()` method, it defaults
 to 1. Any other value is a multiplier of the `step` attribute value, which in
 this case is 5. If we pass `4` as the `stepDecrement`, the input will `stepDown` by
 `4 * 5`, or `20`. If the parameter is `0`, the number will not be
 decremented. The `stepDown()` method will not allow the input to go out of range, in this
 case stopping when it reaches 0 and rounding down and floats that are passed as a
 parameter.

 Try setting the step decrement input to `1.2`. What happens when you invoke the
 method?

 Try setting the value to `44`, which is not valid. What happens when you
 invoke the method?

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

| Specification |
| --- |
| HTML Standard # dom-input-stepdown-dev |

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

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

See also
--------

* `<input>`
* `HTMLInputElement`
* `HTMLInputElement.stepUp()`
* `step`,
 `min` and
 `max` attributes


HTMLInputElement: webkitEntries property - Web APIs

HTMLInputElement: webkitEntries property
========================================

 The read-only **`webkitEntries`**
 property of the `HTMLInputElement` interface contains an array of file
 system entries (as objects based on `FileSystemEntry`) representing files
 and/or directories selected by the user using an `<input>` element of
 type `file`, but only if that selection was made using drag-and-drop:
 selecting a file in the dialog will leave the property empty.

 The array can only contain directories if the
 `webkitdirectory` property is
 `true`. This means the `<input>` element was configured to
 let the user choose directories.

**Note:** This property is called `webkitEntries` in the specification due to its
 origins as a Google Chrome-specific API. It's likely to be renamed someday.

Value
-----

 An array of objects based on `FileSystemEntry`, each representing one file
 which is selected in the `<input>` element. More specifically, files are
 represented by `FileSystemFileEntry` objects, and, if they're allowed,
 directories are represented by `FileSystemDirectoryEntry` objects.

Examples
--------

 This example shows how to create a file selection `<input>` element
 and process the selected files.

### HTML

```html
<input id="files" type="file" multiple />
```

### JavaScript

```js
document.getElementById("files").addEventListener("change", (event) => {
  event.target.webkitEntries.forEach((entry) => {
    /\* do stuff with the entry \*/
  });
});
```

 Each time a `change` event occurs, this code iterates over the selected
 files, obtaining their `FileSystemEntry`-based objects and acting on them.

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

| Specification |
| --- |
| File and Directory Entries API # dom-htmlinputelement-webkitentries |

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

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

See also
--------

* File and Directory Entries API
* Introduction to the File and Directory Entries API
* `HTMLInputElement`
* `FileSystemEntry`
* `FileSystem`


HTMLInputElement: checkValidity() method - Web APIs

HTMLInputElement: checkValidity() method
========================================

Baseline 2023
-------------

Newly availableSince March 2023, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
The **`HTMLInputElement.checkValidity()`** method returns a boolean value which indicates validity of the value of the element. If the value is invalid, this method also fires the `invalid` event on the element.

Syntax
------

```js
checkValidity()
```

### Parameters

None.

### Return value

Returns `true` if the value of the element has no validity problems; otherwise returns `false`.

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

| Specification |
| --- |
| HTML Standard # dom-cva-checkvalidity-dev |

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

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

See also
--------

* reportValidity
* Learn: Client-side form validation
* Guide: Constraint validation


HTMLInputElement: selectionchange event - Web APIs

HTMLInputElement: selectionchange event
=======================================

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

 The **`selectionchange`** event of the Selection API is fired when the text selection within an `<input>` element is changed.
 This includes both changes in the selected range of characters, or if the caret moves.

This event is not cancelable.

The event is usually processed by adding an event listener on the `<input>`, and in the handler function read by the `HTMLInputElement` `selectionStart`, `selectionEnd` and `selectionDirection` properties.

It is also possible to add a listener on the `onselectionchange` event handler, and within the handler function use `Document.getSelection()` to get the `Selection`. However this is not very useful for getting changes to *text* selections.

Syntax
------

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

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

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

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

A generic `Event`.

Examples
--------

The example below shows how to get the text selected in an `<input>` element.

### HTML

```html
<div>
  Enter and select text here:<br /><input id="mytext" rows="2" cols="20" />
</div>
<div>selectionStart: <span id="start"></span></div>
<div>selectionEnd: <span id="end"></span></div>
<div>selectionDirection: <span id="direction"></span></div>
```

### JavaScript

```js
const myinput = document.getElementById("mytext");

myinput.addEventListener("selectionchange", () => {
  document.getElementById("start").textContent = myinput.selectionStart;
  document.getElementById("end").textContent = myinput.selectionEnd;
  document.getElementById("direction").textContent = myinput.selectionDirection;
});
```

### Result

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

| Specification |
| --- |
| Selection API # selectionchange-event |
| Selection API # dom-globaleventhandlers-onselectionchange |

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

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


HTMLInputElement: setRangeText() method - Web APIs

HTMLInputElement: setRangeText() method
=======================================

 The **`HTMLInputElement.setRangeText()`** method replaces a
 range of text in an `<input>` or `<textarea>` element with
 a new string.

Syntax
------

```js
setRangeText(replacement)
setRangeText(replacement, start)
setRangeText(replacement, start, end)
setRangeText(replacement, start, end, selectMode)
```

### Parameters

`replacement`

The string to insert.

`start` Optional

 The 0-based index of the first character to replace. Defaults to the current
 `selectionStart` value (the start of the user's current selection).

`end` Optional

 The 0-based index of the character *after* the last character to replace.
 Defaults to the current `selectionEnd` value (the end of the user's current
 selection).

`selectMode` Optional

 A string defining how the selection should be set after the text has been replaced.
 Possible values:

* `"select"` selects the newly inserted text.
* `"start"`moves the selection to just before the inserted text.
* `"end"` moves the selection to just after the inserted text.
* `"preserve"` attempts to preserve the selection. This is the default.

### Return value

None (`undefined`).

Examples
--------

 Click the button in this example to replace part of the text in the text box. The newly
 inserted text will be highlighted (selected) afterwards.

### HTML

```html
<input
 type="text"
 id="text-box"
 size="30"
 value="This text has NOT been updated." />
<button onclick="selectText()">Update text</button>
```

### JavaScript

```js
function selectText() {
  const input = document.getElementById("text-box");
  input.focus();
  input.setRangeText("ALREADY", 14, 17, "select");
}
```

### Result

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

| Specification |
| --- |
| HTML Standard # dom-textarea/input-setrangetext-dev |

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

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

See also
--------

* `<input>`
* `<textarea>`
* `HTMLInputElement`
* `Selection`