[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"header-categories":3,"post-web-performance-core-web-vitals":73,"parsed-post-e142fe82-f78c-4e55-bfc6-d5c739f3b7f0":147},{"success":4,"data":5},true,{"items":6,"pagination":70},[7,16,24,32,40,48,56,63],{"id":8,"name":9,"description":10,"parentId":11,"createdAt":12,"updatedAt":12,"parent":11,"children":13,"_count":14},"ai-future","AI & The Future","Artificial intelligence and emerging technology",null,"2026-07-24T06:02:45.990Z",[],{"posts":15},1,{"id":17,"name":18,"description":19,"parentId":11,"createdAt":20,"updatedAt":20,"parent":11,"children":21,"_count":22},"tools-productivity","Tools & Productivity","Developer tools and workflow optimization","2026-07-24T06:02:45.712Z",[],{"posts":23},7,{"id":25,"name":26,"description":27,"parentId":11,"createdAt":28,"updatedAt":28,"parent":11,"children":29,"_count":30},"career","Career & Growth","Professional development for developers","2026-07-24T06:02:45.486Z",[],{"posts":31},3,{"id":33,"name":34,"description":35,"parentId":11,"createdAt":36,"updatedAt":36,"parent":11,"children":37,"_count":38},"opinion","Opinion & Analysis","Industry analysis and technical opinions","2026-07-24T06:02:45.272Z",[],{"posts":39},6,{"id":41,"name":42,"description":43,"parentId":11,"createdAt":44,"updatedAt":44,"parent":11,"children":45,"_count":46},"tutorials","Tutorials","Step-by-step learning guides","2026-07-24T06:02:44.965Z",[],{"posts":47},21,{"id":49,"name":50,"description":51,"parentId":11,"createdAt":52,"updatedAt":52,"parent":11,"children":53,"_count":54},"software-engineering","Software Engineering","Best practices, patterns, and principles","2026-07-24T06:02:44.689Z",[],{"posts":55},24,{"id":57,"name":58,"description":59,"parentId":11,"createdAt":60,"updatedAt":60,"parent":11,"children":61,"_count":62},"devops-cloud","DevOps & Cloud","Infrastructure, deployment, and cloud computing","2026-07-24T06:02:44.453Z",[],{"posts":39},{"id":64,"name":65,"description":66,"parentId":11,"createdAt":67,"updatedAt":67,"parent":11,"children":68,"_count":69},"web-development","Web Development","Frontend and backend web development tutorials and guides","2026-07-24T06:02:44.169Z",[],{"posts":55},{"page":15,"limit":71,"total":71,"totalPages":15,"hasNext":72,"hasPrev":72},8,false,{"success":4,"data":74},{"id":75,"slug":76,"title":77,"excerpt":78,"content":79,"status":80,"visibility":81,"featuredImage":82,"canonicalUrl":11,"readingTime":83,"viewCount":84,"commentEnabled":4,"publishedAt":85,"scheduledAt":11,"createdAt":86,"updatedAt":87,"seoTitle":88,"seoDescription":78,"seoKeywords":11,"authorId":89,"author":90,"coAuthors":95,"tags":96,"categories":112,"comments":115,"_count":116,"relatedPosts":118},"e142fe82-f78c-4e55-bfc6-d5c739f3b7f0","web-performance-core-web-vitals","Web Performance: Core Web Vitals Optimization Guide","Practical techniques to improve LCP, FID, and CLS scores — the metrics that actually impact your search rankings and user experience.","## Why Core Web Vitals Matter\n\nGoogle uses Core Web Vitals as a ranking signal. But more importantly — they correlate directly with user experience and conversion rates.\n\n## LCP: Largest Contentful Paint (\u003C 2.5s)\n\nThe time until the largest visible element renders.\n\n**Common culprits:**\n- Unoptimized hero images\n- Render-blocking CSS\u002FJS\n- Slow server response (TTFB)\n\n**Fixes:**\n\n```html\n\u003C!-- Preload the LCP image -->\n\u003Clink rel=\"preload\" as=\"image\" href=\"\u002Fhero.webp\" \u002F>\n\n\u003C!-- Use modern formats with fallbacks -->\n\u003Cpicture>\n  \u003Csource srcset=\"\u002Fhero.avif\" type=\"image\u002Favif\" \u002F>\n  \u003Csource srcset=\"\u002Fhero.webp\" type=\"image\u002Fwebp\" \u002F>\n  \u003Cimg src=\"\u002Fhero.jpg\" alt=\"Hero\" width=\"1200\" height=\"600\" \u002F>\n\u003C\u002Fpicture>\n```\n\n```typescript\n\u002F\u002F nuxt.config.ts — inline critical CSS\nexport default defineNuxtConfig({\n  experimental: {\n    inlineSSRStyles: true,\n  },\n})\n```\n\n## INP: Interaction to Next Paint (\u003C 200ms)\n\nMeasures responsiveness to user interactions.\n\n```typescript\n\u002F\u002F ❌ Heavy computation blocks the main thread\nfunction handleClick() {\n  const result = expensiveCalculation(data) \u002F\u002F 300ms\n  updateUI(result)\n}\n\n\u002F\u002F ✅ Break work into chunks\nasync function handleClick() {\n  showLoadingState()\n  \u002F\u002F Yield to let the browser paint\n  await scheduler.yield()\n  const result = expensiveCalculation(data)\n  updateUI(result)\n}\n```\n\n::callout{icon=\"i-lucide-gauge\" color=\"success\"}\nThe new `scheduler.yield()` API (or `setTimeout(0)` as fallback) lets the browser paint between heavy JS operations, dramatically improving INP.\n::\n\n## CLS: Cumulative Layout Shift (\u003C 0.1)\n\nMeasures unexpected layout movements.\n\n```html\n\u003C!-- ✅ Always set dimensions on images -->\n\u003Cimg src=\"photo.jpg\" width=\"800\" height=\"600\" alt=\"...\" \u002F>\n\n\u003C!-- ✅ Reserve space for dynamic content -->\n\u003Cdiv class=\"min-h-[300px]\">\n  \u003CLazyLoadedChart \u002F>\n\u003C\u002Fdiv>\n```\n\n```css\n\u002F* ✅ Prevent font swap layout shift *\u002F\n@font-face {\n  font-family: 'Inter';\n  font-display: swap;\n  size-adjust: 107%;  \u002F* Match fallback metrics *\u002F\n}\n```\n\n## Quick Wins Checklist\n\n- [ ] Compress images to WebP\u002FAVIF\n- [ ] Set explicit width\u002Fheight on all images and videos\n- [ ] Preload LCP resources\n- [ ] Defer non-critical JavaScript\n- [ ] Use `font-display: swap` with size-adjust\n- [ ] Avoid layout shifts from dynamic content\n- [ ] Lazy load below-the-fold images\n- [ ] Use a CDN for static assets\n\n## Measuring\n\n```typescript\n\u002F\u002F Track real user metrics\nimport { onCLS, onINP, onLCP } from 'web-vitals'\n\nonCLS(console.log)\nonINP(console.log)\nonLCP(console.log)\n```\n\nPerformance isn't a one-time task — monitor continuously and optimize iteratively.\n","published","public","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1555066931-4365d14bab8c?w=1200&q=80",11,1408,"2026-06-21T06:03:26.029Z","2026-07-24T06:03:26.033Z","2026-07-28T17:12:23.078Z","Web Performance: Core Web Vitals Optimization Guide | BitBlog","fddb5d93-7a2c-4d86-a06a-fa32e73a01c6",{"email":91,"bio":92,"id":89,"name":93,"avatarUrl":94},"mbeahessilfieprince@gmail.com","Fullstack Software Developer ","Mbeah Essilfie","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F93322394?v=4",[],[97,102,107],{"id":98,"name":99,"color":100,"description":101},"javascript","JavaScript","#f7df1e","The language of the web",{"id":103,"name":104,"color":105,"description":106},"css","CSS","#1572b6","Cascading Style Sheets",{"id":108,"name":109,"color":110,"description":111},"performance","Performance","#e535ab","Web performance optimization",[113,114],{"id":64,"name":65,"description":66},{"id":49,"name":50,"description":51},[],{"comments":117},0,[119,128,137],{"id":120,"slug":121,"title":122,"excerpt":123,"featuredImage":124,"viewCount":125,"readingTime":71,"publishedAt":126,"author":127},"2997028f-4d22-4eb7-9d86-894a54cb559a","building-type-safe-apis-nuxt3-prisma","Building Type-Safe APIs with Nuxt 3 and Prisma","Learn how to build end-to-end type-safe APIs using Nuxt 3 server routes and Prisma ORM for a seamless developer experience.","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1498050108023-c5249f4df085?w=1200&q=80",1922,"2026-07-23T06:02:46.910Z",{"id":89,"name":93,"avatarUrl":94},{"id":129,"slug":130,"title":131,"excerpt":132,"featuredImage":82,"viewCount":133,"readingTime":134,"publishedAt":135,"author":136},"da9e4553-8b0d-411e-b4ec-f9684017e163","mastering-tailwind-css-design-systems","Mastering Tailwind CSS: From Utility Classes to Design Systems","Go beyond basic utility classes and learn how to build cohesive, maintainable design systems with Tailwind CSS.",257,10,"2026-07-21T06:02:49.268Z",{"id":89,"name":93,"avatarUrl":94},{"id":138,"slug":139,"title":140,"excerpt":141,"featuredImage":142,"viewCount":143,"readingTime":144,"publishedAt":145,"author":146},"50add5fc-4026-4267-b917-7f71ea9e35b0","complete-guide-vue3-composables","The Complete Guide to Vue 3 Composables","Understand the power of Vue 3's Composition API through practical, real-world composable patterns that you can use today.","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1517694712202-14dd9538aa97?w=1200&q=80",990,12,"2026-07-19T06:02:51.753Z",{"id":89,"name":93,"avatarUrl":94},{"data":148,"body":150,"toc":431},{"title":149,"description":149},"",{"type":151,"children":152},"root",[153,162,168,174,179,188,208,216,229,239,245,250,258,285,291,296,304,313,319,407,413,421,426],{"type":154,"tag":155,"props":156,"children":158},"element","h2",{"id":157},"why-core-web-vitals-matter",[159],{"type":160,"value":161},"text","Why Core Web Vitals Matter",{"type":154,"tag":163,"props":164,"children":165},"p",{},[166],{"type":160,"value":167},"Google uses Core Web Vitals as a ranking signal. But more importantly — they correlate directly with user experience and conversion rates.",{"type":154,"tag":155,"props":169,"children":171},{"id":170},"lcp-largest-contentful-paint-25s",[172],{"type":160,"value":173},"LCP: Largest Contentful Paint (\u003C 2.5s)",{"type":154,"tag":163,"props":175,"children":176},{},[177],{"type":160,"value":178},"The time until the largest visible element renders.",{"type":154,"tag":163,"props":180,"children":181},{},[182],{"type":154,"tag":183,"props":184,"children":185},"strong",{},[186],{"type":160,"value":187},"Common culprits:",{"type":154,"tag":189,"props":190,"children":191},"ul",{},[192,198,203],{"type":154,"tag":193,"props":194,"children":195},"li",{},[196],{"type":160,"value":197},"Unoptimized hero images",{"type":154,"tag":193,"props":199,"children":200},{},[201],{"type":160,"value":202},"Render-blocking CSS\u002FJS",{"type":154,"tag":193,"props":204,"children":205},{},[206],{"type":160,"value":207},"Slow server response (TTFB)",{"type":154,"tag":163,"props":209,"children":210},{},[211],{"type":154,"tag":183,"props":212,"children":213},{},[214],{"type":160,"value":215},"Fixes:",{"type":154,"tag":217,"props":218,"children":223},"pre",{"className":219,"code":220,"language":221,"meta":149,"style":222},"language-html","\u003C!-- Preload the LCP image -->\n\u003Clink rel=\"preload\" as=\"image\" href=\"\u002Fhero.webp\" \u002F>\n\n\u003C!-- Use modern formats with fallbacks -->\n\u003Cpicture>\n  \u003Csource srcset=\"\u002Fhero.avif\" type=\"image\u002Favif\" \u002F>\n  \u003Csource srcset=\"\u002Fhero.webp\" type=\"image\u002Fwebp\" \u002F>\n  \u003Cimg src=\"\u002Fhero.jpg\" alt=\"Hero\" width=\"1200\" height=\"600\" \u002F>\n\u003C\u002Fpicture>\n","html","undefined",[224],{"type":154,"tag":225,"props":226,"children":227},"code",{"__ignoreMap":149},[228],{"type":160,"value":220},{"type":154,"tag":217,"props":230,"children":234},{"className":231,"code":232,"language":233,"meta":149,"style":222},"language-typescript","\u002F\u002F nuxt.config.ts — inline critical CSS\nexport default defineNuxtConfig({\n  experimental: {\n    inlineSSRStyles: true,\n  },\n})\n","typescript",[235],{"type":154,"tag":225,"props":236,"children":237},{"__ignoreMap":149},[238],{"type":160,"value":232},{"type":154,"tag":155,"props":240,"children":242},{"id":241},"inp-interaction-to-next-paint-200ms",[243],{"type":160,"value":244},"INP: Interaction to Next Paint (\u003C 200ms)",{"type":154,"tag":163,"props":246,"children":247},{},[248],{"type":160,"value":249},"Measures responsiveness to user interactions.",{"type":154,"tag":217,"props":251,"children":253},{"className":231,"code":252,"language":233,"meta":149,"style":222},"\u002F\u002F ❌ Heavy computation blocks the main thread\nfunction handleClick() {\n  const result = expensiveCalculation(data) \u002F\u002F 300ms\n  updateUI(result)\n}\n\n\u002F\u002F ✅ Break work into chunks\nasync function handleClick() {\n  showLoadingState()\n  \u002F\u002F Yield to let the browser paint\n  await scheduler.yield()\n  const result = expensiveCalculation(data)\n  updateUI(result)\n}\n",[254],{"type":154,"tag":225,"props":255,"children":256},{"__ignoreMap":149},[257],{"type":160,"value":252},{"type":154,"tag":259,"props":260,"children":263},"callout",{"color":261,"icon":262},"success","i-lucide-gauge",[264],{"type":154,"tag":163,"props":265,"children":266},{},[267,269,275,277,283],{"type":160,"value":268},"The new ",{"type":154,"tag":225,"props":270,"children":272},{"className":271},[],[273],{"type":160,"value":274},"scheduler.yield()",{"type":160,"value":276}," API (or ",{"type":154,"tag":225,"props":278,"children":280},{"className":279},[],[281],{"type":160,"value":282},"setTimeout(0)",{"type":160,"value":284}," as fallback) lets the browser paint between heavy JS operations, dramatically improving INP.",{"type":154,"tag":155,"props":286,"children":288},{"id":287},"cls-cumulative-layout-shift-01",[289],{"type":160,"value":290},"CLS: Cumulative Layout Shift (\u003C 0.1)",{"type":154,"tag":163,"props":292,"children":293},{},[294],{"type":160,"value":295},"Measures unexpected layout movements.",{"type":154,"tag":217,"props":297,"children":299},{"className":219,"code":298,"language":221,"meta":149,"style":222},"\u003C!-- ✅ Always set dimensions on images -->\n\u003Cimg src=\"photo.jpg\" width=\"800\" height=\"600\" alt=\"...\" \u002F>\n\n\u003C!-- ✅ Reserve space for dynamic content -->\n\u003Cdiv class=\"min-h-[300px]\">\n  \u003CLazyLoadedChart \u002F>\n\u003C\u002Fdiv>\n",[300],{"type":154,"tag":225,"props":301,"children":302},{"__ignoreMap":149},[303],{"type":160,"value":298},{"type":154,"tag":217,"props":305,"children":308},{"className":306,"code":307,"language":103,"meta":149,"style":222},"language-css","\u002F* ✅ Prevent font swap layout shift *\u002F\n@font-face {\n  font-family: 'Inter';\n  font-display: swap;\n  size-adjust: 107%;  \u002F* Match fallback metrics *\u002F\n}\n",[309],{"type":154,"tag":225,"props":310,"children":311},{"__ignoreMap":149},[312],{"type":160,"value":307},{"type":154,"tag":155,"props":314,"children":316},{"id":315},"quick-wins-checklist",[317],{"type":160,"value":318},"Quick Wins Checklist",{"type":154,"tag":189,"props":320,"children":323},{"className":321},[322],"contains-task-list",[324,336,345,354,363,380,389,398],{"type":154,"tag":193,"props":325,"children":328},{"className":326},[327],"task-list-item",[329,334],{"type":154,"tag":330,"props":331,"children":333},"input",{"disabled":4,"type":332},"checkbox",[],{"type":160,"value":335}," Compress images to WebP\u002FAVIF",{"type":154,"tag":193,"props":337,"children":339},{"className":338},[327],[340,343],{"type":154,"tag":330,"props":341,"children":342},{"disabled":4,"type":332},[],{"type":160,"value":344}," Set explicit width\u002Fheight on all images and videos",{"type":154,"tag":193,"props":346,"children":348},{"className":347},[327],[349,352],{"type":154,"tag":330,"props":350,"children":351},{"disabled":4,"type":332},[],{"type":160,"value":353}," Preload LCP resources",{"type":154,"tag":193,"props":355,"children":357},{"className":356},[327],[358,361],{"type":154,"tag":330,"props":359,"children":360},{"disabled":4,"type":332},[],{"type":160,"value":362}," Defer non-critical JavaScript",{"type":154,"tag":193,"props":364,"children":366},{"className":365},[327],[367,370,372,378],{"type":154,"tag":330,"props":368,"children":369},{"disabled":4,"type":332},[],{"type":160,"value":371}," Use ",{"type":154,"tag":225,"props":373,"children":375},{"className":374},[],[376],{"type":160,"value":377},"font-display: swap",{"type":160,"value":379}," with size-adjust",{"type":154,"tag":193,"props":381,"children":383},{"className":382},[327],[384,387],{"type":154,"tag":330,"props":385,"children":386},{"disabled":4,"type":332},[],{"type":160,"value":388}," Avoid layout shifts from dynamic content",{"type":154,"tag":193,"props":390,"children":392},{"className":391},[327],[393,396],{"type":154,"tag":330,"props":394,"children":395},{"disabled":4,"type":332},[],{"type":160,"value":397}," Lazy load below-the-fold images",{"type":154,"tag":193,"props":399,"children":401},{"className":400},[327],[402,405],{"type":154,"tag":330,"props":403,"children":404},{"disabled":4,"type":332},[],{"type":160,"value":406}," Use a CDN for static assets",{"type":154,"tag":155,"props":408,"children":410},{"id":409},"measuring",[411],{"type":160,"value":412},"Measuring",{"type":154,"tag":217,"props":414,"children":416},{"className":231,"code":415,"language":233,"meta":149,"style":222},"\u002F\u002F Track real user metrics\nimport { onCLS, onINP, onLCP } from 'web-vitals'\n\nonCLS(console.log)\nonINP(console.log)\nonLCP(console.log)\n",[417],{"type":154,"tag":225,"props":418,"children":419},{"__ignoreMap":149},[420],{"type":160,"value":415},{"type":154,"tag":163,"props":422,"children":423},{},[424],{"type":160,"value":425},"Performance isn't a one-time task — monitor continuously and optimize iteratively.",{"type":154,"tag":427,"props":428,"children":429},"style",{},[430],{"type":160,"value":149},{"title":149,"searchDepth":432,"depth":432,"links":433},2,[434,435,436,437,438,439],{"id":157,"depth":432,"text":161},{"id":170,"depth":432,"text":173},{"id":241,"depth":432,"text":244},{"id":287,"depth":432,"text":290},{"id":315,"depth":432,"text":318},{"id":409,"depth":432,"text":412}]