Skip to content

Performance of canvas snapshotting on Safari is poor #6775

@Pinpickle

Description

@Pinpickle

Describe the bug

Snapshotting a canvas element in Safari 16.x takes a long time (>20ms). This leads to a frame drop every time the canvas is snapshotted.

To Reproduce

Go to the Codsandbox full-screen here https://jqgtld.csb.app/

Look at the "Snapshot" stat in the top right corner (or in the console). On my computer it is ~20ms on Safari 16.5. On Chrome, it is between 0 and 0.3ms.

The window size is 1057 x 734 (retina display, so double the dimensions for the canvas)

Here's the codesandbox with the editor: https://codesandbox.io/s/dazzling-roentgen-jqgtld?file=/src/App.js

Expected behavior

Overhead for snapshotting to be near 0

Screenshots

Safari

CleanShot 2023-10-02 at 15 23 03 png

Chrome

CleanShot 2023-10-02 at 15 23 55 png

iOS

CleanShot 2023-10-02 at 15 27 57 png

Additional context

Environment:

System:
    OS: macOS 13.4
    CPU: (8) arm64 Apple M1
    Memory: 51.78 MB / 8.00 GB
Browsers:
    Chrome: 117.0.5938.92
    Safari: 16.5

Provided this also affects Safari 17 (I don't know if it does), this affects every Safari-based browser (including everything on iOS). This performance drop means we had to disable canvas recording for Safari on our app which really limits its usefulness.

The larger the canvas, the longer the snapshot time, from what I can tell. Changing canvasMaxSnapshotDimension does not appear to make a difference. Safari doesn't even respect the options parameter for createBitmapImage: https://developer.mozilla.org/en-US/docs/Web/API/createImageBitmap

I'm reasonably confident this comes from the call to createBitmapImage here:

const bitmap = yield createImageBitmap(element, {
resizeWidth: width,
resizeHeight: height
});

It's supposed to be asynchronous but it looks like it is blocking in Safari. I wonder if there are other ways to get the image data out of a canvas? I understand there are efforts to use WebRTC for canvas recording? I imagine this could help.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

Status

Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions