Skip to content

⚡ Bolt: Optimize project detail page data fetching#26

Open
aicoder2009 wants to merge 2 commits intomainfrom
bolt-optimize-project-details-3229720793011527760
Open

⚡ Bolt: Optimize project detail page data fetching#26
aicoder2009 wants to merge 2 commits intomainfrom
bolt-optimize-project-details-3229720793011527760

Conversation

@aicoder2009
Copy link
Copy Markdown
Owner

💡 What: The data fetching logic in src/app/projects/[id]/page.tsx was optimized to run parallel independent fetches, and defer fetching data that isn't immediately necessary for the UI.
🎯 Why: The project detail page was sequentially fetching project data, then lists data, then all lists data. This blocked the render thread longer than necessary.
📊 Impact: This cuts Time-to-Interactive (TTI) since the major project data fetches are executed concurrently. It also removes one network request (/api/lists) from the critical path entirely, only loading it if the user wants to append an existing list.
🔬 Measurement: Verify by using the "Network" tab in devtools on /projects/:id to see the concurrent timing of /api/projects/:id and /api/projects/:id/lists. Ensure /api/lists is only requested upon clicking "Add List".


PR created automatically by Jules for task 3229720793011527760 started by @aicoder2009

- Fetch `project` details and `lists` within the project concurrently via `Promise.all()` to reduce initial blocking sequence on render.
- Lazy load `allLists` to only fetch when the user triggers the "Add List" UI, trimming unnecessary initial network load.

Co-authored-by: aicoder2009 <[email protected]>
Copilot AI review requested due to automatic review settings April 27, 2026 08:24
@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
opencitation Ready Ready Preview, Comment May 1, 2026 6:25pm

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Optimizes the /projects/[id] detail page’s client-side data fetching to reduce time-to-interactive by parallelizing independent requests and deferring non-critical data until the user initiates an action.

Changes:

  • Fetch project details and project lists concurrently via Promise.all() in src/app/projects/[id]/page.tsx.
  • Lazily fetch “all user lists” (/api/lists) only when the user opens the “Add List” UI.
  • Add a Jules “Bolt” learning note documenting the performance approach.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/app/projects/[id]/page.tsx Parallelizes project + project-lists fetch; defers all-lists fetch until user opens add-list UI.
evaluate_page.py Adds a Python helper script that checks for a substring in the page file.
.jules/bolt.md Documents the “concurrent + lazy fetch” approach as a learning/action item.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

This project has no lists yet.
</p>
<WikiButton variant="primary" onClick={() => setShowAddList(true)}>
<WikiButton variant="primary" onClick={() => { setShowAddList(true); if (!hasFetchedAllLists) fetchAllUserLists(); }}>
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This inline click handler duplicates the “open add list + lazy fetch all lists” behavior implemented in handleToggleAddList, which increases the chance of the two code paths drifting (and makes it harder to add loading/error UI for the add-list panel). Consider reusing the shared handler or extracting a dedicated handleOpenAddList helper used by both buttons.

Suggested change
<WikiButton variant="primary" onClick={() => { setShowAddList(true); if (!hasFetchedAllLists) fetchAllUserLists(); }}>
<WikiButton
variant="primary"
onClick={() => {
if (!showAddList) {
handleToggleAddList();
}
}}
>

Copilot uses AI. Check for mistakes.
Comment thread evaluate_page.py
Comment on lines +1 to +9
import re

with open("src/app/projects/[id]/page.tsx", "r") as f:
content = f.read()

if "fetchProjectAndLists" not in content:
print("Function not found")
else:
print("Function found")
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This Python script appears to be a one-off verification helper (it just checks for a substring in a TSX file) and introduces an otherwise-unused Python artifact into a Node/Next.js repo (there are no npm scripts or other Python utilities). Recommend removing it from the PR, or moving it under scripts/ and rewriting it in TS/JS (or wiring it into CI) if it’s intended to be kept. Also, re is imported but unused.

Suggested change
import re
with open("src/app/projects/[id]/page.tsx", "r") as f:
content = f.read()
if "fetchProjectAndLists" not in content:
print("Function not found")
else:
print("Function found")
import argparse
import sys
def main() -> int:
parser = argparse.ArgumentParser(
description="Verify that a source file contains a required substring."
)
parser.add_argument(
"file_path",
nargs="?",
default="src/app/projects/[id]/page.tsx",
help="Path to the file to inspect.",
)
parser.add_argument(
"expected_text",
nargs="?",
default="fetchProjectAndLists",
help="Substring that must be present in the file.",
)
args = parser.parse_args()
with open(args.file_path, "r", encoding="utf-8") as f:
content = f.read()
if args.expected_text not in content:
print("Function not found")
return 1
print("Function found")
return 0
if __name__ == "__main__":
sys.exit(main())

Copilot uses AI. Check for mistakes.
Comment on lines 98 to +104
if (allListsResult.success) {
setAllLists(allListsResult.data);
setHasFetchedAllLists(true);
}
} catch (err) {
console.error("Error fetching project:", err);
setError("Failed to load project");
} finally {
setIsLoading(false);
console.error("Error fetching all user lists:", err);
}
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fetchAllUserLists swallows failures (only logs to console). If /api/lists fails or returns non-success, the “Add existing list” section will silently stay empty with no user feedback. Consider setting error (or a dedicated allListsError / loading state for the add-list panel) when the request fails or when allListsResult.success is false so the UI can explain what happened.

Copilot uses AI. Check for mistakes.
@aicoder2009 aicoder2009 closed this May 1, 2026
@aicoder2009 aicoder2009 reopened this May 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants