From 0d57397454a17142deecafc4bda1a84eb8d28701 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 1 Jun 2026 05:47:12 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Use=20deferred=20value=20fo?= =?UTF-8?q?r=20rubric=20analysis=20during=20text=20streaming?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wrap visibleOutput with useDeferredValue before passing it to the expensive synchronous analyzeText computation. This prevents the main thread from blocking during the rapid character-by-character fake streaming (~24ms intervals), keeping the UI responsive. Co-authored-by: aloewright <3641844+aloewright@users.noreply.github.com> --- .jules/bolt.md | 3 +++ apps/quill/client/components/playground-view.tsx | 12 ++++++++++-- 2 files changed, 13 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..117e7949 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2024-06-01 - Prevent main thread blocking during fake text streaming +**Learning:** During rapid state updates like fake text streaming (e.g. interval ~24ms), passing the rapidly changing state directly to expensive synchronous evaluation functions (like deterministic scoring/analyzing) causes severe main thread blocking and unresponsiveness. +**Action:** Use React's `useDeferredValue` to wrap the rapidly updating stream state before passing it to expensive synchronous functions. This allows React to prioritize UI updates and interrupt the expensive rendering. diff --git a/apps/quill/client/components/playground-view.tsx b/apps/quill/client/components/playground-view.tsx index 511226b4..65abeda1 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,15 @@ export function PlaygroundView({ }; }, [output]); - const snapshot = useMemo(() => analyzeText(visibleOutput), [visibleOutput]); + // ⚡ Bolt: Wrap visibleOutput with useDeferredValue before passing it to the expensive + // synchronous analyzeText computation. This prevents the main thread from blocking + // during the rapid character-by-character fake streaming (~24ms intervals), keeping + // the UI responsive. + const deferredVisibleOutput = useDeferredValue(visibleOutput); + const snapshot = useMemo( + () => analyzeText(deferredVisibleOutput), + [deferredVisibleOutput] + ); const { score, details } = useMemo( () => guide