Skip to content

Commit 04a86f9

Browse files
fix: resolve AI insights loading, clean up debug logs, add favicon
1 parent 65e6778 commit 04a86f9

6 files changed

Lines changed: 29 additions & 8 deletions

File tree

.claude/settings.local.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
"Bash(npx eslint:*)",
1010
"Bash(ls /Users/angeloprabajith/Home/GitHub/shopify-performance-analyzer/eslint.config.*)",
1111
"Bash(ls -la /Users/angeloprabajith/Home/GitHub/shopify-performance-analyzer/eslint*)",
12-
"Bash(npm test:*)"
12+
"Bash(npm test:*)",
13+
"Bash(grep -n \"console.log\\\\|console.error\\\\|console.warn\" /Users/angeloprabajith/Home/GitHub/shopify-performance-analyzer/web/app/api/**/*.ts)",
14+
"Bash(grep -r console. /Users/angeloprabajith/Home/GitHub/shopify-performance-analyzer/web --include=*.tsx --include=*.ts)"
1315
]
1416
}
1517
}

assets/results-page.jpeg

216 KB
Loading

assets/results-page.png

-486 KB
Binary file not shown.

docs/architecture.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ Key design decisions:
6161
| Render Blocking | `render-blocking` | Scripts in `<head>` without async/defer |
6262
| Image Optimization | `image-optimization` | Large images, legacy formats |
6363
| Third-Party Impact | `third-party-impact` | External script weight |
64+
| Resource Hints | `resource-hints` | Missing preconnect/preload for third-party domains |
6465

6566
### Detectors (`src/detectors/`)
6667

web/app/api/ai-insights/route.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { NextRequest, NextResponse } from "next/server";
22
import Anthropic from "@anthropic-ai/sdk";
33
import type { AnalyzeOutput } from "@analyzer";
44

5+
export const maxDuration = 30;
6+
57
const client = new Anthropic();
68

79
export async function POST(req: NextRequest) {

web/components/AIInsights.tsx

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -141,36 +141,52 @@ export function AIInsights({ analyzeOutput }: AIInsightsProps) {
141141
const [data, setData] = useState<AIInsightsData | null>(null);
142142
const [loading, setLoading] = useState(true);
143143
const [error, setError] = useState<string | null>(null);
144-
// Use a ref to prevent re-fetching when the parent re-renders with the same data
145144
const fetchedRef = useRef(false);
146145

147146
useEffect(() => {
148-
if (fetchedRef.current) return;
149-
fetchedRef.current = true;
150-
147+
// In React Strict Mode, the first effect run is cleaned up immediately.
148+
// Reset the ref on cleanup so the second run can actually fetch.
151149
let cancelled = false;
152150

151+
// Skip if we already have data (prevents re-fetching on parent re-renders)
152+
if (fetchedRef.current) return;
153+
153154
async function fetchInsights() {
154155
setLoading(true);
155156
setError(null);
156157

157158
try {
159+
// Send only what the AI endpoint needs (exclude waterfall/pages to reduce payload)
160+
const { waterfall: _w, pages: _p, ...payload } = analyzeOutput;
161+
162+
const controller = new AbortController();
163+
const timeout = setTimeout(() => controller.abort(), 30000);
164+
158165
const res = await fetch("/api/ai-insights", {
159166
method: "POST",
160167
headers: { "Content-Type": "application/json" },
161-
body: JSON.stringify(analyzeOutput),
168+
body: JSON.stringify(payload),
169+
signal: controller.signal,
162170
});
163171

172+
clearTimeout(timeout);
173+
164174
if (!res.ok) {
165175
const body = await res.json().catch(() => ({}));
166176
throw new Error(body.error ?? `HTTP ${res.status}`);
167177
}
168178

169179
const json = await res.json();
170-
if (!cancelled) setData(json);
180+
if (!cancelled) {
181+
fetchedRef.current = true;
182+
setData(json);
183+
}
171184
} catch (err) {
172185
if (!cancelled) {
173-
setError(err instanceof Error ? err.message : "AI request failed");
186+
const msg = err instanceof Error
187+
? err.name === "AbortError" ? "AI request timed out" : err.message
188+
: "AI request failed";
189+
setError(msg);
174190
}
175191
} finally {
176192
if (!cancelled) setLoading(false);

0 commit comments

Comments
 (0)