-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore: Improve dev server performance #5962
base: preview
Are you sure you want to change the base?
Conversation
WalkthroughThe pull request introduces several modifications across multiple files in the web application, primarily focusing on dynamic imports and component loading optimization. The changes involve using Next.js's Changes
Possibly related PRs
Suggested Labels
Suggested Reviewers
Poem
Tip CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
…rove-dev-server-performance
…rove-dev-server-performance
…rove-dev-server-performance
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (8)
web/core/components/cycles/cycles-view.tsx (1)
18-21
: Reconsider SSR disabled configurationWhile dynamic import is correctly implemented, disabling SSR completely might affect SEO and initial page load experience. Consider enabling SSR if the component doesn't rely on browser-specific APIs.
const CyclesList = dynamic(() => import("@/components/cycles/list/root").then((m) => m.CyclesList), { - ssr: false, + ssr: true, loading: () => <CycleModuleListLayout />, });web/core/components/page-views/workspace-dashboard.tsx (2)
7-8
: Remove commented importsThese commented-out imports are no longer needed since they've been replaced with dynamic imports. Clean them up to maintain code clarity.
-// import { DashboardWidgets } from "@/components/dashboard"; -// import { IssuePeekOverview } from "@/components/issues";Also applies to: 10-10
22-40
: Dynamic imports look good, consider adding error boundariesThe dynamic imports are well-implemented with appropriate loading states. However, consider wrapping the dynamically imported components with error boundaries to gracefully handle loading failures.
Example implementation:
import { ErrorBoundary } from '@/components/error-boundary'; const DashboardWidgets = dynamic( () => import("@/components/dashboard/home-dashboard-widgets").then((m) => m.DashboardWidgets), { ssr: false, loading: () => ( <div className="h-full w-full flex items-center justify-center"> <LogoSpinner /> </div> ), } ); // Usage <ErrorBoundary fallback={<div>Failed to load dashboard widgets</div>}> <DashboardWidgets /> </ErrorBoundary>web/core/components/inbox/content/root.tsx (1)
9-9
: Consider dynamically importing the loader componentSince
IssuePeekOverviewLoader
is only used in the loading state ofInboxIssueMainContent
, consider dynamically importing it to further optimize the initial bundle size.-import { IssuePeekOverviewLoader } from "@/components/issues/peek-overview/loader"; +const IssuePeekOverviewLoader = dynamic( + () => import("@/components/issues/peek-overview/loader").then((m) => m.IssuePeekOverviewLoader), + { + ssr: false, + loading: () => null + } +);web/core/components/issues/issue-layouts/roots/project-layout-root.tsx (2)
27-36
: Consider adding a loading state for ProjectAppliedFiltersRootThe current implementation returns
null
during loading which could cause layout shifts. Consider adding a skeleton loader to maintain layout stability.const ProjectAppliedFiltersRoot = dynamic( () => import("@/components/issues/issue-layouts/filters/applied-filters/roots/project-root").then( (m) => m.ProjectAppliedFiltersRoot ), { ssr: false, - loading: () => null, + loading: () => <div className="h-[40px] w-full animate-pulse bg-custom-background-90" />, } );
90-96
: Add loading state for IssuePeekOverviewSimilar to the above, consider adding a skeleton loader instead of returning null to prevent layout shifts.
const IssuePeekOverview = dynamic( () => import("@/components/issues/peek-overview/root").then((m) => m.IssuePeekOverview), { ssr: false, - loading: () => null, + loading: () => <div className="fixed bottom-0 right-0 h-full w-1/3 animate-pulse bg-custom-background-90" />, } );web/core/components/pages/editor/header/options-dropdown.tsx (1)
39-45
: Consider adding a loading indicator for ExportPageModalWhile returning null during loading might be acceptable for a modal, consider adding a loading indicator for better UX, especially on slower connections.
const ExportPageModal = dynamic( () => import("@/components/pages/modals/export-page-modal").then((m) => m.ExportPageModal), { ssr: false, - loading: () => null, + loading: () => ( + <div className="fixed inset-0 z-50 flex items-center justify-center bg-custom-background-90/50"> + <div className="h-8 w-8 animate-spin rounded-full border-2 border-custom-primary border-t-transparent" /> + </div> + ), } );web/next.config.js (1)
142-147
: LGTM! Consider monitoring the optimization impact.The selected library paths are well-chosen core utilities that are likely to benefit from import optimization.
Consider adding a comment explaining why these specific libraries were chosen for optimization, to help future maintainers understand the performance implications.
// lib + // Core utilities frequently imported across the application "@/lib/store-context",
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
web/app/[workspaceSlug]/(projects)/notifications/page.tsx
(1 hunks)web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/issues/(list)/page.tsx
(1 hunks)web/ce/hooks/use-editor-flagging.ts
(1 hunks)web/core/components/analytics/project-modal/modal.tsx
(2 hunks)web/core/components/cycles/cycles-view.tsx
(2 hunks)web/core/components/inbox/content/root.tsx
(1 hunks)web/core/components/issues/filters.tsx
(2 hunks)web/core/components/issues/issue-layouts/roots/project-layout-root.tsx
(2 hunks)web/core/components/page-views/workspace-dashboard.tsx
(2 hunks)web/core/components/pages/editor/header/options-dropdown.tsx
(1 hunks)web/core/components/profile/profile-setting-content-wrapper.tsx
(1 hunks)web/core/hooks/use-workspace-issue-properties.ts
(1 hunks)web/next.config.js
(1 hunks)
✅ Files skipped from review due to trivial changes (3)
- web/core/components/profile/profile-setting-content-wrapper.tsx
- web/ce/hooks/use-editor-flagging.ts
- web/core/hooks/use-workspace-issue-properties.ts
🔇 Additional comments (10)
web/core/components/analytics/project-modal/modal.tsx (1)
3-3
: Verify dynamic import bundle splitting
Let's verify that the dynamic imports are effectively creating separate chunks.
✅ Verification successful
Dynamic imports are correctly implemented for code splitting
The modal component is properly implementing dynamic imports for its heavy components:
ProjectAnalyticsModalHeader
andProjectAnalyticsModalMainContent
are both dynamically imported withssr: false
- Loading states are handled with
loading: () => null
- The imports are correctly scoped to only load when the modal is opened
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for dynamic imports and their impact on bundle splitting
# Search for dynamic import patterns
echo "Checking dynamic import usage:"
rg "dynamic\(\(\) =>" -A 2
# Search for potential candidates for dynamic imports
echo "\nChecking large component imports that could be dynamically imported:"
rg "^import.*from.*components.*" --type tsx
Length of output: 1252
Script:
#!/bin/bash
# Let's verify the dynamic imports more comprehensively
# Check for all dynamic imports using ast-grep
echo "Checking all dynamic imports with ast-grep:"
ast-grep --pattern 'dynamic(() => import($path))'
# Check specifically for the modal component's dynamic imports
echo -e "\nChecking modal-related imports:"
rg "import.*modal" --type ts --type tsx -A 2
# Check the file structure around the modal
echo -e "\nChecking modal component structure:"
fd modal --type f --extension tsx --extension ts
Length of output: 4495
Script:
#!/bin/bash
# Let's check the specific modal component and its usage
# Check the content of the project modal
echo "Checking project modal content:"
cat "web/core/components/analytics/project-modal/modal.tsx"
# Look for imports of this modal
echo -e "\nChecking where this modal is imported:"
rg "analytics/project-modal" --type ts --type tsx -A 2
# Check for any dynamic imports in the same directory
echo -e "\nChecking for other dynamic imports in analytics:"
rg "dynamic" "web/core/components/analytics/" --type ts --type tsx
Length of output: 3393
web/core/components/inbox/content/root.tsx (1)
14-28
: Well-structured dynamic imports with appropriate loading states
The dynamic imports are correctly implemented with SSR disabled and suitable loading states for each component. The separation of header and main content allows for better code splitting.
web/app/[workspaceSlug]/(projects)/notifications/page.tsx (2)
20-26
: Clean dynamic import implementation
The dynamic import is well-implemented with SSR disabled and an appropriate loading state for this use case.
Line range hint 108-116
: Verify the conditional rendering logic for IssuePeekOverview
The component is rendered based on multiple conditions. Let's verify that all cases are properly handled.
✅ Verification successful
Based on the search results, I can now provide a comprehensive verification of the IssuePeekOverview rendering logic. The component is used consistently across the codebase with proper conditional handling.
Conditional rendering in notifications page is properly handled
- The component is rendered based on a clear condition with proper props:
- When not in inbox issue view:
<IssuePeekOverview embedIssue embedRemoveCurrentNotification={embedRemoveCurrentNotification} />
- When in inbox issue view: Renders InboxIssueMainContent with proper props
- When not in inbox issue view:
- The component is loaded dynamically with proper fallback using
dynamic
import - Props interface is well-defined and consistently used
- Error and loading states are handled through IssuePeekOverviewLoader and IssuePeekOverviewError components
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for all possible rendering paths of IssuePeekOverview
# Search for all conditions affecting IssuePeekOverview rendering
rg -A 5 "IssuePeekOverview" --type ts --type tsx
# Search for related state management
rg "currentSelectedNotificationId|is_inbox_issue|workspace_slug|project_id|issue_id" --type ts --type tsx
Length of output: 212
Script:
#!/bin/bash
# Search for IssuePeekOverview usage without file type restrictions
rg -A 5 "IssuePeekOverview"
# Search for the component definition
ast-grep --pattern 'const IssuePeekOverview = $_'
# Search for conditional rendering patterns around IssuePeekOverview
rg -B 5 -A 5 "<IssuePeekOverview"
Length of output: 66041
web/core/components/issues/issue-layouts/roots/project-layout-root.tsx (1)
37-72
: LGTM: Well-implemented dynamic imports with proper loading states
The dynamic imports for layout components are well implemented with appropriate loading states using dedicated loader components. This will improve the initial load time while maintaining a good user experience during loading.
web/core/components/issues/filters.tsx (1)
11-11
: LGTM: Import path improvement
The change from relative to absolute import path is a good practice that improves maintainability and readability.
web/core/components/pages/editor/header/options-dropdown.tsx (1)
31-31
: LGTM: Proper implementation of dynamic imports
The dynamic import of ExportPageModal is well implemented and aligns with the PR's goal of improving dev server performance. The SSR configuration is correct for modal components.
Also applies to: 39-45
web/next.config.js (3)
97-97
: LGTM! Verify the Next.js version compatibility.
The addition of the experimental
configuration aligns with the PR objective of improving dev server performance.
Let's verify the Next.js version compatibility:
✅ Verification successful
The experimental.optimizePackageImports feature is supported in your Next.js version
The project uses Next.js version ^14.2.20, which fully supports the experimental.optimizePackageImports
configuration. This feature was introduced in Next.js 13.1 and has been stable since then, making it safe to use in your configuration.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check if package.json specifies a Next.js version that supports optimizePackageImports
cat package.json | jq -r '.dependencies["next"] // .devDependencies["next"]'
Length of output: 83
Script:
#!/bin/bash
# Let's try to find package.json in the web directory since the config file is in web/
cat web/package.json | jq -r '.dependencies["next"] // .devDependencies["next"]'
Length of output: 91
148-156
: Verify the benefit of optimizing external libraries.
While optimizing internal services makes sense, we should verify if optimizing external libraries like @headlessui/react
and axios
provides meaningful benefits.
Let's analyze the import patterns:
99-141
: Verify the effectiveness of component optimizations.
The component paths are comprehensive, but we should verify:
- That these paths actually contain barrel files
- The impact on bundle size
- Potential circular dependencies
Let's check these aspects:
✅ Verification successful
The previous script failed because we need to first locate the correct paths. Let's find where these files actually exist in the repository structure.
The previous output showed extensive component imports. Let's verify the barrel file structure and look for potential circular dependencies by analyzing imports and exports patterns.
Component optimizations are well-structured and effective
The verification shows that the component paths in next.config.js are well-organized with proper barrel files (index.ts/tsx) present in each component directory. The extensive barrel file structure indicates:
- Proper encapsulation of component modules
- Clean and organized exports
- Efficient code splitting at the component level
Key findings:
- All major component directories have index files for proper module exports
- Component organization follows a clear hierarchy (core, features, ui, etc.)
- Barrel files are consistently used across the codebase
The component optimizations are working as intended, with no immediate concerns about the structure or organization. The barrel files enable efficient code splitting while maintaining clean import/export patterns.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check for barrel files (index.ts/js) in the specified paths
echo "Checking for barrel files..."
for path in $(cat next.config.js | grep '@/components/' | sed 's/.*@//' | sed 's/".*//' | sort -u); do
fd -t f '^index\.(ts|js|tsx|jsx)$' "web${path#/}"
done
# Check for potential circular dependencies
echo "Checking for potential circular dependencies..."
rg -l "import.*from.*@/components.*" web/components
Length of output: 416
Script:
#!/bin/bash
# First, let's locate the next.config.js file
fd -t f "next.config.js$"
# Then, let's check the actual component directory structure
fd -t d "components"
# Finally, let's check imports within components directory if we find it
fd -t f "\.(js|jsx|ts|tsx)$" -d 1 . | xargs rg "import.*from.*@/components.*" || true
Length of output: 66149
Script:
#!/bin/bash
# Let's check for the existence of barrel files (index files) in the web components directory
echo "Checking for barrel files in web components..."
fd -t f "^index\.(js|jsx|ts|tsx)$" web/core/components/
# Let's analyze potential circular dependencies by checking imports between components
echo "Checking for potential circular dependencies..."
rg "import.*from.*@/components/(.*)" web/core/components/ -g "!*.test.*" -g "!*.spec.*" --no-filename | sort | uniq > /tmp/imports.txt
rg "export.*from.*@/components/(.*)" web/core/components/ -g "!*.test.*" -g "!*.spec.*" --no-filename | sort | uniq > /tmp/exports.txt
Length of output: 11641
Summary by CodeRabbit
New Features
PageOptionsDropdown
component.Bug Fixes
Documentation
Chores