Optimize blog performance with Next.js 16 features and video conversion
## Performance Improvements ### Next.js 16 Features - Enable Partial Prerendering (PPR) via cacheComponents - Add Turbopack for 4-5x faster development builds - Implement loading states and error boundaries - Configure static asset caching (1 year max-age) ### Bundle Size Reduction - Replace Framer Motion with CSS-only animations (~50KB reduction) - Dynamic import for SearchModal component (lazy loaded) - Optimize scroll reveals using IntersectionObserver - Remove loading attribute from OptimizedVideo (not supported on video elements) ### Image & Video Optimization - Add responsive sizes attributes to all Image components - Implement lazy loading for below-fold images - Add priority loading for hero images - Convert large GIFs to MP4/WebM formats (80-95% file size reduction) - Create OptimizedVideo component for efficient video playback ### Search Optimization - Configure Pagefind to index only essential content - Add data-pagefind-body wrapper for main content - Add data-pagefind-meta for tags metadata - Add data-pagefind-ignore for navigation and related posts - Result: Cleaner search results, smaller index size ### SEO & Social Media - Add dynamic OG image generation using @vercel/og - Enhance metadata with OpenGraph and Twitter Cards - Generate 1200x630 social images for all posts ### Documentation - Update README with comprehensive performance optimizations section - Document Pagefind configuration - Add GIF to video conversion details ## Technical Details Video file size reduction: - AddNewThings3.gif (2.4MB) → WebM (116KB) = 95% reduction - Things3.gif (1.5MB) → WebM (170KB) = 89% reduction - Total: 3.9MB → 286KB = 93% reduction Build output: 49 pages indexed, 5370 words searchable
This commit is contained in:
@@ -81,9 +81,11 @@ export default async function BlogPostPage({ params }: Props) {
|
||||
<ReadingProgress />
|
||||
<PostLayout hasToc={hasToc}>
|
||||
<div className="space-y-8">
|
||||
<SectionDivider>
|
||||
<ScrollReveal>
|
||||
<header className="mb-6 space-y-4 text-center">
|
||||
{/* Main content area for Pagefind indexing */}
|
||||
<div data-pagefind-body>
|
||||
<SectionDivider>
|
||||
<ScrollReveal>
|
||||
<header className="mb-6 space-y-4 text-center">
|
||||
{post.published_at && (
|
||||
<p className="type-small text-slate-500 dark:text-slate-500">
|
||||
{new Date(post.published_at).toLocaleDateString(
|
||||
@@ -95,7 +97,7 @@ export default async function BlogPostPage({ params }: Props) {
|
||||
{post.title}
|
||||
</h1>
|
||||
{post.tags && (
|
||||
<div className="flex flex-wrap justify-center gap-2 pt-2">
|
||||
<div className="flex flex-wrap justify-center gap-2 pt-2" data-pagefind-meta="tags">
|
||||
{post.tags.map((t) => (
|
||||
<Link
|
||||
key={t}
|
||||
@@ -133,23 +135,26 @@ export default async function BlogPostPage({ params }: Props) {
|
||||
</article>
|
||||
</ScrollReveal>
|
||||
</SectionDivider>
|
||||
</div>
|
||||
|
||||
<FooterCue />
|
||||
|
||||
<SectionDivider>
|
||||
<ScrollReveal>
|
||||
<PostStorylineNav
|
||||
current={post}
|
||||
newer={neighbors.newer}
|
||||
older={neighbors.older}
|
||||
/>
|
||||
</ScrollReveal>
|
||||
</SectionDivider>
|
||||
|
||||
{relatedPosts.length > 0 && (
|
||||
{/* Exclude navigation and related posts from search indexing */}
|
||||
<div data-pagefind-ignore>
|
||||
<SectionDivider>
|
||||
<ScrollReveal>
|
||||
<section className="space-y-6 rounded-2xl border border-slate-200/60 bg-slate-50/50 p-8 dark:border-slate-800 dark:bg-slate-900/30">
|
||||
<PostStorylineNav
|
||||
current={post}
|
||||
newer={neighbors.newer}
|
||||
older={neighbors.older}
|
||||
/>
|
||||
</ScrollReveal>
|
||||
</SectionDivider>
|
||||
|
||||
{relatedPosts.length > 0 && (
|
||||
<SectionDivider>
|
||||
<ScrollReveal>
|
||||
<section className="space-y-6 rounded-2xl border border-slate-200/60 bg-slate-50/50 p-8 dark:border-slate-800 dark:bg-slate-900/30">
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<h2 className="type-subtitle font-semibold text-slate-900 dark:text-slate-50">
|
||||
相關文章
|
||||
@@ -166,7 +171,8 @@ export default async function BlogPostPage({ params }: Props) {
|
||||
</section>
|
||||
</ScrollReveal>
|
||||
</SectionDivider>
|
||||
)}
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</PostLayout>
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user