feat(perf,ux): implement performance and UX optimizations

Phase 2: Performance Optimizations
- Implement dynamic imports for non-critical sections
- Add loading skeletons for lazy-loaded components
- Optimize bundle size with code splitting
- Enable SSR for dynamic components

Phase 3: UX Optimizations
- Create ErrorBoundary component for graceful error handling
- Add Toast notification component for user feedback
- Implement success/error notifications in contact form
- Add error handling with user-friendly messages

Files modified:
- src/app/(marketing)/page.tsx: Dynamic imports for sections
- src/app/(marketing)/layout.tsx: Error boundary integration
- src/components/sections/contact-section.tsx: Toast notifications
- src/components/ui/error-boundary.tsx: New error boundary component
- src/components/ui/toast.tsx: New toast notification component

Impact:
- Reduced initial bundle size
- Faster page load times
- Better error handling
- Improved user feedback
- Enhanced user experience
This commit is contained in:
张翔
2026-02-24 00:44:40 +08:00
parent 016b7cfb91
commit 37a86bfaf7
5 changed files with 202 additions and 10 deletions
+25 -4
View File
@@ -5,6 +5,7 @@ import { z } from 'zod';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import { Toast } from '@/components/ui/toast';
import { Mail, Phone, MapPin, Send, Loader2, Clock, HeadphonesIcon, CheckCircle2 } from 'lucide-react';
import { COMPANY_INFO } from '@/lib/constants';
@@ -28,6 +29,9 @@ export function ContactSection() {
const [isVisible, setIsVisible] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);
const [isSubmitted, setIsSubmitted] = useState(false);
const [showToast, setShowToast] = useState(false);
const [toastMessage, setToastMessage] = useState('');
const [toastType, setToastType] = useState<'success' | 'error'>('success');
const [formData, setFormData] = useState<ContactFormData>({
name: '',
phone: '',
@@ -96,14 +100,31 @@ export function ContactSection() {
setIsSubmitting(true);
await new Promise(resolve => setTimeout(resolve, 1500));
setIsSubmitting(false);
setIsSubmitted(true);
try {
await new Promise(resolve => setTimeout(resolve, 1500));
setIsSubmitting(false);
setIsSubmitted(true);
setToastMessage('表单提交成功!我们会尽快与您联系。');
setToastType('success');
setShowToast(true);
} catch (error) {
setIsSubmitting(false);
setToastMessage('提交失败,请稍后重试。');
setToastType('error');
setShowToast(true);
}
}
return (
<section id="contact" className="section-padding relative bg-white overflow-hidden" ref={sectionRef}>
{showToast && (
<Toast
message={toastMessage}
type={toastType}
onClose={() => setShowToast(false)}
/>
)}
<div className="absolute inset-0 pointer-events-none">
<div className="absolute inset-0 bg-gradient-radial from-[rgba(79,70,229,0.03)] via-transparent to-transparent" />
</div>