From 1187733e1086902942748606f00773c150c8a125 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 27 May 2026 06:03:28 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Defer=20expensive=20rub?= =?UTF-8?q?ric=20calculations=20during=20text=20streaming?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: aloewright <3641844+aloewright@users.noreply.github.com> --- .jules/bolt.md | 3 +++ apps/quill/client/components/playground-view.tsx | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 .jules/bolt.md diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 00000000..67cddb26 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2024-05-27 - UI Blocking During Text Streaming +**Learning:** During simulated text generation loops (like `setInterval` firing every 24ms), synchronous deterministic scoring and analysis functions that depend on the rapidly updating text state can bottleneck the main thread, leading to jittery render loops or missed frames. +**Action:** Use React's `useDeferredValue` for rapidly updating text state before passing it into complex computations (like `analyzeText` or `scoreDeterministic` in `useMemo`). This allows React to process the updates asynchronously and interruptibly, maintaining UI responsiveness during simulated text streaming. diff --git a/apps/quill/client/components/playground-view.tsx b/apps/quill/client/components/playground-view.tsx index 511226b4..1dc47006 100644 --- a/apps/quill/client/components/playground-view.tsx +++ b/apps/quill/client/components/playground-view.tsx @@ -1,6 +1,6 @@ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { AnimatePresence, motion } from "framer-motion"; -import { useEffect, useMemo, useRef, useState } from "react"; +import { useDeferredValue, useEffect, useMemo, useRef, useState } from "react"; import { USE_CASE_PRESETS } from "../../src/lib/presets"; import { analyzeText, scoreDeterministic } from "../../src/lib/rubric"; import type { Guide, UseCase } from "../../src/lib/types"; @@ -255,7 +255,11 @@ export function PlaygroundView({ }; }, [output]); - const snapshot = useMemo(() => analyzeText(visibleOutput), [visibleOutput]); + // Defer the expensive analyzeText and scoreDeterministic calculations to a lower + // priority render cycle. This prevents them from blocking the main UI thread during + // rapid state updates like text streaming (which happens every 24ms). + const deferredOutput = useDeferredValue(visibleOutput); + const snapshot = useMemo(() => analyzeText(deferredOutput), [deferredOutput]); const { score, details } = useMemo( () => guide From caec4140227b069f4c4a6cb201944050f3e120e4 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 27 May 2026 06:18:26 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Defer=20expensive=20rub?= =?UTF-8?q?ric=20calculations=20during=20text=20streaming?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: aloewright <3641844+aloewright@users.noreply.github.com>