# 网站全面优化实施计划 > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. **Goal:** 全面优化睿新致远网站,提升导航一致性、测试覆盖率、错误处理、性能、移动端体验和SEO。 **Architecture:** 采用渐进式优化策略,按优先级分阶段实施,每个阶段独立可验证和回滚。 **Tech Stack:** Next.js 16.1.6, TypeScript, Framer Motion, Playwright, Tailwind CSS --- ## 阶段一:高优先级修复(1-2天) ### Task 1.1: 修复导航一致性问题 **Files:** - Create: `src/components/layout/breadcrumb.tsx` - Modify: `src/components/layout/header.tsx:1-150` - Modify: `src/app/(marketing)/about/page.tsx:1-15` - Modify: `src/app/(marketing)/cases/page.tsx:1-20` - Modify: `src/app/(marketing)/services/page.tsx:1-20` - Modify: `src/app/(marketing)/products/page.tsx:1-20` - Modify: `src/app/(marketing)/solutions/page.tsx:1-20` - Modify: `src/app/(marketing)/contact/page.tsx:1-20` - Modify: `src/app/(marketing)/news/page.tsx:1-20` **Step 1: 创建面包屑导航组件** ```typescript // src/components/layout/breadcrumb.tsx 'use client'; import Link from 'next/link'; import { ChevronRight, Home } from 'lucide-react'; interface BreadcrumbItem { label: string; href: string; } interface BreadcrumbProps { items: BreadcrumbItem[]; } export function Breadcrumb({ items }: BreadcrumbProps) { return ( ); } ``` **Step 2: 运行测试验证组件创建** Run: `npm run build` Expected: BUILD SUCCESS **Step 3: 在各个页面集成面包屑导航** ```typescript // 示例:src/app/(marketing)/about/page.tsx import { Breadcrumb } from '@/components/layout/breadcrumb'; export default function AboutPage() { return (
{/* 其他内容 */}
); } ``` **Step 4: 更新 Header 组件以支持统一导航** ```typescript // src/components/layout/header.tsx // 修改导航逻辑,使其在首页使用锚点,在详情页使用路由 const getNavigationHref = (item: typeof NAVIGATION[number], isHomePage: boolean) => { return isHomePage ? item.href : `/${item.id}`; }; ``` **Step 5: 运行测试验证导航一致性** Run: `npm run lint` Expected: No linting errors **Step 6: 提交代码** ```bash git add src/components/layout/breadcrumb.tsx src/components/layout/header.tsx src/app/ git commit -m "feat: implement consistent navigation with breadcrumbs" ``` --- ### Task 1.2: 补充关键页面的E2E测试 **Files:** - Create: `e2e/src/pages/AboutPage.ts` - Create: `e2e/src/pages/CasesPage.ts` - Create: `e2e/src/pages/ServicesPage.ts` - Create: `e2e/src/pages/ProductsPage.ts` - Create: `e2e/src/pages/SolutionsPage.ts` - Create: `e2e/src/pages/NewsPage.ts` - Create: `e2e/src/tests/smoke/about-page.smoke.spec.ts` - Create: `e2e/src/tests/smoke/cases-page.smoke.spec.ts` - Create: `e2e/src/tests/smoke/services-page.smoke.spec.ts` - Create: `e2e/src/tests/smoke/products-page.smoke.spec.ts` - Create: `e2e/src/tests/smoke/solutions-page.smoke.spec.ts` - Create: `e2e/src/tests/smoke/news-page.smoke.spec.ts` **Step 1: 创建 AboutPage Page Object** ```typescript // e2e/src/pages/AboutPage.ts import { Page, Locator, expect } from '@playwright/test'; export class AboutPage { readonly page: Page; readonly breadcrumb: Locator; readonly pageHeader: Locator; constructor(page: Page) { this.page = page; this.breadcrumb = page.locator('nav'); this.pageHeader = page.locator('h1'); } async goto() { await this.page.goto('/about'); await this.page.waitForLoadState('networkidle'); } async waitForPageLoad() { await this.page.waitForLoadState('networkidle'); await expect(this.pageHeader).toBeVisible(); } async getBreadcrumbItems() { return await this.breadcrumb.allTextContents(); } } ``` **Step 2: 创建关于页面冒烟测试** ```typescript // e2e/src/tests/smoke/about-page.smoke.spec.ts import { test, expect } from '../../fixtures/base.fixture'; test.describe('关于页面冒烟测试 @smoke', () => { test.beforeEach(async ({ aboutPage }) => { await aboutPage.goto(); await aboutPage.waitForPageLoad(); }); test('应该成功加载关于页面', async ({ aboutPage }) => { await expect(aboutPage.page).toHaveURL(/\/about/); await expect(aboutPage.pageHeader).toBeVisible(); }); test('应该显示面包屑导航', async ({ aboutPage }) => { const items = await aboutPage.getBreadcrumbItems(); expect(items.length).toBeGreaterThan(0); }); }); ``` **Step 3: 运行测试验证失败** Run: `cd e2e && npm test --grep "关于页面冒烟测试"` Expected: FAIL with "aboutPage is not defined" **Step 4: 更新 fixtures 以包含新页面** ```typescript // e2e/src/fixtures/base.fixture.ts import { test as base } from '@playwright/test'; import { AboutPage } from '../pages/AboutPage'; import { CasesPage } from '../pages/CasesPage'; import { ServicesPage } from '../pages/ServicesPage'; import { ProductsPage } from '../pages/ProductsPage'; import { SolutionsPage } from '../pages/SolutionsPage'; import { NewsPage } from '../pages/NewsPage'; export const test = base.extend<{ aboutPage: AboutPage; casesPage: CasesPage; servicesPage: ServicesPage; productsPage: ProductsPage; solutionsPage: SolutionsPage; newsPage: NewsPage; }>({ aboutPage: async ({ page }, use) => { const aboutPage = new AboutPage(page); await use(aboutPage); }, casesPage: async ({ page }, use) => { const casesPage = new CasesPage(page); await use(casesPage); }, servicesPage: async ({ page }, use) => { const servicesPage = new ServicesPage(page); await use(servicesPage); }, productsPage: async ({ page }, use) => { const productsPage = new ProductsPage(page); await use(productsPage); }, solutionsPage: async ({ page }, use) => { const solutionsPage = new SolutionsPage(page); await use(solutionsPage); }, newsPage: async ({ page }, use) => { const newsPage = new NewsPage(page); await use(newsPage); }, }); ``` **Step 5: 运行测试验证通过** Run: `cd e2e && npm test --grep "关于页面冒烟测试"` Expected: PASS **Step 6: 为其他页面创建类似的测试** 重复步骤 1-5,为 CasesPage、ServicesPage、ProductsPage、SolutionsPage、NewsPage 创建 Page Objects 和测试。 **Step 7: 提交代码** ```bash git add e2e/src/pages/ e2e/src/tests/smoke/ e2e/src/fixtures/base.fixture.ts git commit -m "test: add smoke tests for all major pages" ``` --- ### Task 1.3: 完善错误处理 **Files:** - Create: `src/app/not-found.tsx` - Create: `src/app/error.tsx` - Create: `src/components/ui/error-boundary.tsx` - Modify: `src/app/layout.tsx:1-50` **Step 1: 创建 404 页面** ```typescript // src/app/not-found.tsx import Link from 'next/link'; import { Button } from '@/components/ui/button'; import { Home, ArrowRight } from 'lucide-react'; export default function NotFound() { return (

404

页面未找到

抱歉,您访问的页面不存在。

); } ``` **Step 2: 创建全局错误页面** ```typescript // src/app/error.tsx 'use client'; import { useEffect } from 'react'; import { Button } from '@/components/ui/button'; import Link from 'next/link'; import { AlertCircle, RefreshCw } from 'lucide-react'; export default function Error({ error, reset, }: { error: Error & { digest?: string }; reset: () => void; }) { useEffect(() => { console.error(error); }, [error]); return (

出错了

抱歉,页面加载时发生了错误。请刷新页面或联系我们的技术支持。

); } ``` **Step 3: 创建错误边界组件** ```typescript // src/components/ui/error-boundary.tsx 'use client'; import { Component, ReactNode } from 'react'; interface ErrorBoundaryProps { children: ReactNode; fallback?: ReactNode; } interface ErrorBoundaryState { hasError: boolean; } export class ErrorBoundary extends Component< ErrorBoundaryProps, ErrorBoundaryState > { constructor(props: ErrorBoundaryProps) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(_: Error): ErrorBoundaryState { return { hasError: true }; } componentDidCatch(error: Error, errorInfo: any) { console.error('ErrorBoundary caught an error:', error, errorInfo); } render() { if (this.state.hasError) { return this.props.fallback || (

组件加载失败

抱歉,页面部分内容加载失败。请刷新页面重试。

); } return this.props.children; } } ``` **Step 4: 在根布局中集成错误边界** ```typescript // src/app/layout.tsx import { ErrorBoundary } from '@/components/ui/error-boundary'; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` **Step 5: 运行测试验证错误处理** Run: `npm run build` Expected: BUILD SUCCESS **Step 6: 添加错误处理的E2E测试** ```typescript // e2e/src/tests/smoke/error-handling.smoke.spec.ts import { test, expect } from '@playwright/test'; test.describe('错误处理冒烟测试 @smoke', () => { test('应该显示404页面', async ({ page }) => { await page.goto('/non-existent-page'); await expect(page.locator('h1')).toContainText('404'); await expect(page.locator('h2')).toContainText('页面未找到'); }); test('404页面应该有返回首页按钮', async ({ page }) => { await page.goto('/non-existent-page'); const homeButton = page.getByRole('link', { name: /返回首页/ }); await expect(homeButton).toBeVisible(); await homeButton.click(); await expect(page).toHaveURL('/'); }); }); ``` **Step 7: 提交代码** ```bash git add src/app/not-found.tsx src/app/error.tsx src/components/ui/error-boundary.tsx src/app/layout.tsx e2e/src/tests/smoke/error-handling.smoke.spec.ts git commit -m "feat: implement comprehensive error handling with 404 and error pages" ``` --- ## 阶段二:中优先级优化(1周) ### Task 2.1: 优化加载性能 **Files:** - Create: `src/components/ui/optimized-image.tsx` - Modify: `src/components/sections/hero-section.tsx:1-100` - Modify: `src/components/sections/services-section.tsx:1-100` - Modify: `src/components/sections/products-section.tsx:1-100` - Modify: `src/components/sections/cases-section.tsx:1-100` - Modify: `src/components/sections/news-section.tsx:1-100` - Modify: `next.config.ts:1-50` **Step 1: 创建优化的图片组件** ```typescript // src/components/ui/optimized-image.tsx 'use client'; import Image from 'next/image'; import { useState } from 'react'; interface OptimizedImageProps { src: string; alt: string; width?: number; height?: number; className?: string; priority?: boolean; } export function OptimizedImage({ src, alt, width = 800, height = 600, className, priority = false, }: OptimizedImageProps) { const [isLoading, setIsLoading] = useState(true); return (
{isLoading && (
)} {alt} setIsLoading(false)} sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw" />
); } ``` **Step 2: 更新 Next.js 配置以支持图片优化** ```typescript // next.config.ts const nextConfig = { images: { remotePatterns: [ { protocol: 'https', hostname: '**', }, ], formats: ['image/avif', 'image/webp'], deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840], imageSizes: [16, 32, 48, 64, 96, 128, 256, 384], }, // 其他配置... }; ``` **Step 3: 在各个 section 中使用优化的图片组件** ```typescript // 示例:src/components/sections/hero-section.tsx import { OptimizedImage } from '@/components/ui/optimized-image'; // 替换所有 标签为 ``` **Step 4: 实现代码分割和懒加载** ```typescript // src/app/(marketing)/page.tsx import dynamic from 'next/dynamic'; // 使用动态导入和懒加载 const HeroSection = dynamic( () => import('@/components/sections/hero-section').then(mod => ({ default: mod.HeroSection })), { loading: () => , ssr: true } ); const ServicesSection = dynamic( () => import('@/components/sections/services-section').then(mod => ({ default: mod.ServicesSection })), { loading: () => , ssr: false } ); ``` **Step 5: 添加性能测试** ```typescript // e2e/src/tests/performance/image-loading.spec.ts import { test, expect } from '@playwright/test'; test.describe('图片加载性能测试 @performance', () => { test('应该使用优化的图片格式', async ({ page }) => { await page.goto('/'); const images = await page.locator('img').all(); for (const image of images) { const src = await image.getAttribute('src'); if (src) { expect(src).toMatch(/\.(avif|webp|jpg|png)$/); } } }); test('应该有合理的图片尺寸', async ({ page }) => { await page.goto('/'); const images = await page.locator('img').all(); for (const image of images) { const width = await image.getAttribute('width'); const height = await image.getAttribute('height'); expect(width).toBeTruthy(); expect(height).toBeTruthy(); } }); }); ``` **Step 6: 运行性能测试** Run: `cd e2e && npm test --grep "图片加载性能测试"` Expected: PASS **Step 7: 提交代码** ```bash git add src/components/ui/optimized-image.tsx next.config.ts src/components/sections/ e2e/src/tests/performance/ git commit -m "perf: implement image optimization and code splitting" ``` --- ### Task 2.2: 改进移动端体验 **Files:** - Modify: `src/components/layout/mobile-menu.tsx:1-200` - Modify: `src/components/layout/mobile-tab-bar.tsx:1-100` - Create: `e2e/src/tests/responsive/mobile-ux.spec.ts` **Step 1: 优化移动端菜单交互** ```typescript // src/components/layout/mobile-menu.tsx 'use client'; import { useState, useEffect, useRef } from 'react'; import { X } from 'lucide-react'; export function MobileMenu({ isOpen, onClose, children }: any) { const menuRef = useRef(null); useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (menuRef.current && !menuRef.current.contains(event.target as Node)) { onClose(); } }; if (isOpen) { document.addEventListener('mousedown', handleClickOutside); document.body.style.overflow = 'hidden'; } else { document.body.style.overflow = 'unset'; } return () => { document.removeEventListener('mousedown', handleClickOutside); document.body.style.overflow = 'unset'; }; }, [isOpen, onClose]); if (!isOpen) return null; return (
{children}
); } ``` **Step 2: 添加移动端触摸优化** ```typescript // src/components/ui/touch-button.tsx 'use client'; import { Button } from './button'; import { forwardRef } from 'react'; export const TouchButton = forwardRef< HTMLButtonElement, React.ComponentProps >((props, ref) => { return (