diff --git a/app/layout.tsx b/app/layout.tsx
index 853ec3208..64b3b13ac 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -2,6 +2,7 @@ import type { Metadata } from "next";
import { Toaster } from "sonner";
import { ThemeProvider } from "@/components/theme-provider";
import { FaviconUpdater } from "@/components/favicon-updater";
+import { ImageDeliveryOptimizer } from "@/components/image-delivery-optimizer";
import "./globals.css";
import { SessionProvider } from "next-auth/react";
@@ -171,6 +172,7 @@ export default async function RootLayout({
+
{
+ optimizeImageElement(image);
+ });
+}
+
+export function ImageDeliveryOptimizer() {
+ useEffect(() => {
+ let frameId = 0;
+ const scheduleOptimize = (root: ParentNode = document) => {
+ if (frameId) {
+ cancelAnimationFrame(frameId);
+ }
+ frameId = requestAnimationFrame(() => {
+ frameId = 0;
+ optimizeAllImages(root);
+ });
+ };
+
+ scheduleOptimize();
+
+ const observer = new MutationObserver((mutations) => {
+ for (const mutation of mutations) {
+ if (mutation.type === "attributes") {
+ const target = mutation.target;
+ if (target instanceof HTMLImageElement) {
+ optimizeImageElement(target);
+ }
+ continue;
+ }
+
+ for (const node of mutation.addedNodes) {
+ if (node instanceof HTMLImageElement) {
+ optimizeImageElement(node);
+ } else if (node instanceof Element) {
+ scheduleOptimize(node);
+ }
+ }
+ }
+ });
+
+ observer.observe(document.body, {
+ attributes: true,
+ attributeFilter: ["src"],
+ childList: true,
+ subtree: true,
+ });
+
+ const handleResize = () => scheduleOptimize();
+ window.addEventListener("resize", handleResize, { passive: true });
+
+ return () => {
+ if (frameId) {
+ cancelAnimationFrame(frameId);
+ }
+ observer.disconnect();
+ window.removeEventListener("resize", handleResize);
+ };
+ }, []);
+
+ return null;
+}
diff --git a/lib/image-delivery.ts b/lib/image-delivery.ts
index e9238d220..99bb21543 100644
--- a/lib/image-delivery.ts
+++ b/lib/image-delivery.ts
@@ -99,6 +99,7 @@ export function buildImageProxyUrl(url: string, options: ImageProxyOptions = {})
if (directDisplayUrl) {
return directDisplayUrl;
}
+ return source;
}
const width = normalizeWidth(options.width);