diff --git a/packages/core/components/AutoFrame/index.tsx b/packages/core/components/AutoFrame/index.tsx
index a0d8580f4c..5e15619ee2 100644
--- a/packages/core/components/AutoFrame/index.tsx
+++ b/packages/core/components/AutoFrame/index.tsx
@@ -6,11 +6,24 @@ import {
useEffect,
useState,
} from "react";
-import hash from "object-hash";
import { createPortal } from "react-dom";
const styleSelector = 'style, link[rel="stylesheet"]';
+/**
+ * Fast, non-cryptographic djb2 hash over a string.
+ * Replaces `object-hash` which serialises the full outerHTML via JSON
+ * and is O(n) on the CSS string length — catastrophically slow when
+ * many large style nodes are present.
+ */
+const fastHash = (str: string): string => {
+ let h = 5381;
+ for (let i = 0; i < str.length; i++) {
+ h = (((h << 5) + h) ^ str.charCodeAt(i)) >>> 0;
+ }
+ return h.toString(36);
+};
+
const collectStyles = (doc: Document) => {
const collected: HTMLElement[] = [];
@@ -66,6 +79,25 @@ const syncAttributes = (sourceElement: Element, targetElement: Element) => {
const defer = (fn: () => void) => setTimeout(fn, 0);
+/**
+ * Compute a cheap hash key for a style element.
+ * - For elements we key on the href (a short string).
+ * - For