diff --git a/source/dom/updater.mjs b/source/dom/updater.mjs
index 8a5bf59b1351f06ebb0addb5c274cb9dd17ae73f..b769647a5f6607b4b6de5e05039f672bf91d8e09 100644
--- a/source/dom/updater.mjs
+++ b/source/dom/updater.mjs
@@ -60,6 +60,18 @@ export { Updater, addObjectWithUpdaterToElement };
  */
 const timerElementEventHandlerSymbol = Symbol("timerElementEventHandler");
 
+/**
+ * @private
+ * @type {symbol}
+ */
+const pendingDiffsSymbol = Symbol("pendingDiffs");
+
+/**
+ * @private
+ * @type {symbol}
+ */
+const processingSymbol = Symbol("processing");
+
 /**
  * The updater class connects an object with the DOM. In this way, structures and contents in the DOM can be
  * programmatically adapted via attributes.
@@ -85,6 +97,7 @@ const timerElementEventHandlerSymbol = Symbol("timerElementEventHandler");
  * @summary The updater class connects an object with the dom
  */
 class Updater extends Base {
+
   /**
    * @since 1.8.0
    * @param {HTMLElement} element
@@ -117,39 +130,50 @@ class Updater extends Base {
       getCheckStateCallback.call(this),
     );
 
-    this[internalSymbol].subject.attachObserver(
-      new Observer(() => {
-        const s = this[internalSymbol].subject.getRealSubject();
-
-        const diffResult = diff(this[internalSymbol].last, s);
-        this[internalSymbol].last = clone(s);
-
-        const promises = [];
-
-        for (const [, change] of Object.entries(diffResult)) {
-          promises.push(
-            new Promise((resolve, reject) => {
-              getWindow().requestAnimationFrame(() => {
-                try {
-                  removeElement.call(this, change);
-                  insertElement.call(this, change);
-                  updateContent.call(this, change);
-                  updateAttributes.call(this, change);
-
-                  resolve();
-                } catch (error) {
-                  reject(error);
-                }
-              });
-            }),
-          );
-        }
+    this[pendingDiffsSymbol] = [];
+    this[processingSymbol] = false;
 
-        return Promise.all(promises);
-      }),
+    this[internalSymbol].subject.attachObserver(
+        new Observer(() => {
+          const real = this[internalSymbol].subject.getRealSubject();
+          const diffResult = diff(this[internalSymbol].last, real);
+          this[internalSymbol].last = clone(real);
+          this[pendingDiffsSymbol].push(diffResult);
+          return this.#processQueue();
+        }),
     );
   }
 
+  /**
+   * @private
+   * @return {Promise}
+   */
+  async #processQueue() {
+    if ( this[processingSymbol]) {
+      return Promise.resolve();
+    }
+    this[processingSymbol] = true;
+
+    while (this[pendingDiffsSymbol].length > 0) {
+      const diffResult = this[pendingDiffsSymbol].shift();
+      for (const [, change] of Object.entries(diffResult)) {
+        await new Promise((resolve, reject) => {
+            try {
+              removeElement.call(this, change);
+              insertElement.call(this, change);
+              updateContent.call(this, change);
+              updateAttributes.call(this, change);
+              resolve();
+            } catch (err) {
+              reject(err);
+            }
+        });
+      }
+    }
+
+    this[processingSymbol] = false;
+  }
+
   /**
    * Defaults: 'keyup', 'click', 'change', 'drop', 'touchend'
    *