diff --git a/.changeset/ninety-beans-compare.md b/.changeset/ninety-beans-compare.md
index de5b0a0f..fd3e8b1a 100644
--- a/.changeset/ninety-beans-compare.md
+++ b/.changeset/ninety-beans-compare.md
@@ -2,4 +2,15 @@
"@preact/signals": minor
---
-Defer all DOM updates by an animation frame as well
+Defer all DOM updates by an animation frame, this should make it so
+that any used to be synchronous DOM update will be delayed by an
+animation frame. This allows Preact to first perform its own render
+cycle and then our direct DOM updates to occur. These will now
+be performed in a batched way which is more performant as the browser
+is prepared to handle these during the animation frame.
+
+This does have one way to how Preact based signals are tested, when
+we perform a signal update we have to wrap it in `act`, in a way
+this was always the case as a signal update that resulted in
+a Preact state update would require it to be wrapped in `act` but
+now this is the norm.
diff --git a/packages/preact/src/index.ts b/packages/preact/src/index.ts
index 02f3e832..7a408d6b 100644
--- a/packages/preact/src/index.ts
+++ b/packages/preact/src/index.ts
@@ -381,7 +381,7 @@ function flushEffects() {
function notifyEffects(this: Effect) {
if (effectsQueue.push(this) === 1) {
- (options.debounceRendering || defer)(flushEffects);
+ (options.requestAnimationFrame || defer)(flushEffects);
}
}
@@ -394,7 +394,7 @@ function flushComputeds() {
function notifyComputeds(this: Effect) {
if (computedsQueue.push(this) === 1) {
- (options.debounceRendering || defer)(flushComputeds);
+ (options.requestAnimationFrame || defer)(flushComputeds);
}
}
diff --git a/packages/preact/test/index.test.tsx b/packages/preact/test/index.test.tsx
index ff85d85c..a74ca53b 100644
--- a/packages/preact/test/index.test.tsx
+++ b/packages/preact/test/index.test.tsx
@@ -13,17 +13,8 @@ import { useContext, useRef, useState } from "preact/hooks";
import { setupRerender, act } from "preact/test-utils";
const sleep = (ms?: number) => new Promise(r => setTimeout(r, ms));
-const defer =
- typeof requestAnimationFrame === "undefined"
- ? setTimeout
- : requestAnimationFrame;
-const afterFrame = () => {
- return new Promise(res => {
- defer(res);
- });
-};
-describe.only("@preact/signals", () => {
+describe("@preact/signals", () => {
let scratch: HTMLDivElement;
let rerender: () => void;
@@ -234,7 +225,6 @@ describe.only("@preact/signals", () => {
act(() => {
sig.value = d;
});
- await afterFrame();
rerender();
await sleep();
@@ -707,7 +697,6 @@ describe.only("@preact/signals", () => {
});
expect(scratch.textContent).to.equal("foo");
// expect(spy).not.to.have.been.called;
- await afterFrame();
expect(spy).to.have.been.calledOnceWith(
"foo",
scratch.firstElementChild,
@@ -756,7 +745,6 @@ describe.only("@preact/signals", () => {
render(
` ); @@ -632,7 +626,6 @@ export function updateSignalsTests(usingTransform = false) { await act(() => { scratch.querySelector("button")!.click(); }); - await afterFrame(); expect(url.textContent).to.equal("https://domain.com/test?a=2"); expect(URLModelProvider).to.be.calledOnce;-2
${count.value * 2}