aigroup-workflow 2.2.0 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/fix-build.md +10 -5
- package/.claude/commands/init-project.md +13 -8
- package/.claude/commands/plan.md +15 -8
- package/.claude/commands/review.md +12 -6
- package/.claude/commands/tdd.md +11 -5
- package/.claude/commands/workflow-start.md +20 -11
- package/.claude/settings.json +28 -0
- package/.codex/agents/architect.toml +207 -0
- package/.codex/agents/build-error-resolver.toml +110 -0
- package/.codex/agents/code-reviewer.toml +233 -0
- package/.codex/agents/doc-updater.toml +103 -0
- package/.codex/agents/e2e-runner.toml +103 -0
- package/.codex/agents/get-current-datetime.toml +23 -0
- package/.codex/agents/init-architect.toml +181 -0
- package/.codex/agents/planner.toml +208 -0
- package/.codex/agents/refactor-cleaner.toml +81 -0
- package/.codex/agents/rust-reviewer.toml +90 -0
- package/.codex/agents/security-reviewer.toml +104 -0
- package/.codex/agents/tdd-guide.toml +87 -0
- package/AGENTS.md +2 -2
- package/CLAUDE.md +23 -1
- package/LICENSE +20 -20
- package/README.md +333 -333
- package/agents/a11y-architect.md +141 -141
- package/agents/architect.md +211 -211
- package/agents/build-error-resolver.md +114 -114
- package/agents/chief-of-staff.md +151 -151
- package/agents/code-architect.md +71 -71
- package/agents/code-explorer.md +69 -69
- package/agents/code-reviewer.md +237 -237
- package/agents/code-simplifier.md +47 -47
- package/agents/comment-analyzer.md +45 -45
- package/agents/conversation-analyzer.md +52 -52
- package/agents/cpp-build-resolver.md +90 -90
- package/agents/cpp-reviewer.md +72 -72
- package/agents/csharp-reviewer.md +101 -101
- package/agents/dart-build-resolver.md +201 -201
- package/agents/database-reviewer.md +91 -91
- package/agents/doc-updater.md +107 -107
- package/agents/docs-lookup.md +68 -68
- package/agents/e2e-runner.md +107 -107
- package/agents/flutter-reviewer.md +243 -243
- package/agents/gan-evaluator.md +209 -209
- package/agents/gan-generator.md +131 -131
- package/agents/gan-planner.md +99 -99
- package/agents/get-current-datetime.md +26 -26
- package/agents/go-build-resolver.md +94 -94
- package/agents/go-reviewer.md +76 -76
- package/agents/harness-optimizer.md +35 -35
- package/agents/healthcare-reviewer.md +83 -83
- package/agents/java-build-resolver.md +153 -153
- package/agents/java-reviewer.md +92 -92
- package/agents/kotlin-build-resolver.md +118 -118
- package/agents/kotlin-reviewer.md +159 -159
- package/agents/loop-operator.md +36 -36
- package/agents/opensource-forker.md +198 -198
- package/agents/opensource-packager.md +249 -249
- package/agents/opensource-sanitizer.md +188 -188
- package/agents/performance-optimizer.md +446 -446
- package/agents/planner.md +212 -212
- package/agents/pr-test-analyzer.md +45 -45
- package/agents/python-reviewer.md +98 -98
- package/agents/pytorch-build-resolver.md +120 -120
- package/agents/refactor-cleaner.md +85 -85
- package/agents/rust-build-resolver.md +148 -148
- package/agents/rust-reviewer.md +94 -94
- package/agents/security-reviewer.md +108 -108
- package/agents/seo-specialist.md +59 -59
- package/agents/silent-failure-hunter.md +50 -50
- package/agents/tdd-guide.md +91 -91
- package/agents/type-design-analyzer.md +41 -41
- package/agents/typescript-reviewer.md +112 -112
- package/cli/commands/update.mjs +1 -1
- package/cli/utils/scaffold.mjs +53 -0
- package/docs/rules/agents.md +166 -50
- package/docs/rules/cpp/coding-style.md +44 -44
- package/docs/rules/cpp/hooks.md +39 -39
- package/docs/rules/cpp/patterns.md +51 -51
- package/docs/rules/cpp/security.md +51 -51
- package/docs/rules/cpp/testing.md +44 -44
- package/docs/rules/csharp/coding-style.md +72 -72
- package/docs/rules/csharp/hooks.md +25 -25
- package/docs/rules/csharp/patterns.md +50 -50
- package/docs/rules/csharp/security.md +58 -58
- package/docs/rules/csharp/testing.md +46 -46
- package/docs/rules/dart/coding-style.md +159 -159
- package/docs/rules/dart/hooks.md +66 -66
- package/docs/rules/dart/patterns.md +261 -261
- package/docs/rules/dart/security.md +135 -135
- package/docs/rules/dart/testing.md +215 -215
- package/docs/rules/golang/coding-style.md +32 -32
- package/docs/rules/golang/hooks.md +17 -17
- package/docs/rules/golang/patterns.md +45 -45
- package/docs/rules/golang/security.md +34 -34
- package/docs/rules/golang/testing.md +31 -31
- package/docs/rules/java/coding-style.md +114 -114
- package/docs/rules/java/hooks.md +18 -18
- package/docs/rules/java/patterns.md +146 -146
- package/docs/rules/java/security.md +100 -100
- package/docs/rules/java/testing.md +131 -131
- package/docs/rules/kotlin/coding-style.md +86 -86
- package/docs/rules/kotlin/hooks.md +17 -17
- package/docs/rules/kotlin/patterns.md +146 -146
- package/docs/rules/kotlin/security.md +82 -82
- package/docs/rules/kotlin/testing.md +128 -128
- package/docs/rules/perl/coding-style.md +46 -46
- package/docs/rules/perl/hooks.md +22 -22
- package/docs/rules/perl/patterns.md +76 -76
- package/docs/rules/perl/security.md +69 -69
- package/docs/rules/perl/testing.md +54 -54
- package/docs/rules/php/coding-style.md +40 -40
- package/docs/rules/php/hooks.md +24 -24
- package/docs/rules/php/patterns.md +33 -33
- package/docs/rules/php/security.md +37 -37
- package/docs/rules/php/testing.md +39 -39
- package/docs/rules/python/coding-style.md +42 -42
- package/docs/rules/python/hooks.md +19 -19
- package/docs/rules/python/patterns.md +39 -39
- package/docs/rules/python/security.md +30 -30
- package/docs/rules/python/testing.md +38 -38
- package/docs/rules/rust/coding-style.md +151 -151
- package/docs/rules/rust/hooks.md +16 -16
- package/docs/rules/rust/patterns.md +168 -168
- package/docs/rules/rust/security.md +141 -141
- package/docs/rules/rust/testing.md +154 -154
- package/docs/rules/swift/coding-style.md +47 -47
- package/docs/rules/swift/hooks.md +20 -20
- package/docs/rules/swift/patterns.md +66 -66
- package/docs/rules/swift/security.md +33 -33
- package/docs/rules/swift/testing.md +45 -45
- package/docs/rules/typescript/coding-style.md +199 -199
- package/docs/rules/typescript/hooks.md +22 -22
- package/docs/rules/typescript/patterns.md +52 -52
- package/docs/rules/typescript/security.md +28 -28
- package/docs/rules/typescript/testing.md +18 -18
- package/docs/rules/web/coding-style.md +96 -96
- package/docs/rules/web/design-quality.md +62 -62
- package/docs/rules/web/hooks.md +120 -120
- package/docs/rules/web/patterns.md +79 -79
- package/docs/rules/web/performance.md +64 -64
- package/docs/rules/web/security.md +57 -57
- package/docs/rules/web/testing.md +55 -55
- package/docs/templates/README.md +36 -36
- package/docs/templates/ai-project-final.md +124 -124
- package/docs/templates/ai-project.md +105 -105
- package/docs/templates/api.md +157 -157
- package/docs/templates/bug.md +62 -62
- package/docs/templates/code-review.md +87 -87
- package/docs/templates/generic.md +116 -116
- package/docs/templates/implementation-plan.md +1 -1
- package/docs/templates/meeting.md +68 -68
- package/docs/templates/prd.md +98 -98
- package/docs/templates/ui.md +134 -134
- package/docs/workflow-pipeline.md +11 -10
- package/package.json +40 -39
- package/scripts/hooks/checks/orchestration-artifacts.cjs +28 -23
- package/scripts/hooks/checks/workflow-state.cjs +4 -5
- package/scripts/orchestration/lib/orchestrator.cjs +344 -117
- package/scripts/orchestration/lib/validate.cjs +145 -0
- package/scripts/orchestration/session.cjs +88 -44
- package/skills/SUPERPOWERS-LICENSE +21 -21
- package/skills/ai-ml/fine-tuning-expert/SKILL.md +162 -162
- package/skills/ai-ml/fine-tuning-expert/references/dataset-preparation.md +540 -540
- package/skills/ai-ml/fine-tuning-expert/references/deployment-optimization.md +673 -673
- package/skills/ai-ml/fine-tuning-expert/references/evaluation-metrics.md +597 -597
- package/skills/ai-ml/fine-tuning-expert/references/hyperparameter-tuning.md +565 -565
- package/skills/ai-ml/fine-tuning-expert/references/lora-peft.md +347 -347
- package/skills/ai-ml/ml-pipeline/SKILL.md +159 -159
- package/skills/ai-ml/ml-pipeline/references/experiment-tracking.md +833 -833
- package/skills/ai-ml/ml-pipeline/references/feature-engineering.md +631 -631
- package/skills/ai-ml/ml-pipeline/references/model-validation.md +978 -978
- package/skills/ai-ml/ml-pipeline/references/pipeline-orchestration.md +907 -907
- package/skills/ai-ml/ml-pipeline/references/training-pipelines.md +782 -782
- package/skills/ai-ml/rag-architect/SKILL.md +194 -194
- package/skills/ai-ml/rag-architect/references/chunking-strategies.md +878 -878
- package/skills/ai-ml/rag-architect/references/embedding-models.md +561 -561
- package/skills/ai-ml/rag-architect/references/rag-evaluation.md +833 -833
- package/skills/ai-ml/rag-architect/references/retrieval-optimization.md +795 -795
- package/skills/ai-ml/rag-architect/references/vector-databases.md +589 -589
- package/skills/ai-ml/spark-engineer/SKILL.md +148 -148
- package/skills/ai-ml/spark-engineer/references/partitioning-caching.md +543 -543
- package/skills/ai-ml/spark-engineer/references/performance-tuning.md +544 -544
- package/skills/ai-ml/spark-engineer/references/rdd-operations.md +599 -599
- package/skills/ai-ml/spark-engineer/references/spark-sql-dataframes.md +474 -474
- package/skills/ai-ml/spark-engineer/references/streaming-patterns.md +786 -786
- package/skills/backend/api-designer/SKILL.md +217 -217
- package/skills/backend/api-designer/references/error-handling.md +541 -541
- package/skills/backend/api-designer/references/openapi.md +824 -824
- package/skills/backend/api-designer/references/pagination.md +494 -494
- package/skills/backend/api-designer/references/rest-patterns.md +335 -335
- package/skills/backend/api-designer/references/versioning.md +391 -391
- package/skills/backend/architecture-designer/SKILL.md +117 -117
- package/skills/backend/architecture-designer/references/adr-template.md +116 -116
- package/skills/backend/architecture-designer/references/architecture-patterns.md +111 -111
- package/skills/backend/architecture-designer/references/database-selection.md +102 -102
- package/skills/backend/architecture-designer/references/nfr-checklist.md +112 -112
- package/skills/backend/architecture-designer/references/system-design.md +100 -100
- package/skills/backend/code-documenter/SKILL.md +147 -147
- package/skills/backend/code-documenter/references/api-docs-fastapi-django.md +166 -166
- package/skills/backend/code-documenter/references/api-docs-nestjs-express.md +220 -220
- package/skills/backend/code-documenter/references/coverage-reports.md +125 -125
- package/skills/backend/code-documenter/references/documentation-systems.md +333 -333
- package/skills/backend/code-documenter/references/interactive-api-docs.md +531 -531
- package/skills/backend/code-documenter/references/python-docstrings.md +121 -121
- package/skills/backend/code-documenter/references/typescript-jsdoc.md +145 -145
- package/skills/backend/code-documenter/references/user-guides-tutorials.md +530 -530
- package/skills/backend/debugging-wizard/SKILL.md +105 -105
- package/skills/backend/debugging-wizard/references/common-patterns.md +132 -132
- package/skills/backend/debugging-wizard/references/debugging-tools.md +140 -140
- package/skills/backend/debugging-wizard/references/quick-fixes.md +177 -177
- package/skills/backend/debugging-wizard/references/strategies.md +142 -142
- package/skills/backend/debugging-wizard/references/systematic-debugging.md +367 -367
- package/skills/backend/feature-forge/SKILL.md +98 -98
- package/skills/backend/feature-forge/references/acceptance-criteria.md +104 -104
- package/skills/backend/feature-forge/references/ears-syntax.md +99 -99
- package/skills/backend/feature-forge/references/interview-questions.md +150 -150
- package/skills/backend/feature-forge/references/pre-discovery-subagents.md +54 -54
- package/skills/backend/feature-forge/references/specification-template.md +103 -103
- package/skills/backend/fullstack-guardian/SKILL.md +105 -105
- package/skills/backend/fullstack-guardian/references/api-design-standards.md +307 -307
- package/skills/backend/fullstack-guardian/references/architecture-decisions.md +350 -350
- package/skills/backend/fullstack-guardian/references/backend-patterns.md +237 -237
- package/skills/backend/fullstack-guardian/references/common-patterns.md +134 -134
- package/skills/backend/fullstack-guardian/references/deliverables-checklist.md +354 -354
- package/skills/backend/fullstack-guardian/references/design-template.md +91 -91
- package/skills/backend/fullstack-guardian/references/error-handling.md +135 -135
- package/skills/backend/fullstack-guardian/references/frontend-patterns.md +340 -340
- package/skills/backend/fullstack-guardian/references/integration-patterns.md +333 -333
- package/skills/backend/fullstack-guardian/references/security-checklist.md +106 -106
- package/skills/backend/graphql-architect/SKILL.md +146 -146
- package/skills/backend/graphql-architect/references/federation.md +418 -418
- package/skills/backend/graphql-architect/references/migration-from-rest.md +1141 -1141
- package/skills/backend/graphql-architect/references/resolvers.md +425 -425
- package/skills/backend/graphql-architect/references/schema-design.md +393 -393
- package/skills/backend/graphql-architect/references/security.md +569 -569
- package/skills/backend/graphql-architect/references/subscriptions.md +510 -510
- package/skills/backend/legacy-modernizer/SKILL.md +137 -137
- package/skills/backend/legacy-modernizer/references/legacy-testing.md +381 -381
- package/skills/backend/legacy-modernizer/references/migration-strategies.md +423 -423
- package/skills/backend/legacy-modernizer/references/refactoring-patterns.md +395 -395
- package/skills/backend/legacy-modernizer/references/strangler-fig-pattern.md +281 -281
- package/skills/backend/legacy-modernizer/references/system-assessment.md +487 -487
- package/skills/backend/microservices-architect/SKILL.md +164 -164
- package/skills/backend/microservices-architect/references/communication.md +499 -499
- package/skills/backend/microservices-architect/references/data.md +721 -721
- package/skills/backend/microservices-architect/references/decomposition.md +344 -344
- package/skills/backend/microservices-architect/references/observability.md +805 -805
- package/skills/backend/microservices-architect/references/patterns.md +603 -603
- package/skills/database/database-optimizer/SKILL.md +147 -147
- package/skills/database/database-optimizer/references/index-strategies.md +331 -331
- package/skills/database/database-optimizer/references/monitoring-analysis.md +501 -501
- package/skills/database/database-optimizer/references/mysql-tuning.md +452 -452
- package/skills/database/database-optimizer/references/postgresql-tuning.md +413 -413
- package/skills/database/database-optimizer/references/query-optimization.md +251 -251
- package/skills/database/postgres-pro/SKILL.md +152 -152
- package/skills/database/postgres-pro/references/extensions.md +404 -404
- package/skills/database/postgres-pro/references/jsonb.md +321 -321
- package/skills/database/postgres-pro/references/maintenance.md +481 -481
- package/skills/database/postgres-pro/references/performance.md +265 -265
- package/skills/database/postgres-pro/references/replication.md +446 -446
- package/skills/database/sql-pro/SKILL.md +129 -129
- package/skills/database/sql-pro/references/database-design.md +402 -402
- package/skills/database/sql-pro/references/dialect-differences.md +419 -419
- package/skills/database/sql-pro/references/optimization.md +384 -384
- package/skills/database/sql-pro/references/query-patterns.md +285 -285
- package/skills/database/sql-pro/references/window-functions.md +328 -328
- package/skills/dotnet/csharp-developer/SKILL.md +125 -125
- package/skills/dotnet/csharp-developer/references/aspnet-core.md +394 -394
- package/skills/dotnet/csharp-developer/references/blazor.md +553 -553
- package/skills/dotnet/csharp-developer/references/entity-framework.md +409 -409
- package/skills/dotnet/csharp-developer/references/modern-csharp.md +248 -248
- package/skills/dotnet/csharp-developer/references/performance.md +498 -498
- package/skills/dotnet/dotnet-core-expert/SKILL.md +138 -138
- package/skills/dotnet/dotnet-core-expert/references/authentication.md +546 -546
- package/skills/dotnet/dotnet-core-expert/references/clean-architecture.md +455 -455
- package/skills/dotnet/dotnet-core-expert/references/cloud-native.md +548 -548
- package/skills/dotnet/dotnet-core-expert/references/entity-framework.md +440 -440
- package/skills/dotnet/dotnet-core-expert/references/minimal-apis.md +319 -319
- package/skills/frontend/angular-architect/SKILL.md +152 -152
- package/skills/frontend/angular-architect/references/components.md +297 -297
- package/skills/frontend/angular-architect/references/ngrx.md +401 -401
- package/skills/frontend/angular-architect/references/routing.md +361 -361
- package/skills/frontend/angular-architect/references/rxjs.md +319 -319
- package/skills/frontend/angular-architect/references/testing.md +405 -405
- package/skills/frontend/design-commands/design.md +91 -91
- package/skills/frontend/design-commands/handoff.md +97 -97
- package/skills/frontend/design-commands/prototype.md +120 -120
- package/skills/frontend/design-commands/spec.md +160 -160
- package/skills/frontend/design-commands/style.md +78 -78
- package/skills/frontend/flutter-expert/SKILL.md +138 -138
- package/skills/frontend/flutter-expert/references/bloc-state.md +259 -259
- package/skills/frontend/flutter-expert/references/gorouter-navigation.md +119 -119
- package/skills/frontend/flutter-expert/references/performance.md +99 -99
- package/skills/frontend/flutter-expert/references/project-structure.md +118 -118
- package/skills/frontend/flutter-expert/references/riverpod-state.md +130 -130
- package/skills/frontend/flutter-expert/references/widget-patterns.md +123 -123
- package/skills/frontend/nextjs-developer/SKILL.md +143 -143
- package/skills/frontend/nextjs-developer/references/app-router.md +311 -311
- package/skills/frontend/nextjs-developer/references/data-fetching.md +482 -482
- package/skills/frontend/nextjs-developer/references/deployment.md +545 -545
- package/skills/frontend/nextjs-developer/references/server-actions.md +462 -462
- package/skills/frontend/nextjs-developer/references/server-components.md +384 -384
- package/skills/frontend/react-expert/SKILL.md +149 -149
- package/skills/frontend/react-expert/references/hooks-patterns.md +162 -162
- package/skills/frontend/react-expert/references/migration-class-to-modern.md +1119 -1119
- package/skills/frontend/react-expert/references/performance.md +168 -168
- package/skills/frontend/react-expert/references/react-19-features.md +174 -174
- package/skills/frontend/react-expert/references/server-components.md +143 -143
- package/skills/frontend/react-expert/references/state-management.md +171 -171
- package/skills/frontend/react-expert/references/testing-react.md +174 -174
- package/skills/frontend/react-native-expert/SKILL.md +185 -185
- package/skills/frontend/react-native-expert/references/expo-router.md +187 -187
- package/skills/frontend/react-native-expert/references/list-optimization.md +204 -204
- package/skills/frontend/react-native-expert/references/platform-handling.md +188 -188
- package/skills/frontend/react-native-expert/references/project-structure.md +171 -171
- package/skills/frontend/react-native-expert/references/storage-hooks.md +173 -173
- package/skills/frontend/senior-frontend/SKILL.md +477 -477
- package/skills/frontend/senior-frontend/references/frontend_best_practices.md +806 -806
- package/skills/frontend/senior-frontend/references/nextjs_optimization_guide.md +724 -724
- package/skills/frontend/senior-frontend/references/react_patterns.md +746 -746
- package/skills/frontend/senior-frontend/scripts/bundle_analyzer.py +407 -407
- package/skills/frontend/senior-frontend/scripts/component_generator.py +329 -329
- package/skills/frontend/senior-frontend/scripts/frontend_scaffolder.py +1005 -1005
- package/skills/frontend/ui-ux-pro-max/SKILL.md +386 -386
- package/skills/frontend/ui-ux-pro-max/data/charts.csv +26 -26
- package/skills/frontend/ui-ux-pro-max/data/colors.csv +97 -97
- package/skills/frontend/ui-ux-pro-max/data/icons.csv +101 -101
- package/skills/frontend/ui-ux-pro-max/data/landing.csv +31 -31
- package/skills/frontend/ui-ux-pro-max/data/products.csv +96 -96
- package/skills/frontend/ui-ux-pro-max/data/react-performance.csv +45 -45
- package/skills/frontend/ui-ux-pro-max/data/stacks/astro.csv +54 -54
- package/skills/frontend/ui-ux-pro-max/data/stacks/flutter.csv +53 -53
- package/skills/frontend/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -56
- package/skills/frontend/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -53
- package/skills/frontend/ui-ux-pro-max/data/stacks/nextjs.csv +53 -53
- package/skills/frontend/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -51
- package/skills/frontend/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -59
- package/skills/frontend/ui-ux-pro-max/data/stacks/react-native.csv +52 -52
- package/skills/frontend/ui-ux-pro-max/data/stacks/react.csv +54 -54
- package/skills/frontend/ui-ux-pro-max/data/stacks/shadcn.csv +61 -61
- package/skills/frontend/ui-ux-pro-max/data/stacks/svelte.csv +54 -54
- package/skills/frontend/ui-ux-pro-max/data/stacks/swiftui.csv +51 -51
- package/skills/frontend/ui-ux-pro-max/data/stacks/vue.csv +50 -50
- package/skills/frontend/ui-ux-pro-max/data/styles.csv +68 -68
- package/skills/frontend/ui-ux-pro-max/data/typography.csv +57 -57
- package/skills/frontend/ui-ux-pro-max/data/ui-reasoning.csv +101 -101
- package/skills/frontend/ui-ux-pro-max/data/ux-guidelines.csv +99 -99
- package/skills/frontend/ui-ux-pro-max/data/web-interface.csv +31 -31
- package/skills/frontend/ui-ux-pro-max/scripts/core.py +253 -253
- package/skills/frontend/ui-ux-pro-max/scripts/design_system.py +1067 -1067
- package/skills/frontend/ui-ux-pro-max/scripts/search.py +114 -114
- package/skills/frontend/vue-expert/SKILL.md +98 -98
- package/skills/frontend/vue-expert/references/build-tooling.md +480 -480
- package/skills/frontend/vue-expert/references/components.md +448 -448
- package/skills/frontend/vue-expert/references/composition-api.md +299 -299
- package/skills/frontend/vue-expert/references/mobile-hybrid.md +636 -636
- package/skills/frontend/vue-expert/references/nuxt.md +669 -669
- package/skills/frontend/vue-expert/references/state-management.md +449 -449
- package/skills/frontend/vue-expert/references/typescript.md +584 -584
- package/skills/frontend/vue-expert-js/SKILL.md +167 -167
- package/skills/frontend/vue-expert-js/references/component-architecture.md +219 -219
- package/skills/frontend/vue-expert-js/references/composables-patterns.md +183 -183
- package/skills/frontend/vue-expert-js/references/jsdoc-typing.md +535 -535
- package/skills/frontend/vue-expert-js/references/state-management.md +249 -249
- package/skills/frontend/vue-expert-js/references/testing-patterns.md +237 -237
- package/skills/go-rust-cpp/cpp-pro/SKILL.md +115 -115
- package/skills/go-rust-cpp/cpp-pro/references/build-tooling.md +440 -440
- package/skills/go-rust-cpp/cpp-pro/references/concurrency.md +437 -437
- package/skills/go-rust-cpp/cpp-pro/references/memory-performance.md +397 -397
- package/skills/go-rust-cpp/cpp-pro/references/modern-cpp.md +304 -304
- package/skills/go-rust-cpp/cpp-pro/references/templates.md +357 -357
- package/skills/go-rust-cpp/golang-pro/SKILL.md +122 -122
- package/skills/go-rust-cpp/golang-pro/references/concurrency.md +329 -329
- package/skills/go-rust-cpp/golang-pro/references/generics.md +442 -442
- package/skills/go-rust-cpp/golang-pro/references/interfaces.md +432 -432
- package/skills/go-rust-cpp/golang-pro/references/project-structure.md +477 -477
- package/skills/go-rust-cpp/golang-pro/references/testing.md +451 -451
- package/skills/go-rust-cpp/rust-engineer/SKILL.md +167 -167
- package/skills/go-rust-cpp/rust-engineer/references/async.md +458 -458
- package/skills/go-rust-cpp/rust-engineer/references/error-handling.md +334 -334
- package/skills/go-rust-cpp/rust-engineer/references/ownership.md +278 -278
- package/skills/go-rust-cpp/rust-engineer/references/testing.md +470 -470
- package/skills/go-rust-cpp/rust-engineer/references/traits.md +413 -413
- package/skills/infra/cli-developer/SKILL.md +113 -113
- package/skills/infra/cli-developer/references/design-patterns.md +221 -221
- package/skills/infra/cli-developer/references/go-cli.md +540 -540
- package/skills/infra/cli-developer/references/node-cli.md +383 -383
- package/skills/infra/cli-developer/references/python-cli.md +422 -422
- package/skills/infra/cli-developer/references/ux-patterns.md +448 -448
- package/skills/infra/cloud-architect/SKILL.md +216 -216
- package/skills/infra/cloud-architect/references/aws.md +394 -394
- package/skills/infra/cloud-architect/references/azure.md +562 -562
- package/skills/infra/cloud-architect/references/cost.md +582 -582
- package/skills/infra/cloud-architect/references/gcp.md +633 -633
- package/skills/infra/cloud-architect/references/multi-cloud.md +483 -483
- package/skills/infra/devops-engineer/SKILL.md +144 -144
- package/skills/infra/devops-engineer/references/deployment-strategies.md +241 -241
- package/skills/infra/devops-engineer/references/docker-patterns.md +113 -113
- package/skills/infra/devops-engineer/references/github-actions.md +139 -139
- package/skills/infra/devops-engineer/references/incident-response.md +331 -331
- package/skills/infra/devops-engineer/references/kubernetes.md +154 -154
- package/skills/infra/devops-engineer/references/platform-engineering.md +417 -417
- package/skills/infra/devops-engineer/references/release-automation.md +527 -527
- package/skills/infra/devops-engineer/references/terraform-iac.md +141 -141
- package/skills/infra/kubernetes-specialist/SKILL.md +241 -241
- package/skills/infra/kubernetes-specialist/references/configuration.md +452 -452
- package/skills/infra/kubernetes-specialist/references/cost-optimization.md +458 -458
- package/skills/infra/kubernetes-specialist/references/custom-operators.md +563 -563
- package/skills/infra/kubernetes-specialist/references/gitops.md +530 -530
- package/skills/infra/kubernetes-specialist/references/helm-charts.md +912 -912
- package/skills/infra/kubernetes-specialist/references/multi-cluster.md +507 -507
- package/skills/infra/kubernetes-specialist/references/networking.md +447 -447
- package/skills/infra/kubernetes-specialist/references/service-mesh.md +459 -459
- package/skills/infra/kubernetes-specialist/references/storage.md +535 -535
- package/skills/infra/kubernetes-specialist/references/troubleshooting.md +414 -414
- package/skills/infra/kubernetes-specialist/references/workloads.md +377 -377
- package/skills/infra/mcp-developer/SKILL.md +143 -143
- package/skills/infra/mcp-developer/references/protocol.md +244 -244
- package/skills/infra/mcp-developer/references/python-sdk.md +367 -367
- package/skills/infra/mcp-developer/references/resources.md +554 -554
- package/skills/infra/mcp-developer/references/tools.md +480 -480
- package/skills/infra/mcp-developer/references/typescript-sdk.md +350 -350
- package/skills/infra/monitoring-expert/SKILL.md +176 -176
- package/skills/infra/monitoring-expert/references/alerting-rules.md +141 -141
- package/skills/infra/monitoring-expert/references/application-profiling.md +331 -331
- package/skills/infra/monitoring-expert/references/capacity-planning.md +344 -344
- package/skills/infra/monitoring-expert/references/dashboards.md +126 -126
- package/skills/infra/monitoring-expert/references/opentelemetry.md +123 -123
- package/skills/infra/monitoring-expert/references/performance-testing.md +269 -269
- package/skills/infra/monitoring-expert/references/prometheus-metrics.md +136 -136
- package/skills/infra/monitoring-expert/references/structured-logging.md +142 -142
- package/skills/infra/sre-engineer/SKILL.md +181 -181
- package/skills/infra/sre-engineer/references/automation-toil.md +492 -492
- package/skills/infra/sre-engineer/references/error-budget-policy.md +334 -334
- package/skills/infra/sre-engineer/references/incident-chaos.md +576 -576
- package/skills/infra/sre-engineer/references/monitoring-alerting.md +424 -424
- package/skills/infra/sre-engineer/references/slo-sli-management.md +238 -238
- package/skills/infra/terraform-engineer/SKILL.md +143 -143
- package/skills/infra/terraform-engineer/references/best-practices.md +583 -583
- package/skills/infra/terraform-engineer/references/module-patterns.md +297 -297
- package/skills/infra/terraform-engineer/references/providers.md +452 -452
- package/skills/infra/terraform-engineer/references/state-management.md +371 -371
- package/skills/infra/terraform-engineer/references/testing.md +486 -486
- package/skills/infra/websocket-engineer/SKILL.md +168 -168
- package/skills/infra/websocket-engineer/references/alternatives.md +391 -391
- package/skills/infra/websocket-engineer/references/patterns.md +400 -400
- package/skills/infra/websocket-engineer/references/protocol.md +195 -195
- package/skills/infra/websocket-engineer/references/scaling.md +333 -333
- package/skills/infra/websocket-engineer/references/security.md +474 -474
- package/skills/java/java-architect/SKILL.md +132 -132
- package/skills/java/java-architect/references/jpa-optimization.md +393 -393
- package/skills/java/java-architect/references/reactive-webflux.md +356 -356
- package/skills/java/java-architect/references/spring-boot-setup.md +269 -269
- package/skills/java/java-architect/references/spring-security.md +445 -445
- package/skills/java/java-architect/references/testing-patterns.md +500 -500
- package/skills/java/kotlin-specialist/SKILL.md +147 -147
- package/skills/java/kotlin-specialist/references/android-compose.md +419 -419
- package/skills/java/kotlin-specialist/references/coroutines-flow.md +276 -276
- package/skills/java/kotlin-specialist/references/dsl-idioms.md +421 -421
- package/skills/java/kotlin-specialist/references/ktor-server.md +426 -426
- package/skills/java/kotlin-specialist/references/multiplatform-kmp.md +380 -380
- package/skills/java/spring-boot-engineer/SKILL.md +195 -195
- package/skills/java/spring-boot-engineer/references/cloud.md +498 -498
- package/skills/java/spring-boot-engineer/references/data.md +381 -381
- package/skills/java/spring-boot-engineer/references/security.md +459 -459
- package/skills/java/spring-boot-engineer/references/testing.md +545 -545
- package/skills/java/spring-boot-engineer/references/web.md +295 -295
- package/skills/javascript/javascript-pro/SKILL.md +132 -132
- package/skills/javascript/javascript-pro/references/async-patterns.md +334 -334
- package/skills/javascript/javascript-pro/references/browser-apis.md +398 -398
- package/skills/javascript/javascript-pro/references/modern-syntax.md +272 -272
- package/skills/javascript/javascript-pro/references/modules.md +357 -357
- package/skills/javascript/javascript-pro/references/node-essentials.md +471 -471
- package/skills/javascript/nestjs-expert/SKILL.md +206 -206
- package/skills/javascript/nestjs-expert/references/authentication.md +166 -166
- package/skills/javascript/nestjs-expert/references/controllers-routing.md +111 -111
- package/skills/javascript/nestjs-expert/references/dtos-validation.md +153 -153
- package/skills/javascript/nestjs-expert/references/migration-from-express.md +1237 -1237
- package/skills/javascript/nestjs-expert/references/services-di.md +140 -140
- package/skills/javascript/nestjs-expert/references/testing-patterns.md +186 -186
- package/skills/javascript/typescript-pro/SKILL.md +145 -145
- package/skills/javascript/typescript-pro/references/advanced-types.md +259 -259
- package/skills/javascript/typescript-pro/references/configuration.md +445 -445
- package/skills/javascript/typescript-pro/references/patterns.md +484 -484
- package/skills/javascript/typescript-pro/references/type-guards.md +352 -352
- package/skills/javascript/typescript-pro/references/utility-types.md +329 -329
- package/skills/php/laravel-specialist/SKILL.md +262 -262
- package/skills/php/laravel-specialist/references/eloquent.md +351 -351
- package/skills/php/laravel-specialist/references/livewire.md +512 -512
- package/skills/php/laravel-specialist/references/queues.md +423 -423
- package/skills/php/laravel-specialist/references/routing.md +362 -362
- package/skills/php/laravel-specialist/references/testing.md +522 -522
- package/skills/php/php-pro/SKILL.md +206 -206
- package/skills/php/php-pro/references/async-patterns.md +412 -412
- package/skills/php/php-pro/references/laravel-patterns.md +377 -377
- package/skills/php/php-pro/references/modern-php-features.md +323 -323
- package/skills/php/php-pro/references/symfony-patterns.md +466 -466
- package/skills/php/php-pro/references/testing-quality.md +466 -466
- package/skills/product/competitive-analysis/SKILL.md +257 -257
- package/skills/product/meeting-notes/SKILL.md +266 -266
- package/skills/product/prd-template/SKILL.md +150 -150
- package/skills/product/stakeholder-update/SKILL.md +225 -225
- package/skills/product/user-research-synthesis/SKILL.md +235 -235
- package/skills/python/django-expert/SKILL.md +162 -162
- package/skills/python/django-expert/references/authentication.md +145 -145
- package/skills/python/django-expert/references/drf-serializers.md +148 -148
- package/skills/python/django-expert/references/models-orm.md +151 -151
- package/skills/python/django-expert/references/testing-django.md +204 -204
- package/skills/python/django-expert/references/viewsets-views.md +153 -153
- package/skills/python/fastapi-expert/SKILL.md +185 -185
- package/skills/python/fastapi-expert/references/async-sqlalchemy.md +146 -146
- package/skills/python/fastapi-expert/references/authentication.md +159 -159
- package/skills/python/fastapi-expert/references/endpoints-routing.md +142 -142
- package/skills/python/fastapi-expert/references/migration-from-django.md +996 -996
- package/skills/python/fastapi-expert/references/pydantic-v2.md +135 -135
- package/skills/python/fastapi-expert/references/testing-async.md +159 -159
- package/skills/python/pandas-pro/SKILL.md +178 -178
- package/skills/python/pandas-pro/references/aggregation-groupby.md +545 -545
- package/skills/python/pandas-pro/references/data-cleaning.md +500 -500
- package/skills/python/pandas-pro/references/dataframe-operations.md +420 -420
- package/skills/python/pandas-pro/references/merging-joining.md +596 -596
- package/skills/python/pandas-pro/references/performance-optimization.md +597 -597
- package/skills/python/python-pro/SKILL.md +177 -177
- package/skills/python/python-pro/references/async-patterns.md +356 -356
- package/skills/python/python-pro/references/packaging.md +460 -460
- package/skills/python/python-pro/references/standard-library.md +378 -378
- package/skills/python/python-pro/references/testing.md +404 -404
- package/skills/python/python-pro/references/type-system.md +290 -290
- package/skills/quality/chaos-engineer/SKILL.md +182 -182
- package/skills/quality/chaos-engineer/references/chaos-tools.md +511 -511
- package/skills/quality/chaos-engineer/references/experiment-design.md +229 -229
- package/skills/quality/chaos-engineer/references/game-days.md +434 -434
- package/skills/quality/chaos-engineer/references/infrastructure-chaos.md +348 -348
- package/skills/quality/chaos-engineer/references/kubernetes-chaos.md +432 -432
- package/skills/quality/code-reviewer/SKILL.md +119 -119
- package/skills/quality/code-reviewer/references/common-issues.md +142 -142
- package/skills/quality/code-reviewer/references/feedback-examples.md +144 -144
- package/skills/quality/code-reviewer/references/receiving-feedback.md +238 -238
- package/skills/quality/code-reviewer/references/report-template.md +109 -109
- package/skills/quality/code-reviewer/references/review-checklist.md +88 -88
- package/skills/quality/code-reviewer/references/spec-compliance-review.md +258 -258
- package/skills/quality/playwright-expert/SKILL.md +169 -169
- package/skills/quality/playwright-expert/references/api-mocking.md +140 -140
- package/skills/quality/playwright-expert/references/configuration.md +155 -155
- package/skills/quality/playwright-expert/references/debugging-flaky.md +150 -150
- package/skills/quality/playwright-expert/references/page-object-model.md +152 -152
- package/skills/quality/playwright-expert/references/selectors-locators.md +119 -119
- package/skills/quality/secure-code-guardian/SKILL.md +191 -191
- package/skills/quality/secure-code-guardian/references/authentication.md +136 -136
- package/skills/quality/secure-code-guardian/references/input-validation.md +146 -146
- package/skills/quality/secure-code-guardian/references/owasp-prevention.md +135 -135
- package/skills/quality/secure-code-guardian/references/security-headers.md +133 -133
- package/skills/quality/secure-code-guardian/references/xss-csrf.md +157 -157
- package/skills/quality/security-reviewer/SKILL.md +103 -103
- package/skills/quality/security-reviewer/references/infrastructure-security.md +268 -268
- package/skills/quality/security-reviewer/references/penetration-testing.md +268 -268
- package/skills/quality/security-reviewer/references/report-template.md +170 -170
- package/skills/quality/security-reviewer/references/sast-tools.md +117 -117
- package/skills/quality/security-reviewer/references/secret-scanning.md +125 -125
- package/skills/quality/security-reviewer/references/vulnerability-patterns.md +152 -152
- package/skills/quality/senior-qa/README.md +196 -196
- package/skills/quality/senior-qa/SKILL.md +399 -399
- package/skills/quality/senior-qa/references/qa_best_practices.md +964 -964
- package/skills/quality/senior-qa/references/test_automation_patterns.md +1009 -1009
- package/skills/quality/senior-qa/references/testing_strategies.md +649 -649
- package/skills/quality/senior-qa/scripts/coverage_analyzer.py +836 -836
- package/skills/quality/senior-qa/scripts/e2e_test_scaffolder.py +820 -820
- package/skills/quality/senior-qa/scripts/test_suite_generator.py +605 -605
- package/skills/quality/tdd-guide/HOW_TO_USE.md +313 -313
- package/skills/quality/tdd-guide/README.md +680 -680
- package/skills/quality/tdd-guide/SKILL.md +122 -122
- package/skills/quality/tdd-guide/assets/expected_output.json +77 -77
- package/skills/quality/tdd-guide/assets/sample_input_python.json +39 -39
- package/skills/quality/tdd-guide/assets/sample_input_typescript.json +36 -36
- package/skills/quality/tdd-guide/references/ci-integration.md +195 -195
- package/skills/quality/tdd-guide/references/framework-guide.md +206 -206
- package/skills/quality/tdd-guide/references/tdd-best-practices.md +128 -128
- package/skills/quality/tdd-guide/scripts/coverage_analyzer.py +434 -434
- package/skills/quality/tdd-guide/scripts/fixture_generator.py +440 -440
- package/skills/quality/tdd-guide/scripts/format_detector.py +384 -384
- package/skills/quality/tdd-guide/scripts/framework_adapter.py +428 -428
- package/skills/quality/tdd-guide/scripts/metrics_calculator.py +456 -456
- package/skills/quality/tdd-guide/scripts/output_formatter.py +354 -354
- package/skills/quality/tdd-guide/scripts/tdd_workflow.py +474 -474
- package/skills/quality/tdd-guide/scripts/test_generator.py +438 -438
- package/skills/quality/test-master/SKILL.md +94 -94
- package/skills/quality/test-master/references/automation-frameworks.md +294 -294
- package/skills/quality/test-master/references/e2e-testing.md +128 -128
- package/skills/quality/test-master/references/integration-testing.md +120 -120
- package/skills/quality/test-master/references/performance-testing.md +118 -118
- package/skills/quality/test-master/references/qa-methodology.md +247 -247
- package/skills/quality/test-master/references/security-testing.md +127 -127
- package/skills/quality/test-master/references/tdd-iron-laws.md +174 -174
- package/skills/quality/test-master/references/test-reports.md +104 -104
- package/skills/quality/test-master/references/testing-anti-patterns.md +231 -231
- package/skills/quality/test-master/references/unit-testing.md +113 -113
- package/skills/ruby/rails-expert/SKILL.md +154 -154
- package/skills/ruby/rails-expert/references/active-record.md +244 -244
- package/skills/ruby/rails-expert/references/api-development.md +401 -401
- package/skills/ruby/rails-expert/references/background-jobs.md +272 -272
- package/skills/ruby/rails-expert/references/hotwire-turbo.md +228 -228
- package/skills/ruby/rails-expert/references/rspec-testing.md +367 -367
- package/skills/swift/swift-expert/SKILL.md +163 -163
- package/skills/swift/swift-expert/references/async-concurrency.md +360 -360
- package/skills/swift/swift-expert/references/memory-performance.md +377 -377
- package/skills/swift/swift-expert/references/protocol-oriented.md +354 -354
- package/skills/swift/swift-expert/references/swiftui-patterns.md +291 -291
- package/skills/swift/swift-expert/references/testing-patterns.md +399 -399
- package/skills/workflow/brainstorming/SKILL.md +164 -164
- package/skills/workflow/brainstorming/scripts/frame-template.html +214 -214
- package/skills/workflow/brainstorming/scripts/helper.js +88 -88
- package/skills/workflow/brainstorming/scripts/server.cjs +354 -354
- package/skills/workflow/brainstorming/scripts/start-server.sh +148 -148
- package/skills/workflow/brainstorming/scripts/stop-server.sh +56 -56
- package/skills/workflow/brainstorming/spec-document-reviewer-prompt.md +49 -49
- package/skills/workflow/brainstorming/visual-companion.md +287 -287
- package/skills/workflow/documentation/SKILL.md +45 -45
- package/skills/workflow/entropy-management/SKILL.md +115 -115
- package/skills/workflow/executing-plans/SKILL.md +70 -70
- package/skills/workflow/finishing-a-development-branch/SKILL.md +200 -200
- package/skills/workflow/receiving-code-review/SKILL.md +213 -213
- package/skills/workflow/requesting-code-review/SKILL.md +105 -105
- package/skills/workflow/requesting-code-review/code-reviewer.md +146 -146
- package/skills/workflow/requirement-engineering/SKILL.md +111 -111
- package/skills/workflow/systematic-debugging/CREATION-LOG.md +119 -119
- package/skills/workflow/systematic-debugging/SKILL.md +296 -296
- package/skills/workflow/systematic-debugging/condition-based-waiting-example.ts +158 -158
- package/skills/workflow/systematic-debugging/condition-based-waiting.md +115 -115
- package/skills/workflow/systematic-debugging/defense-in-depth.md +122 -122
- package/skills/workflow/systematic-debugging/find-polluter.sh +63 -63
- package/skills/workflow/systematic-debugging/root-cause-tracing.md +169 -169
- package/skills/workflow/systematic-debugging/test-academic.md +14 -14
- package/skills/workflow/systematic-debugging/test-pressure-1.md +58 -58
- package/skills/workflow/systematic-debugging/test-pressure-2.md +68 -68
- package/skills/workflow/systematic-debugging/test-pressure-3.md +69 -69
- package/skills/workflow/using-git-worktrees/SKILL.md +218 -218
- package/skills/workflow/verification-before-completion/SKILL.md +139 -139
- package/skills/workflow/writing-plans/SKILL.md +151 -151
- package/skills/workflow/writing-plans/plan-document-reviewer-prompt.md +49 -49
- package/skills/workflow/writing-skills/SKILL.md +655 -655
- package/skills/workflow/writing-skills/anthropic-best-practices.md +1150 -1150
- package/skills/workflow/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -189
- package/skills/workflow/writing-skills/persuasion-principles.md +187 -187
- package/skills/workflow/writing-skills/render-graphs.js +168 -168
- package/skills/workflow/writing-skills/testing-skills-with-subagents.md +384 -384
|
@@ -1,724 +1,724 @@
|
|
|
1
|
-
# Next.js Optimization Guide
|
|
2
|
-
|
|
3
|
-
Performance optimization techniques for Next.js 14+ applications.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Table of Contents
|
|
8
|
-
|
|
9
|
-
- [Rendering Strategies](#rendering-strategies)
|
|
10
|
-
- [Image Optimization](#image-optimization)
|
|
11
|
-
- [Code Splitting](#code-splitting)
|
|
12
|
-
- [Data Fetching](#data-fetching)
|
|
13
|
-
- [Caching Strategies](#caching-strategies)
|
|
14
|
-
- [Bundle Optimization](#bundle-optimization)
|
|
15
|
-
- [Core Web Vitals](#core-web-vitals)
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## Rendering Strategies
|
|
20
|
-
|
|
21
|
-
### Server Components (Default)
|
|
22
|
-
|
|
23
|
-
Server Components render on the server and send HTML to the client. Use for data-heavy, non-interactive content.
|
|
24
|
-
|
|
25
|
-
```tsx
|
|
26
|
-
// app/products/page.tsx - Server Component (default)
|
|
27
|
-
async function ProductsPage() {
|
|
28
|
-
// This runs on the server - no client bundle impact
|
|
29
|
-
const products = await db.products.findMany();
|
|
30
|
-
|
|
31
|
-
return (
|
|
32
|
-
<div className="grid grid-cols-3 gap-4">
|
|
33
|
-
{products.map(product => (
|
|
34
|
-
<ProductCard key={product.id} product={product} />
|
|
35
|
-
))}
|
|
36
|
-
</div>
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
### Client Components
|
|
42
|
-
|
|
43
|
-
Use `'use client'` only when you need:
|
|
44
|
-
- Event handlers (onClick, onChange)
|
|
45
|
-
- State (useState, useReducer)
|
|
46
|
-
- Effects (useEffect)
|
|
47
|
-
- Browser APIs (window, document)
|
|
48
|
-
|
|
49
|
-
```tsx
|
|
50
|
-
'use client';
|
|
51
|
-
|
|
52
|
-
import { useState } from 'react';
|
|
53
|
-
|
|
54
|
-
function AddToCartButton({ productId }: { productId: string }) {
|
|
55
|
-
const [isAdding, setIsAdding] = useState(false);
|
|
56
|
-
|
|
57
|
-
async function handleClick() {
|
|
58
|
-
setIsAdding(true);
|
|
59
|
-
await addToCart(productId);
|
|
60
|
-
setIsAdding(false);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return (
|
|
64
|
-
<button onClick={handleClick} disabled={isAdding}>
|
|
65
|
-
{isAdding ? 'Adding...' : 'Add to Cart'}
|
|
66
|
-
</button>
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
### Mixing Server and Client Components
|
|
72
|
-
|
|
73
|
-
```tsx
|
|
74
|
-
// app/products/[id]/page.tsx - Server Component
|
|
75
|
-
async function ProductPage({ params }: { params: { id: string } }) {
|
|
76
|
-
const product = await getProduct(params.id);
|
|
77
|
-
|
|
78
|
-
return (
|
|
79
|
-
<div>
|
|
80
|
-
{/* Server-rendered content */}
|
|
81
|
-
<h1>{product.name}</h1>
|
|
82
|
-
<p>{product.description}</p>
|
|
83
|
-
|
|
84
|
-
{/* Client component for interactivity */}
|
|
85
|
-
<AddToCartButton productId={product.id} />
|
|
86
|
-
|
|
87
|
-
{/* Server component for reviews */}
|
|
88
|
-
<ProductReviews productId={product.id} />
|
|
89
|
-
</div>
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
### Static vs Dynamic Rendering
|
|
95
|
-
|
|
96
|
-
```tsx
|
|
97
|
-
// Force static generation at build time
|
|
98
|
-
export const dynamic = 'force-static';
|
|
99
|
-
|
|
100
|
-
// Force dynamic rendering at request time
|
|
101
|
-
export const dynamic = 'force-dynamic';
|
|
102
|
-
|
|
103
|
-
// Revalidate every 60 seconds (ISR)
|
|
104
|
-
export const revalidate = 60;
|
|
105
|
-
|
|
106
|
-
// Revalidate on-demand
|
|
107
|
-
import { revalidatePath, revalidateTag } from 'next/cache';
|
|
108
|
-
|
|
109
|
-
async function updateProduct(id: string, data: ProductData) {
|
|
110
|
-
await db.products.update({ where: { id }, data });
|
|
111
|
-
|
|
112
|
-
// Revalidate specific path
|
|
113
|
-
revalidatePath(`/products/${id}`);
|
|
114
|
-
|
|
115
|
-
// Or revalidate by tag
|
|
116
|
-
revalidateTag('products');
|
|
117
|
-
}
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
## Image Optimization
|
|
123
|
-
|
|
124
|
-
### Next.js Image Component
|
|
125
|
-
|
|
126
|
-
```tsx
|
|
127
|
-
import Image from 'next/image';
|
|
128
|
-
|
|
129
|
-
// Basic optimized image
|
|
130
|
-
<Image
|
|
131
|
-
src="/hero.jpg"
|
|
132
|
-
alt="Hero image"
|
|
133
|
-
width={1200}
|
|
134
|
-
height={600}
|
|
135
|
-
priority // Load immediately for LCP
|
|
136
|
-
/>
|
|
137
|
-
|
|
138
|
-
// Responsive image
|
|
139
|
-
<Image
|
|
140
|
-
src="/product.jpg"
|
|
141
|
-
alt="Product"
|
|
142
|
-
fill
|
|
143
|
-
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
|
|
144
|
-
className="object-cover"
|
|
145
|
-
/>
|
|
146
|
-
|
|
147
|
-
// With placeholder blur
|
|
148
|
-
import productImage from '@/public/product.jpg';
|
|
149
|
-
|
|
150
|
-
<Image
|
|
151
|
-
src={productImage}
|
|
152
|
-
alt="Product"
|
|
153
|
-
placeholder="blur" // Uses imported image data
|
|
154
|
-
/>
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
### Remote Images Configuration
|
|
158
|
-
|
|
159
|
-
```js
|
|
160
|
-
// next.config.js
|
|
161
|
-
module.exports = {
|
|
162
|
-
images: {
|
|
163
|
-
remotePatterns: [
|
|
164
|
-
{
|
|
165
|
-
protocol: 'https',
|
|
166
|
-
hostname: 'cdn.example.com',
|
|
167
|
-
pathname: '/images/**',
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
protocol: 'https',
|
|
171
|
-
hostname: '*.cloudinary.com',
|
|
172
|
-
},
|
|
173
|
-
],
|
|
174
|
-
// Image formats (webp is default)
|
|
175
|
-
formats: ['image/avif', 'image/webp'],
|
|
176
|
-
// Device sizes for srcset
|
|
177
|
-
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
|
|
178
|
-
// Image sizes for srcset
|
|
179
|
-
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
|
|
180
|
-
},
|
|
181
|
-
};
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### Lazy Loading Patterns
|
|
185
|
-
|
|
186
|
-
```tsx
|
|
187
|
-
// Images below the fold - lazy load (default)
|
|
188
|
-
<Image
|
|
189
|
-
src="/gallery/photo1.jpg"
|
|
190
|
-
alt="Gallery photo"
|
|
191
|
-
width={400}
|
|
192
|
-
height={300}
|
|
193
|
-
loading="lazy" // Default behavior
|
|
194
|
-
/>
|
|
195
|
-
|
|
196
|
-
// Above the fold - load immediately
|
|
197
|
-
<Image
|
|
198
|
-
src="/hero.jpg"
|
|
199
|
-
alt="Hero"
|
|
200
|
-
width={1200}
|
|
201
|
-
height={600}
|
|
202
|
-
priority
|
|
203
|
-
loading="eager"
|
|
204
|
-
/>
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
---
|
|
208
|
-
|
|
209
|
-
## Code Splitting
|
|
210
|
-
|
|
211
|
-
### Dynamic Imports
|
|
212
|
-
|
|
213
|
-
```tsx
|
|
214
|
-
import dynamic from 'next/dynamic';
|
|
215
|
-
|
|
216
|
-
// Basic dynamic import
|
|
217
|
-
const HeavyChart = dynamic(() => import('@/components/HeavyChart'), {
|
|
218
|
-
loading: () => <ChartSkeleton />,
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
// Disable SSR for client-only components
|
|
222
|
-
const MapComponent = dynamic(() => import('@/components/Map'), {
|
|
223
|
-
ssr: false,
|
|
224
|
-
loading: () => <div className="h-[400px] bg-gray-100" />,
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
// Named exports
|
|
228
|
-
const Modal = dynamic(() =>
|
|
229
|
-
import('@/components/ui').then(mod => mod.Modal)
|
|
230
|
-
);
|
|
231
|
-
|
|
232
|
-
// With suspense
|
|
233
|
-
const DashboardCharts = dynamic(() => import('@/components/DashboardCharts'), {
|
|
234
|
-
loading: () => <Suspense fallback={<ChartsSkeleton />} />,
|
|
235
|
-
});
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
### Route-Based Splitting
|
|
239
|
-
|
|
240
|
-
```tsx
|
|
241
|
-
// app/dashboard/analytics/page.tsx
|
|
242
|
-
// This page only loads when /dashboard/analytics is visited
|
|
243
|
-
import { Suspense } from 'react';
|
|
244
|
-
import AnalyticsCharts from './AnalyticsCharts';
|
|
245
|
-
|
|
246
|
-
export default function AnalyticsPage() {
|
|
247
|
-
return (
|
|
248
|
-
<Suspense fallback={<AnalyticsSkeleton />}>
|
|
249
|
-
<AnalyticsCharts />
|
|
250
|
-
</Suspense>
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
### Parallel Routes for Code Splitting
|
|
256
|
-
|
|
257
|
-
```
|
|
258
|
-
app/
|
|
259
|
-
├── dashboard/
|
|
260
|
-
│ ├── @analytics/
|
|
261
|
-
│ │ └── page.tsx # Loaded in parallel
|
|
262
|
-
│ ├── @metrics/
|
|
263
|
-
│ │ └── page.tsx # Loaded in parallel
|
|
264
|
-
│ ├── layout.tsx
|
|
265
|
-
│ └── page.tsx
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
```tsx
|
|
269
|
-
// app/dashboard/layout.tsx
|
|
270
|
-
export default function DashboardLayout({
|
|
271
|
-
children,
|
|
272
|
-
analytics,
|
|
273
|
-
metrics,
|
|
274
|
-
}: {
|
|
275
|
-
children: React.ReactNode;
|
|
276
|
-
analytics: React.ReactNode;
|
|
277
|
-
metrics: React.ReactNode;
|
|
278
|
-
}) {
|
|
279
|
-
return (
|
|
280
|
-
<div className="grid grid-cols-2 gap-4">
|
|
281
|
-
{children}
|
|
282
|
-
<Suspense fallback={<AnalyticsSkeleton />}>{analytics}</Suspense>
|
|
283
|
-
<Suspense fallback={<MetricsSkeleton />}>{metrics}</Suspense>
|
|
284
|
-
</div>
|
|
285
|
-
);
|
|
286
|
-
}
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
---
|
|
290
|
-
|
|
291
|
-
## Data Fetching
|
|
292
|
-
|
|
293
|
-
### Server-Side Data Fetching
|
|
294
|
-
|
|
295
|
-
```tsx
|
|
296
|
-
// Parallel data fetching
|
|
297
|
-
async function Dashboard() {
|
|
298
|
-
// Start both requests simultaneously
|
|
299
|
-
const [user, stats, notifications] = await Promise.all([
|
|
300
|
-
getUser(),
|
|
301
|
-
getStats(),
|
|
302
|
-
getNotifications(),
|
|
303
|
-
]);
|
|
304
|
-
|
|
305
|
-
return (
|
|
306
|
-
<div>
|
|
307
|
-
<UserHeader user={user} />
|
|
308
|
-
<StatsPanel stats={stats} />
|
|
309
|
-
<NotificationList notifications={notifications} />
|
|
310
|
-
</div>
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
### Streaming with Suspense
|
|
316
|
-
|
|
317
|
-
```tsx
|
|
318
|
-
import { Suspense } from 'react';
|
|
319
|
-
|
|
320
|
-
async function ProductPage({ params }: { params: { id: string } }) {
|
|
321
|
-
const product = await getProduct(params.id);
|
|
322
|
-
|
|
323
|
-
return (
|
|
324
|
-
<div>
|
|
325
|
-
{/* Immediate content */}
|
|
326
|
-
<h1>{product.name}</h1>
|
|
327
|
-
<p>{product.description}</p>
|
|
328
|
-
|
|
329
|
-
{/* Stream reviews - don't block page */}
|
|
330
|
-
<Suspense fallback={<ReviewsSkeleton />}>
|
|
331
|
-
<Reviews productId={params.id} />
|
|
332
|
-
</Suspense>
|
|
333
|
-
|
|
334
|
-
{/* Stream recommendations */}
|
|
335
|
-
<Suspense fallback={<RecommendationsSkeleton />}>
|
|
336
|
-
<Recommendations productId={params.id} />
|
|
337
|
-
</Suspense>
|
|
338
|
-
</div>
|
|
339
|
-
);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
// Slow data component
|
|
343
|
-
async function Reviews({ productId }: { productId: string }) {
|
|
344
|
-
const reviews = await getReviews(productId); // Slow query
|
|
345
|
-
return <ReviewList reviews={reviews} />;
|
|
346
|
-
}
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
### Request Memoization
|
|
350
|
-
|
|
351
|
-
```tsx
|
|
352
|
-
// Next.js automatically dedupes identical requests
|
|
353
|
-
async function Layout({ children }) {
|
|
354
|
-
const user = await getUser(); // Request 1
|
|
355
|
-
return <div>{children}</div>;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
async function Header() {
|
|
359
|
-
const user = await getUser(); // Same request - cached!
|
|
360
|
-
return <div>Hello, {user.name}</div>;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// Both components call getUser() but only one request is made
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
---
|
|
367
|
-
|
|
368
|
-
## Caching Strategies
|
|
369
|
-
|
|
370
|
-
### Fetch Cache Options
|
|
371
|
-
|
|
372
|
-
```tsx
|
|
373
|
-
// Cache indefinitely (default for static)
|
|
374
|
-
fetch('https://api.example.com/data');
|
|
375
|
-
|
|
376
|
-
// No cache - always fresh
|
|
377
|
-
fetch('https://api.example.com/data', { cache: 'no-store' });
|
|
378
|
-
|
|
379
|
-
// Revalidate after time
|
|
380
|
-
fetch('https://api.example.com/data', {
|
|
381
|
-
next: { revalidate: 3600 } // 1 hour
|
|
382
|
-
});
|
|
383
|
-
|
|
384
|
-
// Tag-based revalidation
|
|
385
|
-
fetch('https://api.example.com/products', {
|
|
386
|
-
next: { tags: ['products'] }
|
|
387
|
-
});
|
|
388
|
-
|
|
389
|
-
// Later, revalidate by tag
|
|
390
|
-
import { revalidateTag } from 'next/cache';
|
|
391
|
-
revalidateTag('products');
|
|
392
|
-
```
|
|
393
|
-
|
|
394
|
-
### Route Segment Config
|
|
395
|
-
|
|
396
|
-
```tsx
|
|
397
|
-
// app/products/page.tsx
|
|
398
|
-
|
|
399
|
-
// Revalidate every hour
|
|
400
|
-
export const revalidate = 3600;
|
|
401
|
-
|
|
402
|
-
// Or force dynamic
|
|
403
|
-
export const dynamic = 'force-dynamic';
|
|
404
|
-
|
|
405
|
-
// Generate static params at build
|
|
406
|
-
export async function generateStaticParams() {
|
|
407
|
-
const products = await getProducts();
|
|
408
|
-
return products.map(p => ({ id: p.id }));
|
|
409
|
-
}
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
### unstable_cache for Custom Caching
|
|
413
|
-
|
|
414
|
-
```tsx
|
|
415
|
-
import { unstable_cache } from 'next/cache';
|
|
416
|
-
|
|
417
|
-
const getCachedUser = unstable_cache(
|
|
418
|
-
async (userId: string) => {
|
|
419
|
-
const user = await db.users.findUnique({ where: { id: userId } });
|
|
420
|
-
return user;
|
|
421
|
-
},
|
|
422
|
-
['user-cache'],
|
|
423
|
-
{
|
|
424
|
-
revalidate: 3600, // 1 hour
|
|
425
|
-
tags: ['users'],
|
|
426
|
-
}
|
|
427
|
-
);
|
|
428
|
-
|
|
429
|
-
// Usage
|
|
430
|
-
const user = await getCachedUser(userId);
|
|
431
|
-
```
|
|
432
|
-
|
|
433
|
-
---
|
|
434
|
-
|
|
435
|
-
## Bundle Optimization
|
|
436
|
-
|
|
437
|
-
### Analyze Bundle Size
|
|
438
|
-
|
|
439
|
-
```bash
|
|
440
|
-
# Install analyzer
|
|
441
|
-
npm install @next/bundle-analyzer
|
|
442
|
-
|
|
443
|
-
# Update next.config.js
|
|
444
|
-
const withBundleAnalyzer = require('@next/bundle-analyzer')({
|
|
445
|
-
enabled: process.env.ANALYZE === 'true',
|
|
446
|
-
});
|
|
447
|
-
|
|
448
|
-
module.exports = withBundleAnalyzer({
|
|
449
|
-
// config
|
|
450
|
-
});
|
|
451
|
-
|
|
452
|
-
# Run analysis
|
|
453
|
-
ANALYZE=true npm run build
|
|
454
|
-
```
|
|
455
|
-
|
|
456
|
-
### Tree Shaking Imports
|
|
457
|
-
|
|
458
|
-
```tsx
|
|
459
|
-
// BAD - Imports entire library
|
|
460
|
-
import _ from 'lodash';
|
|
461
|
-
const result = _.debounce(fn, 300);
|
|
462
|
-
|
|
463
|
-
// GOOD - Import only what you need
|
|
464
|
-
import debounce from 'lodash/debounce';
|
|
465
|
-
const result = debounce(fn, 300);
|
|
466
|
-
|
|
467
|
-
// GOOD - Named imports (tree-shakeable)
|
|
468
|
-
import { debounce } from 'lodash-es';
|
|
469
|
-
```
|
|
470
|
-
|
|
471
|
-
### Optimize Dependencies
|
|
472
|
-
|
|
473
|
-
```js
|
|
474
|
-
// next.config.js
|
|
475
|
-
module.exports = {
|
|
476
|
-
// Transpile specific packages
|
|
477
|
-
transpilePackages: ['ui-library', 'shared-utils'],
|
|
478
|
-
|
|
479
|
-
// Optimize package imports
|
|
480
|
-
experimental: {
|
|
481
|
-
optimizePackageImports: ['lucide-react', '@heroicons/react'],
|
|
482
|
-
},
|
|
483
|
-
|
|
484
|
-
// External packages for server
|
|
485
|
-
serverExternalPackages: ['sharp', 'bcrypt'],
|
|
486
|
-
};
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
### Font Optimization
|
|
490
|
-
|
|
491
|
-
```tsx
|
|
492
|
-
// app/layout.tsx
|
|
493
|
-
import { Inter, Roboto_Mono } from 'next/font/google';
|
|
494
|
-
|
|
495
|
-
const inter = Inter({
|
|
496
|
-
subsets: ['latin'],
|
|
497
|
-
display: 'swap',
|
|
498
|
-
variable: '--font-inter',
|
|
499
|
-
});
|
|
500
|
-
|
|
501
|
-
const robotoMono = Roboto_Mono({
|
|
502
|
-
subsets: ['latin'],
|
|
503
|
-
display: 'swap',
|
|
504
|
-
variable: '--font-roboto-mono',
|
|
505
|
-
});
|
|
506
|
-
|
|
507
|
-
export default function RootLayout({ children }) {
|
|
508
|
-
return (
|
|
509
|
-
<html lang="en" className={`${inter.variable} ${robotoMono.variable}`}>
|
|
510
|
-
<body className="font-sans">{children}</body>
|
|
511
|
-
</html>
|
|
512
|
-
);
|
|
513
|
-
}
|
|
514
|
-
```
|
|
515
|
-
|
|
516
|
-
---
|
|
517
|
-
|
|
518
|
-
## Core Web Vitals
|
|
519
|
-
|
|
520
|
-
### Largest Contentful Paint (LCP)
|
|
521
|
-
|
|
522
|
-
```tsx
|
|
523
|
-
// Optimize LCP hero image
|
|
524
|
-
import Image from 'next/image';
|
|
525
|
-
|
|
526
|
-
export default function Hero() {
|
|
527
|
-
return (
|
|
528
|
-
<section className="relative h-[600px]">
|
|
529
|
-
<Image
|
|
530
|
-
src="/hero.jpg"
|
|
531
|
-
alt="Hero"
|
|
532
|
-
fill
|
|
533
|
-
priority // Preload for LCP
|
|
534
|
-
sizes="100vw"
|
|
535
|
-
className="object-cover"
|
|
536
|
-
/>
|
|
537
|
-
<div className="relative z-10">
|
|
538
|
-
<h1>Welcome</h1>
|
|
539
|
-
</div>
|
|
540
|
-
</section>
|
|
541
|
-
);
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
// Preload critical resources in layout
|
|
545
|
-
export default function RootLayout({ children }) {
|
|
546
|
-
return (
|
|
547
|
-
<html>
|
|
548
|
-
<head>
|
|
549
|
-
<link rel="preload" href="/hero.jpg" as="image" />
|
|
550
|
-
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
551
|
-
</head>
|
|
552
|
-
<body>{children}</body>
|
|
553
|
-
</html>
|
|
554
|
-
);
|
|
555
|
-
}
|
|
556
|
-
```
|
|
557
|
-
|
|
558
|
-
### Cumulative Layout Shift (CLS)
|
|
559
|
-
|
|
560
|
-
```tsx
|
|
561
|
-
// Prevent CLS with explicit dimensions
|
|
562
|
-
<Image
|
|
563
|
-
src="/product.jpg"
|
|
564
|
-
alt="Product"
|
|
565
|
-
width={400}
|
|
566
|
-
height={300}
|
|
567
|
-
/>
|
|
568
|
-
|
|
569
|
-
// Or use aspect ratio
|
|
570
|
-
<div className="aspect-video relative">
|
|
571
|
-
<Image src="/video-thumb.jpg" alt="Video" fill />
|
|
572
|
-
</div>
|
|
573
|
-
|
|
574
|
-
// Skeleton placeholders
|
|
575
|
-
function ProductCard({ product }: { product?: Product }) {
|
|
576
|
-
if (!product) {
|
|
577
|
-
return (
|
|
578
|
-
<div className="animate-pulse">
|
|
579
|
-
<div className="h-48 bg-gray-200 rounded" />
|
|
580
|
-
<div className="h-4 bg-gray-200 rounded mt-2 w-3/4" />
|
|
581
|
-
<div className="h-4 bg-gray-200 rounded mt-1 w-1/2" />
|
|
582
|
-
</div>
|
|
583
|
-
);
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
return (
|
|
587
|
-
<div>
|
|
588
|
-
<Image src={product.image} alt={product.name} width={300} height={200} />
|
|
589
|
-
<h3>{product.name}</h3>
|
|
590
|
-
<p>{product.price}</p>
|
|
591
|
-
</div>
|
|
592
|
-
);
|
|
593
|
-
}
|
|
594
|
-
```
|
|
595
|
-
|
|
596
|
-
### First Input Delay (FID) / Interaction to Next Paint (INP)
|
|
597
|
-
|
|
598
|
-
```tsx
|
|
599
|
-
// Defer non-critical JavaScript
|
|
600
|
-
import Script from 'next/script';
|
|
601
|
-
|
|
602
|
-
export default function Layout({ children }) {
|
|
603
|
-
return (
|
|
604
|
-
<html>
|
|
605
|
-
<body>
|
|
606
|
-
{children}
|
|
607
|
-
|
|
608
|
-
{/* Load analytics after page is interactive */}
|
|
609
|
-
<Script
|
|
610
|
-
src="https://analytics.example.com/script.js"
|
|
611
|
-
strategy="afterInteractive"
|
|
612
|
-
/>
|
|
613
|
-
|
|
614
|
-
{/* Load chat widget when idle */}
|
|
615
|
-
<Script
|
|
616
|
-
src="https://chat.example.com/widget.js"
|
|
617
|
-
strategy="lazyOnload"
|
|
618
|
-
/>
|
|
619
|
-
</body>
|
|
620
|
-
</html>
|
|
621
|
-
);
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
// Use web workers for heavy computation
|
|
625
|
-
// app/components/DataProcessor.tsx
|
|
626
|
-
'use client';
|
|
627
|
-
|
|
628
|
-
import { useEffect, useState } from 'react';
|
|
629
|
-
|
|
630
|
-
function DataProcessor({ data }: { data: number[] }) {
|
|
631
|
-
const [result, setResult] = useState<number | null>(null);
|
|
632
|
-
|
|
633
|
-
useEffect(() => {
|
|
634
|
-
const worker = new Worker(new URL('../workers/processor.js', import.meta.url));
|
|
635
|
-
|
|
636
|
-
worker.postMessage(data);
|
|
637
|
-
worker.onmessage = (e) => setResult(e.data);
|
|
638
|
-
|
|
639
|
-
return () => worker.terminate();
|
|
640
|
-
}, [data]);
|
|
641
|
-
|
|
642
|
-
return <div>Result: {result}</div>;
|
|
643
|
-
}
|
|
644
|
-
```
|
|
645
|
-
|
|
646
|
-
### Measuring Performance
|
|
647
|
-
|
|
648
|
-
```tsx
|
|
649
|
-
// app/components/PerformanceMonitor.tsx
|
|
650
|
-
'use client';
|
|
651
|
-
|
|
652
|
-
import { useReportWebVitals } from 'next/web-vitals';
|
|
653
|
-
|
|
654
|
-
export function PerformanceMonitor() {
|
|
655
|
-
useReportWebVitals((metric) => {
|
|
656
|
-
switch (metric.name) {
|
|
657
|
-
case 'LCP':
|
|
658
|
-
console.log('LCP:', metric.value);
|
|
659
|
-
break;
|
|
660
|
-
case 'FID':
|
|
661
|
-
console.log('FID:', metric.value);
|
|
662
|
-
break;
|
|
663
|
-
case 'CLS':
|
|
664
|
-
console.log('CLS:', metric.value);
|
|
665
|
-
break;
|
|
666
|
-
case 'TTFB':
|
|
667
|
-
console.log('TTFB:', metric.value);
|
|
668
|
-
break;
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
// Send to analytics
|
|
672
|
-
analytics.track('web-vital', {
|
|
673
|
-
name: metric.name,
|
|
674
|
-
value: metric.value,
|
|
675
|
-
id: metric.id,
|
|
676
|
-
});
|
|
677
|
-
});
|
|
678
|
-
|
|
679
|
-
return null;
|
|
680
|
-
}
|
|
681
|
-
```
|
|
682
|
-
|
|
683
|
-
---
|
|
684
|
-
|
|
685
|
-
## Quick Reference
|
|
686
|
-
|
|
687
|
-
### Performance Checklist
|
|
688
|
-
|
|
689
|
-
| Area | Optimization | Impact |
|
|
690
|
-
|------|-------------|--------|
|
|
691
|
-
| Images | Use next/image with priority for LCP | High |
|
|
692
|
-
| Fonts | Use next/font with display: swap | Medium |
|
|
693
|
-
| Code | Dynamic imports for heavy components | High |
|
|
694
|
-
| Data | Parallel fetching with Promise.all | High |
|
|
695
|
-
| Render | Server Components by default | High |
|
|
696
|
-
| Cache | Configure revalidate appropriately | Medium |
|
|
697
|
-
| Bundle | Tree-shake imports, analyze size | Medium |
|
|
698
|
-
|
|
699
|
-
### Config Template
|
|
700
|
-
|
|
701
|
-
```js
|
|
702
|
-
// next.config.js
|
|
703
|
-
/** @type {import('next').NextConfig} */
|
|
704
|
-
const nextConfig = {
|
|
705
|
-
images: {
|
|
706
|
-
remotePatterns: [{ hostname: 'cdn.example.com' }],
|
|
707
|
-
formats: ['image/avif', 'image/webp'],
|
|
708
|
-
},
|
|
709
|
-
experimental: {
|
|
710
|
-
optimizePackageImports: ['lucide-react'],
|
|
711
|
-
},
|
|
712
|
-
headers: async () => [
|
|
713
|
-
{
|
|
714
|
-
source: '/(.*)',
|
|
715
|
-
headers: [
|
|
716
|
-
{ key: 'X-Content-Type-Options', value: 'nosniff' },
|
|
717
|
-
{ key: 'X-Frame-Options', value: 'DENY' },
|
|
718
|
-
],
|
|
719
|
-
},
|
|
720
|
-
],
|
|
721
|
-
};
|
|
722
|
-
|
|
723
|
-
module.exports = nextConfig;
|
|
724
|
-
```
|
|
1
|
+
# Next.js Optimization Guide
|
|
2
|
+
|
|
3
|
+
Performance optimization techniques for Next.js 14+ applications.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Rendering Strategies](#rendering-strategies)
|
|
10
|
+
- [Image Optimization](#image-optimization)
|
|
11
|
+
- [Code Splitting](#code-splitting)
|
|
12
|
+
- [Data Fetching](#data-fetching)
|
|
13
|
+
- [Caching Strategies](#caching-strategies)
|
|
14
|
+
- [Bundle Optimization](#bundle-optimization)
|
|
15
|
+
- [Core Web Vitals](#core-web-vitals)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Rendering Strategies
|
|
20
|
+
|
|
21
|
+
### Server Components (Default)
|
|
22
|
+
|
|
23
|
+
Server Components render on the server and send HTML to the client. Use for data-heavy, non-interactive content.
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
// app/products/page.tsx - Server Component (default)
|
|
27
|
+
async function ProductsPage() {
|
|
28
|
+
// This runs on the server - no client bundle impact
|
|
29
|
+
const products = await db.products.findMany();
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<div className="grid grid-cols-3 gap-4">
|
|
33
|
+
{products.map(product => (
|
|
34
|
+
<ProductCard key={product.id} product={product} />
|
|
35
|
+
))}
|
|
36
|
+
</div>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Client Components
|
|
42
|
+
|
|
43
|
+
Use `'use client'` only when you need:
|
|
44
|
+
- Event handlers (onClick, onChange)
|
|
45
|
+
- State (useState, useReducer)
|
|
46
|
+
- Effects (useEffect)
|
|
47
|
+
- Browser APIs (window, document)
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
'use client';
|
|
51
|
+
|
|
52
|
+
import { useState } from 'react';
|
|
53
|
+
|
|
54
|
+
function AddToCartButton({ productId }: { productId: string }) {
|
|
55
|
+
const [isAdding, setIsAdding] = useState(false);
|
|
56
|
+
|
|
57
|
+
async function handleClick() {
|
|
58
|
+
setIsAdding(true);
|
|
59
|
+
await addToCart(productId);
|
|
60
|
+
setIsAdding(false);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<button onClick={handleClick} disabled={isAdding}>
|
|
65
|
+
{isAdding ? 'Adding...' : 'Add to Cart'}
|
|
66
|
+
</button>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Mixing Server and Client Components
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
// app/products/[id]/page.tsx - Server Component
|
|
75
|
+
async function ProductPage({ params }: { params: { id: string } }) {
|
|
76
|
+
const product = await getProduct(params.id);
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<div>
|
|
80
|
+
{/* Server-rendered content */}
|
|
81
|
+
<h1>{product.name}</h1>
|
|
82
|
+
<p>{product.description}</p>
|
|
83
|
+
|
|
84
|
+
{/* Client component for interactivity */}
|
|
85
|
+
<AddToCartButton productId={product.id} />
|
|
86
|
+
|
|
87
|
+
{/* Server component for reviews */}
|
|
88
|
+
<ProductReviews productId={product.id} />
|
|
89
|
+
</div>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Static vs Dynamic Rendering
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
// Force static generation at build time
|
|
98
|
+
export const dynamic = 'force-static';
|
|
99
|
+
|
|
100
|
+
// Force dynamic rendering at request time
|
|
101
|
+
export const dynamic = 'force-dynamic';
|
|
102
|
+
|
|
103
|
+
// Revalidate every 60 seconds (ISR)
|
|
104
|
+
export const revalidate = 60;
|
|
105
|
+
|
|
106
|
+
// Revalidate on-demand
|
|
107
|
+
import { revalidatePath, revalidateTag } from 'next/cache';
|
|
108
|
+
|
|
109
|
+
async function updateProduct(id: string, data: ProductData) {
|
|
110
|
+
await db.products.update({ where: { id }, data });
|
|
111
|
+
|
|
112
|
+
// Revalidate specific path
|
|
113
|
+
revalidatePath(`/products/${id}`);
|
|
114
|
+
|
|
115
|
+
// Or revalidate by tag
|
|
116
|
+
revalidateTag('products');
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Image Optimization
|
|
123
|
+
|
|
124
|
+
### Next.js Image Component
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
import Image from 'next/image';
|
|
128
|
+
|
|
129
|
+
// Basic optimized image
|
|
130
|
+
<Image
|
|
131
|
+
src="/hero.jpg"
|
|
132
|
+
alt="Hero image"
|
|
133
|
+
width={1200}
|
|
134
|
+
height={600}
|
|
135
|
+
priority // Load immediately for LCP
|
|
136
|
+
/>
|
|
137
|
+
|
|
138
|
+
// Responsive image
|
|
139
|
+
<Image
|
|
140
|
+
src="/product.jpg"
|
|
141
|
+
alt="Product"
|
|
142
|
+
fill
|
|
143
|
+
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
|
|
144
|
+
className="object-cover"
|
|
145
|
+
/>
|
|
146
|
+
|
|
147
|
+
// With placeholder blur
|
|
148
|
+
import productImage from '@/public/product.jpg';
|
|
149
|
+
|
|
150
|
+
<Image
|
|
151
|
+
src={productImage}
|
|
152
|
+
alt="Product"
|
|
153
|
+
placeholder="blur" // Uses imported image data
|
|
154
|
+
/>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Remote Images Configuration
|
|
158
|
+
|
|
159
|
+
```js
|
|
160
|
+
// next.config.js
|
|
161
|
+
module.exports = {
|
|
162
|
+
images: {
|
|
163
|
+
remotePatterns: [
|
|
164
|
+
{
|
|
165
|
+
protocol: 'https',
|
|
166
|
+
hostname: 'cdn.example.com',
|
|
167
|
+
pathname: '/images/**',
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
protocol: 'https',
|
|
171
|
+
hostname: '*.cloudinary.com',
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
// Image formats (webp is default)
|
|
175
|
+
formats: ['image/avif', 'image/webp'],
|
|
176
|
+
// Device sizes for srcset
|
|
177
|
+
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
|
|
178
|
+
// Image sizes for srcset
|
|
179
|
+
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Lazy Loading Patterns
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
// Images below the fold - lazy load (default)
|
|
188
|
+
<Image
|
|
189
|
+
src="/gallery/photo1.jpg"
|
|
190
|
+
alt="Gallery photo"
|
|
191
|
+
width={400}
|
|
192
|
+
height={300}
|
|
193
|
+
loading="lazy" // Default behavior
|
|
194
|
+
/>
|
|
195
|
+
|
|
196
|
+
// Above the fold - load immediately
|
|
197
|
+
<Image
|
|
198
|
+
src="/hero.jpg"
|
|
199
|
+
alt="Hero"
|
|
200
|
+
width={1200}
|
|
201
|
+
height={600}
|
|
202
|
+
priority
|
|
203
|
+
loading="eager"
|
|
204
|
+
/>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Code Splitting
|
|
210
|
+
|
|
211
|
+
### Dynamic Imports
|
|
212
|
+
|
|
213
|
+
```tsx
|
|
214
|
+
import dynamic from 'next/dynamic';
|
|
215
|
+
|
|
216
|
+
// Basic dynamic import
|
|
217
|
+
const HeavyChart = dynamic(() => import('@/components/HeavyChart'), {
|
|
218
|
+
loading: () => <ChartSkeleton />,
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// Disable SSR for client-only components
|
|
222
|
+
const MapComponent = dynamic(() => import('@/components/Map'), {
|
|
223
|
+
ssr: false,
|
|
224
|
+
loading: () => <div className="h-[400px] bg-gray-100" />,
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// Named exports
|
|
228
|
+
const Modal = dynamic(() =>
|
|
229
|
+
import('@/components/ui').then(mod => mod.Modal)
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
// With suspense
|
|
233
|
+
const DashboardCharts = dynamic(() => import('@/components/DashboardCharts'), {
|
|
234
|
+
loading: () => <Suspense fallback={<ChartsSkeleton />} />,
|
|
235
|
+
});
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Route-Based Splitting
|
|
239
|
+
|
|
240
|
+
```tsx
|
|
241
|
+
// app/dashboard/analytics/page.tsx
|
|
242
|
+
// This page only loads when /dashboard/analytics is visited
|
|
243
|
+
import { Suspense } from 'react';
|
|
244
|
+
import AnalyticsCharts from './AnalyticsCharts';
|
|
245
|
+
|
|
246
|
+
export default function AnalyticsPage() {
|
|
247
|
+
return (
|
|
248
|
+
<Suspense fallback={<AnalyticsSkeleton />}>
|
|
249
|
+
<AnalyticsCharts />
|
|
250
|
+
</Suspense>
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Parallel Routes for Code Splitting
|
|
256
|
+
|
|
257
|
+
```
|
|
258
|
+
app/
|
|
259
|
+
├── dashboard/
|
|
260
|
+
│ ├── @analytics/
|
|
261
|
+
│ │ └── page.tsx # Loaded in parallel
|
|
262
|
+
│ ├── @metrics/
|
|
263
|
+
│ │ └── page.tsx # Loaded in parallel
|
|
264
|
+
│ ├── layout.tsx
|
|
265
|
+
│ └── page.tsx
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
```tsx
|
|
269
|
+
// app/dashboard/layout.tsx
|
|
270
|
+
export default function DashboardLayout({
|
|
271
|
+
children,
|
|
272
|
+
analytics,
|
|
273
|
+
metrics,
|
|
274
|
+
}: {
|
|
275
|
+
children: React.ReactNode;
|
|
276
|
+
analytics: React.ReactNode;
|
|
277
|
+
metrics: React.ReactNode;
|
|
278
|
+
}) {
|
|
279
|
+
return (
|
|
280
|
+
<div className="grid grid-cols-2 gap-4">
|
|
281
|
+
{children}
|
|
282
|
+
<Suspense fallback={<AnalyticsSkeleton />}>{analytics}</Suspense>
|
|
283
|
+
<Suspense fallback={<MetricsSkeleton />}>{metrics}</Suspense>
|
|
284
|
+
</div>
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## Data Fetching
|
|
292
|
+
|
|
293
|
+
### Server-Side Data Fetching
|
|
294
|
+
|
|
295
|
+
```tsx
|
|
296
|
+
// Parallel data fetching
|
|
297
|
+
async function Dashboard() {
|
|
298
|
+
// Start both requests simultaneously
|
|
299
|
+
const [user, stats, notifications] = await Promise.all([
|
|
300
|
+
getUser(),
|
|
301
|
+
getStats(),
|
|
302
|
+
getNotifications(),
|
|
303
|
+
]);
|
|
304
|
+
|
|
305
|
+
return (
|
|
306
|
+
<div>
|
|
307
|
+
<UserHeader user={user} />
|
|
308
|
+
<StatsPanel stats={stats} />
|
|
309
|
+
<NotificationList notifications={notifications} />
|
|
310
|
+
</div>
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Streaming with Suspense
|
|
316
|
+
|
|
317
|
+
```tsx
|
|
318
|
+
import { Suspense } from 'react';
|
|
319
|
+
|
|
320
|
+
async function ProductPage({ params }: { params: { id: string } }) {
|
|
321
|
+
const product = await getProduct(params.id);
|
|
322
|
+
|
|
323
|
+
return (
|
|
324
|
+
<div>
|
|
325
|
+
{/* Immediate content */}
|
|
326
|
+
<h1>{product.name}</h1>
|
|
327
|
+
<p>{product.description}</p>
|
|
328
|
+
|
|
329
|
+
{/* Stream reviews - don't block page */}
|
|
330
|
+
<Suspense fallback={<ReviewsSkeleton />}>
|
|
331
|
+
<Reviews productId={params.id} />
|
|
332
|
+
</Suspense>
|
|
333
|
+
|
|
334
|
+
{/* Stream recommendations */}
|
|
335
|
+
<Suspense fallback={<RecommendationsSkeleton />}>
|
|
336
|
+
<Recommendations productId={params.id} />
|
|
337
|
+
</Suspense>
|
|
338
|
+
</div>
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Slow data component
|
|
343
|
+
async function Reviews({ productId }: { productId: string }) {
|
|
344
|
+
const reviews = await getReviews(productId); // Slow query
|
|
345
|
+
return <ReviewList reviews={reviews} />;
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### Request Memoization
|
|
350
|
+
|
|
351
|
+
```tsx
|
|
352
|
+
// Next.js automatically dedupes identical requests
|
|
353
|
+
async function Layout({ children }) {
|
|
354
|
+
const user = await getUser(); // Request 1
|
|
355
|
+
return <div>{children}</div>;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
async function Header() {
|
|
359
|
+
const user = await getUser(); // Same request - cached!
|
|
360
|
+
return <div>Hello, {user.name}</div>;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Both components call getUser() but only one request is made
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## Caching Strategies
|
|
369
|
+
|
|
370
|
+
### Fetch Cache Options
|
|
371
|
+
|
|
372
|
+
```tsx
|
|
373
|
+
// Cache indefinitely (default for static)
|
|
374
|
+
fetch('https://api.example.com/data');
|
|
375
|
+
|
|
376
|
+
// No cache - always fresh
|
|
377
|
+
fetch('https://api.example.com/data', { cache: 'no-store' });
|
|
378
|
+
|
|
379
|
+
// Revalidate after time
|
|
380
|
+
fetch('https://api.example.com/data', {
|
|
381
|
+
next: { revalidate: 3600 } // 1 hour
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
// Tag-based revalidation
|
|
385
|
+
fetch('https://api.example.com/products', {
|
|
386
|
+
next: { tags: ['products'] }
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
// Later, revalidate by tag
|
|
390
|
+
import { revalidateTag } from 'next/cache';
|
|
391
|
+
revalidateTag('products');
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### Route Segment Config
|
|
395
|
+
|
|
396
|
+
```tsx
|
|
397
|
+
// app/products/page.tsx
|
|
398
|
+
|
|
399
|
+
// Revalidate every hour
|
|
400
|
+
export const revalidate = 3600;
|
|
401
|
+
|
|
402
|
+
// Or force dynamic
|
|
403
|
+
export const dynamic = 'force-dynamic';
|
|
404
|
+
|
|
405
|
+
// Generate static params at build
|
|
406
|
+
export async function generateStaticParams() {
|
|
407
|
+
const products = await getProducts();
|
|
408
|
+
return products.map(p => ({ id: p.id }));
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### unstable_cache for Custom Caching
|
|
413
|
+
|
|
414
|
+
```tsx
|
|
415
|
+
import { unstable_cache } from 'next/cache';
|
|
416
|
+
|
|
417
|
+
const getCachedUser = unstable_cache(
|
|
418
|
+
async (userId: string) => {
|
|
419
|
+
const user = await db.users.findUnique({ where: { id: userId } });
|
|
420
|
+
return user;
|
|
421
|
+
},
|
|
422
|
+
['user-cache'],
|
|
423
|
+
{
|
|
424
|
+
revalidate: 3600, // 1 hour
|
|
425
|
+
tags: ['users'],
|
|
426
|
+
}
|
|
427
|
+
);
|
|
428
|
+
|
|
429
|
+
// Usage
|
|
430
|
+
const user = await getCachedUser(userId);
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
## Bundle Optimization
|
|
436
|
+
|
|
437
|
+
### Analyze Bundle Size
|
|
438
|
+
|
|
439
|
+
```bash
|
|
440
|
+
# Install analyzer
|
|
441
|
+
npm install @next/bundle-analyzer
|
|
442
|
+
|
|
443
|
+
# Update next.config.js
|
|
444
|
+
const withBundleAnalyzer = require('@next/bundle-analyzer')({
|
|
445
|
+
enabled: process.env.ANALYZE === 'true',
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
module.exports = withBundleAnalyzer({
|
|
449
|
+
// config
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
# Run analysis
|
|
453
|
+
ANALYZE=true npm run build
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
### Tree Shaking Imports
|
|
457
|
+
|
|
458
|
+
```tsx
|
|
459
|
+
// BAD - Imports entire library
|
|
460
|
+
import _ from 'lodash';
|
|
461
|
+
const result = _.debounce(fn, 300);
|
|
462
|
+
|
|
463
|
+
// GOOD - Import only what you need
|
|
464
|
+
import debounce from 'lodash/debounce';
|
|
465
|
+
const result = debounce(fn, 300);
|
|
466
|
+
|
|
467
|
+
// GOOD - Named imports (tree-shakeable)
|
|
468
|
+
import { debounce } from 'lodash-es';
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### Optimize Dependencies
|
|
472
|
+
|
|
473
|
+
```js
|
|
474
|
+
// next.config.js
|
|
475
|
+
module.exports = {
|
|
476
|
+
// Transpile specific packages
|
|
477
|
+
transpilePackages: ['ui-library', 'shared-utils'],
|
|
478
|
+
|
|
479
|
+
// Optimize package imports
|
|
480
|
+
experimental: {
|
|
481
|
+
optimizePackageImports: ['lucide-react', '@heroicons/react'],
|
|
482
|
+
},
|
|
483
|
+
|
|
484
|
+
// External packages for server
|
|
485
|
+
serverExternalPackages: ['sharp', 'bcrypt'],
|
|
486
|
+
};
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
### Font Optimization
|
|
490
|
+
|
|
491
|
+
```tsx
|
|
492
|
+
// app/layout.tsx
|
|
493
|
+
import { Inter, Roboto_Mono } from 'next/font/google';
|
|
494
|
+
|
|
495
|
+
const inter = Inter({
|
|
496
|
+
subsets: ['latin'],
|
|
497
|
+
display: 'swap',
|
|
498
|
+
variable: '--font-inter',
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
const robotoMono = Roboto_Mono({
|
|
502
|
+
subsets: ['latin'],
|
|
503
|
+
display: 'swap',
|
|
504
|
+
variable: '--font-roboto-mono',
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
export default function RootLayout({ children }) {
|
|
508
|
+
return (
|
|
509
|
+
<html lang="en" className={`${inter.variable} ${robotoMono.variable}`}>
|
|
510
|
+
<body className="font-sans">{children}</body>
|
|
511
|
+
</html>
|
|
512
|
+
);
|
|
513
|
+
}
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
---
|
|
517
|
+
|
|
518
|
+
## Core Web Vitals
|
|
519
|
+
|
|
520
|
+
### Largest Contentful Paint (LCP)
|
|
521
|
+
|
|
522
|
+
```tsx
|
|
523
|
+
// Optimize LCP hero image
|
|
524
|
+
import Image from 'next/image';
|
|
525
|
+
|
|
526
|
+
export default function Hero() {
|
|
527
|
+
return (
|
|
528
|
+
<section className="relative h-[600px]">
|
|
529
|
+
<Image
|
|
530
|
+
src="/hero.jpg"
|
|
531
|
+
alt="Hero"
|
|
532
|
+
fill
|
|
533
|
+
priority // Preload for LCP
|
|
534
|
+
sizes="100vw"
|
|
535
|
+
className="object-cover"
|
|
536
|
+
/>
|
|
537
|
+
<div className="relative z-10">
|
|
538
|
+
<h1>Welcome</h1>
|
|
539
|
+
</div>
|
|
540
|
+
</section>
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// Preload critical resources in layout
|
|
545
|
+
export default function RootLayout({ children }) {
|
|
546
|
+
return (
|
|
547
|
+
<html>
|
|
548
|
+
<head>
|
|
549
|
+
<link rel="preload" href="/hero.jpg" as="image" />
|
|
550
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
551
|
+
</head>
|
|
552
|
+
<body>{children}</body>
|
|
553
|
+
</html>
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
### Cumulative Layout Shift (CLS)
|
|
559
|
+
|
|
560
|
+
```tsx
|
|
561
|
+
// Prevent CLS with explicit dimensions
|
|
562
|
+
<Image
|
|
563
|
+
src="/product.jpg"
|
|
564
|
+
alt="Product"
|
|
565
|
+
width={400}
|
|
566
|
+
height={300}
|
|
567
|
+
/>
|
|
568
|
+
|
|
569
|
+
// Or use aspect ratio
|
|
570
|
+
<div className="aspect-video relative">
|
|
571
|
+
<Image src="/video-thumb.jpg" alt="Video" fill />
|
|
572
|
+
</div>
|
|
573
|
+
|
|
574
|
+
// Skeleton placeholders
|
|
575
|
+
function ProductCard({ product }: { product?: Product }) {
|
|
576
|
+
if (!product) {
|
|
577
|
+
return (
|
|
578
|
+
<div className="animate-pulse">
|
|
579
|
+
<div className="h-48 bg-gray-200 rounded" />
|
|
580
|
+
<div className="h-4 bg-gray-200 rounded mt-2 w-3/4" />
|
|
581
|
+
<div className="h-4 bg-gray-200 rounded mt-1 w-1/2" />
|
|
582
|
+
</div>
|
|
583
|
+
);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
return (
|
|
587
|
+
<div>
|
|
588
|
+
<Image src={product.image} alt={product.name} width={300} height={200} />
|
|
589
|
+
<h3>{product.name}</h3>
|
|
590
|
+
<p>{product.price}</p>
|
|
591
|
+
</div>
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
### First Input Delay (FID) / Interaction to Next Paint (INP)
|
|
597
|
+
|
|
598
|
+
```tsx
|
|
599
|
+
// Defer non-critical JavaScript
|
|
600
|
+
import Script from 'next/script';
|
|
601
|
+
|
|
602
|
+
export default function Layout({ children }) {
|
|
603
|
+
return (
|
|
604
|
+
<html>
|
|
605
|
+
<body>
|
|
606
|
+
{children}
|
|
607
|
+
|
|
608
|
+
{/* Load analytics after page is interactive */}
|
|
609
|
+
<Script
|
|
610
|
+
src="https://analytics.example.com/script.js"
|
|
611
|
+
strategy="afterInteractive"
|
|
612
|
+
/>
|
|
613
|
+
|
|
614
|
+
{/* Load chat widget when idle */}
|
|
615
|
+
<Script
|
|
616
|
+
src="https://chat.example.com/widget.js"
|
|
617
|
+
strategy="lazyOnload"
|
|
618
|
+
/>
|
|
619
|
+
</body>
|
|
620
|
+
</html>
|
|
621
|
+
);
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
// Use web workers for heavy computation
|
|
625
|
+
// app/components/DataProcessor.tsx
|
|
626
|
+
'use client';
|
|
627
|
+
|
|
628
|
+
import { useEffect, useState } from 'react';
|
|
629
|
+
|
|
630
|
+
function DataProcessor({ data }: { data: number[] }) {
|
|
631
|
+
const [result, setResult] = useState<number | null>(null);
|
|
632
|
+
|
|
633
|
+
useEffect(() => {
|
|
634
|
+
const worker = new Worker(new URL('../workers/processor.js', import.meta.url));
|
|
635
|
+
|
|
636
|
+
worker.postMessage(data);
|
|
637
|
+
worker.onmessage = (e) => setResult(e.data);
|
|
638
|
+
|
|
639
|
+
return () => worker.terminate();
|
|
640
|
+
}, [data]);
|
|
641
|
+
|
|
642
|
+
return <div>Result: {result}</div>;
|
|
643
|
+
}
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
### Measuring Performance
|
|
647
|
+
|
|
648
|
+
```tsx
|
|
649
|
+
// app/components/PerformanceMonitor.tsx
|
|
650
|
+
'use client';
|
|
651
|
+
|
|
652
|
+
import { useReportWebVitals } from 'next/web-vitals';
|
|
653
|
+
|
|
654
|
+
export function PerformanceMonitor() {
|
|
655
|
+
useReportWebVitals((metric) => {
|
|
656
|
+
switch (metric.name) {
|
|
657
|
+
case 'LCP':
|
|
658
|
+
console.log('LCP:', metric.value);
|
|
659
|
+
break;
|
|
660
|
+
case 'FID':
|
|
661
|
+
console.log('FID:', metric.value);
|
|
662
|
+
break;
|
|
663
|
+
case 'CLS':
|
|
664
|
+
console.log('CLS:', metric.value);
|
|
665
|
+
break;
|
|
666
|
+
case 'TTFB':
|
|
667
|
+
console.log('TTFB:', metric.value);
|
|
668
|
+
break;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
// Send to analytics
|
|
672
|
+
analytics.track('web-vital', {
|
|
673
|
+
name: metric.name,
|
|
674
|
+
value: metric.value,
|
|
675
|
+
id: metric.id,
|
|
676
|
+
});
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
return null;
|
|
680
|
+
}
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
---
|
|
684
|
+
|
|
685
|
+
## Quick Reference
|
|
686
|
+
|
|
687
|
+
### Performance Checklist
|
|
688
|
+
|
|
689
|
+
| Area | Optimization | Impact |
|
|
690
|
+
|------|-------------|--------|
|
|
691
|
+
| Images | Use next/image with priority for LCP | High |
|
|
692
|
+
| Fonts | Use next/font with display: swap | Medium |
|
|
693
|
+
| Code | Dynamic imports for heavy components | High |
|
|
694
|
+
| Data | Parallel fetching with Promise.all | High |
|
|
695
|
+
| Render | Server Components by default | High |
|
|
696
|
+
| Cache | Configure revalidate appropriately | Medium |
|
|
697
|
+
| Bundle | Tree-shake imports, analyze size | Medium |
|
|
698
|
+
|
|
699
|
+
### Config Template
|
|
700
|
+
|
|
701
|
+
```js
|
|
702
|
+
// next.config.js
|
|
703
|
+
/** @type {import('next').NextConfig} */
|
|
704
|
+
const nextConfig = {
|
|
705
|
+
images: {
|
|
706
|
+
remotePatterns: [{ hostname: 'cdn.example.com' }],
|
|
707
|
+
formats: ['image/avif', 'image/webp'],
|
|
708
|
+
},
|
|
709
|
+
experimental: {
|
|
710
|
+
optimizePackageImports: ['lucide-react'],
|
|
711
|
+
},
|
|
712
|
+
headers: async () => [
|
|
713
|
+
{
|
|
714
|
+
source: '/(.*)',
|
|
715
|
+
headers: [
|
|
716
|
+
{ key: 'X-Content-Type-Options', value: 'nosniff' },
|
|
717
|
+
{ key: 'X-Frame-Options', value: 'DENY' },
|
|
718
|
+
],
|
|
719
|
+
},
|
|
720
|
+
],
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
module.exports = nextConfig;
|
|
724
|
+
```
|