Skip to content

[ResizeObserver] ResizeObserver spec should probably mention issues with requestAnimationFrame #9814

@greggman

Description

@greggman

The ResizeObserver spec

I think, most obvious way to use the ResizeObserver API is as follows

function drawToCanvas() {
  // draw to canvas
}

const observer = new ResizeObserver(entries => {
  const entry = entries[0];
  canvas.width = entry.contentBoxSize[0].inlineSize;
  canvas.height = entry.contentBoxSize[0].blockSize;
  drawToCanvas();
});
observer.observe(canvas);

(simplified example, not going over all entries) Note: this is effectively what the example in the spec does.

If you're making an example that uses requestAnimationFrame tho, you don't want to draw in the ResizeObserver, you only want to draw in requestAnimationFrame. You also don't want to draw twice, one in rAF and once in the ResizeObserver callback, as drawing might be very heavy (1000s of draw calls)

Arguably, the most obvious modification of the code above to a rAF based solution is this

function drawToCanvas() {
  // draw to canvas
  requestAnimationFrame(drawToCanvas);
}
requestAnimationFrame(drawToCanvas);

const observer = new ResizeObserver(entries => {
  const entry = entries[0];
  canvas.width = entry.contentBoxSize[0].inlineSize;
  canvas.height = entry.contentBoxSize[0].blockSize;
});
observer.observe(canvas);

It's every small change. Start a rAF loop. Resize the canvas when you get a ResizeObserver callback. Done.

Unfortunately, this results in a poor experience. Because ResizeObserver events are delivered after requestAnimationFrame events (see event loop spec), setting the size of the canvas in the ResizeObserver callback will clear it after rendering but before compositing.

Example (resize the window or drag the divider or open the devtools and drag that divider, watch the flicker)

It seems like it would be a good idea to call this issue out in the spec?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions