[{"data":1,"prerenderedAt":961},["ShallowReactive",2],{"blog-best-image-optimization-tools-nextjs-react/":3},{"id":4,"title":5,"body":6,"description":917,"extension":918,"faqs":919,"image":932,"imageAlt":933,"imageCaption":934,"meta":935,"navigation":162,"path":936,"publishedAt":937,"readingTime":262,"references":938,"seo":951,"stem":952,"tags":953,"updatedAt":937,"__hash__":960},"blog/blog/best-image-optimization-tools-nextjs-react.md","Best Image Optimization Tools for Next.js and React Sites",{"type":7,"value":8,"toc":902},"minimark",[9,13,16,28,31,36,39,64,67,70,74,94,98,105,108,122,125,288,291,316,319,336,339,343,346,349,352,369,372,433,443,446,450,453,456,459,473,476,525,531,535,538,541,555,558,562,565,568,582,585,589,592,595,598,615,618,622,625,671,674,678,681,838,841,845,848,851,854,858,885,889,895,898],[10,11,12],"p",{},"Images are still one of the easiest ways to wreck Largest Contentful Paint.",[10,14,15],{},"You can have a clean React app, a tidy component tree and a decent bundle size, then lose the whole page to one 2400px hero image that loads lazily from a slow origin. I have seen that exact problem more times than I would like.",[10,17,18,19,23,24,27],{},"The annoying part is that \"use an image CDN\" is not always the answer. Sometimes ",[20,21,22],"code",{},"next/image"," is enough. Sometimes a CDN is exactly what you need. Sometimes the real fix is boring: set the right ",[20,25,26],{},"sizes",", stop lazy-loading the hero image, and stop letting CMS uploads go live without constraints.",[10,29,30],{},"This guide is for choosing the right image optimization setup without buying more tooling than the site needs.",[32,33,35],"h2",{"id":34},"start-with-the-actual-image-problem","Start with the actual image problem",[10,37,38],{},"Do this before choosing a tool. Work out which problem is hurting the page:",[40,41,42,46,49,52,55,58,61],"ul",{},[43,44,45],"li",{},"Files are too large.",[43,47,48],{},"Mobile users get desktop-sized images.",[43,50,51],{},"JPEG or PNG is being used where WebP or AVIF would be smaller.",[43,53,54],{},"The browser discovers the hero image too late.",[43,56,57],{},"The LCP image is lazy-loaded or not prioritised.",[43,59,60],{},"Images are transformed repeatedly instead of cached.",[43,62,63],{},"Editors can upload anything and the frontend has no guardrails.",[10,65,66],{},"Compression tools help with file size. Image CDNs help with sizing, formats, caching and transformations. Framework image components help with responsive markup and layout stability.",[10,68,69],{},"None of them fix a hero image that only appears after client-side JavaScript runs.",[32,71,73],{"id":72},"quick-picks","Quick picks",[40,75,76,82,85,88,91],{},[43,77,78,79,81],{},"Next.js on Vercel or a compatible host: start with ",[20,80,22],{},".",[43,83,84],{},"React SPA or Vite site: use build-time optimization for local images or an image CDN for CMS assets.",[43,86,87],{},"Astro/content site: use Astro's image tooling for local files and a CDN for media libraries.",[43,89,90],{},"WordPress: use a plugin/CDN workflow, but check the LCP image after enabling it.",[43,92,93],{},"Agency/client sites: pick the option that prevents non-developers from accidentally uploading a 4 MB homepage banner.",[32,95,97],{"id":96},"nextjs-image-component","Next.js Image component",[10,99,100,101,104],{},"Next.js already has a good image story through the ",[20,102,103],{},"Image"," component. It can create responsive variants, lazy-load non-critical images and reserve space to reduce layout shift.",[10,106,107],{},"Use it first when:",[40,109,110,113,116,119],{},[43,111,112],{},"the site is already on Next.js",[43,114,115],{},"images are local or come from known remote domains",[43,117,118],{},"your host supports the optimization flow you need",[43,120,121],{},"you do not need a shared media library across several sites",[10,123,124],{},"Example:",[126,127,132],"pre",{"className":128,"code":129,"language":130,"meta":131,"style":131},"language-tsx shiki shiki-themes github-light github-dark","import Image from 'next/image';\n\nexport function Hero() {\n  return (\n    \u003CImage\n      src=\"/hero-dashboard.jpg\"\n      alt=\"Dashboard preview\"\n      width={1200}\n      height={700}\n      priority\n      sizes=\"(max-width: 768px) 100vw, 1200px\"\n    />\n  );\n}\n","tsx","",[20,133,134,157,164,180,189,199,211,222,239,254,260,271,277,283],{"__ignoreMap":131},[135,136,139,143,147,150,154],"span",{"class":137,"line":138},"line",1,[135,140,142],{"class":141},"szBVR","import",[135,144,146],{"class":145},"sVt8B"," Image ",[135,148,149],{"class":141},"from",[135,151,153],{"class":152},"sZZnC"," 'next/image'",[135,155,156],{"class":145},";\n",[135,158,160],{"class":137,"line":159},2,[135,161,163],{"emptyLinePlaceholder":162},true,"\n",[135,165,167,170,173,177],{"class":137,"line":166},3,[135,168,169],{"class":141},"export",[135,171,172],{"class":141}," function",[135,174,176],{"class":175},"sScJk"," Hero",[135,178,179],{"class":145},"() {\n",[135,181,183,186],{"class":137,"line":182},4,[135,184,185],{"class":141},"  return",[135,187,188],{"class":145}," (\n",[135,190,192,195],{"class":137,"line":191},5,[135,193,194],{"class":145},"    \u003C",[135,196,198],{"class":197},"sj4cs","Image\n",[135,200,202,205,208],{"class":137,"line":201},6,[135,203,204],{"class":175},"      src",[135,206,207],{"class":141},"=",[135,209,210],{"class":152},"\"/hero-dashboard.jpg\"\n",[135,212,214,217,219],{"class":137,"line":213},7,[135,215,216],{"class":175},"      alt",[135,218,207],{"class":141},[135,220,221],{"class":152},"\"Dashboard preview\"\n",[135,223,225,228,230,233,236],{"class":137,"line":224},8,[135,226,227],{"class":175},"      width",[135,229,207],{"class":141},[135,231,232],{"class":145},"{",[135,234,235],{"class":197},"1200",[135,237,238],{"class":145},"}\n",[135,240,242,245,247,249,252],{"class":137,"line":241},9,[135,243,244],{"class":175},"      height",[135,246,207],{"class":141},[135,248,232],{"class":145},[135,250,251],{"class":197},"700",[135,253,238],{"class":145},[135,255,257],{"class":137,"line":256},10,[135,258,259],{"class":175},"      priority\n",[135,261,263,266,268],{"class":137,"line":262},11,[135,264,265],{"class":175},"      sizes",[135,267,207],{"class":141},[135,269,270],{"class":152},"\"(max-width: 768px) 100vw, 1200px\"\n",[135,272,274],{"class":137,"line":273},12,[135,275,276],{"class":145},"    />\n",[135,278,280],{"class":137,"line":279},13,[135,281,282],{"class":145},"  );\n",[135,284,286],{"class":137,"line":285},14,[135,287,238],{"class":145},[10,289,290],{},"The small details matter:",[40,292,293,300,306,309],{},[43,294,295,296,299],{},"Use ",[20,297,298],{},"priority"," for the real LCP hero image.",[43,301,302,303,305],{},"Add an accurate ",[20,304,26],{}," value. The default can be too broad for real layouts.",[43,307,308],{},"Do not hide critical images behind components that only render after client state loads.",[43,310,311,312,315],{},"Configure ",[20,313,314],{},"remotePatterns"," properly for CMS images.",[10,317,318],{},"Where it gets awkward:",[40,320,321,324,327,330,333],{},[43,322,323],{},"complex editorial cropping",[43,325,326],{},"lots of remote CMS media",[43,328,329],{},"transformations shared across multiple products",[43,331,332],{},"art direction, overlays or reusable image presets",[43,334,335],{},"non-Next.js sites in the same business",[10,337,338],{},"If the image workflow is bigger than one Next.js app, reach for a CDN.",[32,340,342],{"id":341},"cloudinary","Cloudinary",[10,344,345],{},"Cloudinary is the heavyweight option. It handles image and video storage, transformations, responsive delivery, cropping, overlays and asset management.",[10,347,348],{},"It makes sense when media is part of the product workflow, not just a folder of static images.",[10,350,351],{},"Use Cloudinary when:",[40,353,354,357,360,363,366],{},[43,355,356],{},"editors upload a lot of media",[43,358,359],{},"you need transformations, crops, overlays or art direction",[43,361,362],{},"multiple sites share the same assets",[43,364,365],{},"you need image and video handling together",[43,367,368],{},"non-developers need a media UI",[10,370,371],{},"Example URL pattern:",[126,373,377],{"className":374,"code":375,"language":376,"meta":131,"style":131},"language-html shiki shiki-themes github-light github-dark","\u003Cimg\n  src=\"https://res.cloudinary.com/demo/image/upload/f_auto,q_auto,w_800/sample.jpg\"\n  width=\"800\"\n  height=\"533\"\n  alt=\"Optimized sample\"\n/>\n","html",[20,378,379,388,398,408,418,428],{"__ignoreMap":131},[135,380,381,384],{"class":137,"line":138},[135,382,383],{"class":145},"\u003C",[135,385,387],{"class":386},"s9eBZ","img\n",[135,389,390,393,395],{"class":137,"line":159},[135,391,392],{"class":175},"  src",[135,394,207],{"class":145},[135,396,397],{"class":152},"\"https://res.cloudinary.com/demo/image/upload/f_auto,q_auto,w_800/sample.jpg\"\n",[135,399,400,403,405],{"class":137,"line":166},[135,401,402],{"class":175},"  width",[135,404,207],{"class":145},[135,406,407],{"class":152},"\"800\"\n",[135,409,410,413,415],{"class":137,"line":182},[135,411,412],{"class":175},"  height",[135,414,207],{"class":145},[135,416,417],{"class":152},"\"533\"\n",[135,419,420,423,425],{"class":137,"line":191},[135,421,422],{"class":175},"  alt",[135,424,207],{"class":145},[135,426,427],{"class":152},"\"Optimized sample\"\n",[135,429,430],{"class":137,"line":201},[135,431,432],{"class":145},"/>\n",[10,434,435,438,439,442],{},[20,436,437],{},"f_auto"," lets Cloudinary choose the format. ",[20,440,441],{},"q_auto"," handles quality. The width parameter stops you sending the original monster file to every device.",[10,444,445],{},"Watch the usual trade-offs: pricing, transformation sprawl, account limits and keeping image presets consistent across the team.",[32,447,449],{"id":448},"imagekit","ImageKit",[10,451,452],{},"ImageKit is a focused image CDN with URL-based transformations, automatic format conversion, quality settings and media management.",[10,454,455],{},"It is a good fit when you want image delivery improvements without building your own pipeline.",[10,457,458],{},"Use ImageKit when:",[40,460,461,464,467,470],{},[43,462,463],{},"images come from a CMS, S3 bucket or existing origin",[43,465,466],{},"you want global delivery and transformations",[43,468,469],{},"you want to keep existing asset URLs mostly intact",[43,471,472],{},"you need a lighter image platform than Cloudinary",[10,474,475],{},"Typical URL pattern:",[126,477,479],{"className":374,"code":478,"language":376,"meta":131,"style":131},"\u003Cimg\n  src=\"https://ik.imagekit.io/example/site/hero.jpg?tr=w-800,q-80,f-auto\"\n  width=\"800\"\n  height=\"533\"\n  alt=\"Optimized hero\"\n/>\n",[20,480,481,487,496,504,512,521],{"__ignoreMap":131},[135,482,483,485],{"class":137,"line":138},[135,484,383],{"class":145},[135,486,387],{"class":386},[135,488,489,491,493],{"class":137,"line":159},[135,490,392],{"class":175},[135,492,207],{"class":145},[135,494,495],{"class":152},"\"https://ik.imagekit.io/example/site/hero.jpg?tr=w-800,q-80,f-auto\"\n",[135,497,498,500,502],{"class":137,"line":166},[135,499,402],{"class":175},[135,501,207],{"class":145},[135,503,407],{"class":152},[135,505,506,508,510],{"class":137,"line":182},[135,507,412],{"class":175},[135,509,207],{"class":145},[135,511,417],{"class":152},[135,513,514,516,518],{"class":137,"line":191},[135,515,422],{"class":175},[135,517,207],{"class":145},[135,519,520],{"class":152},"\"Optimized hero\"\n",[135,522,523],{"class":137,"line":201},[135,524,432],{"class":145},[10,526,527,528,530],{},"The main thing to check is whether your generated widths match the ",[20,529,26],{}," values in your frontend. A CDN can generate perfect variants and still waste bandwidth if the HTML asks for the wrong one.",[32,532,534],{"id":533},"imgix","Imgix",[10,536,537],{},"Imgix is a developer-friendly image CDN built around URL parameters and precise transformations. It is useful when the engineering team wants control and the source images already live somewhere else.",[10,539,540],{},"Use Imgix when:",[40,542,543,546,549,552],{},[43,544,545],{},"images live in S3, a CMS or another origin",[43,547,548],{},"you need cropping, DPR variants and format control",[43,550,551],{},"engineers are comfortable managing transformation URLs",[43,553,554],{},"you want a mature CDN workflow without a full DAM-style setup",[10,556,557],{},"The risk is complexity leaking into templates. If every component invents its own transformation string, the site becomes harder to maintain. Create presets or helper functions early.",[32,559,561],{"id":560},"cloudflare-images-image-resizing-and-polish","Cloudflare Images, Image Resizing and Polish",[10,563,564],{},"Cloudflare has a few image options, depending on your plan and setup. Cloudflare Images can store and transform images. Image Resizing can transform assets at the edge. Polish can optimize images that pass through Cloudflare on supported plans.",[10,566,567],{},"Use Cloudflare when:",[40,569,570,573,576,579],{},[43,571,572],{},"the site already sits behind Cloudflare",[43,574,575],{},"you want fewer vendors",[43,577,578],{},"your image needs are fairly straightforward",[43,580,581],{},"edge delivery matters more than media-library features",[10,583,584],{},"Check plan availability before designing around a feature. Also check cache behaviour carefully, especially when images are replaced but URLs stay the same.",[32,586,588],{"id":587},"shortpixel-tinypng-and-build-time-compression","ShortPixel, TinyPNG and build-time compression",[10,590,591],{},"Not every site needs an image CDN.",[10,593,594],{},"For small static sites, build-time compression may be the sanest option. Run images through Sharp, Squoosh, ShortPixel, TinyPNG or a similar tool before deploy. Commit the optimized files. Move on.",[10,596,597],{},"That works well when:",[40,599,600,603,606,609,612],{},[43,601,602],{},"there are not many images",[43,604,605],{},"images live in the repo",[43,607,608],{},"content changes slowly",[43,610,611],{},"editors are not uploading new media every day",[43,613,614],{},"transformations on demand would be overkill",[10,616,617],{},"A simple Sharp script that creates WebP/AVIF variants and resizes large originals can beat a paid CDN for a small developer-owned site.",[32,619,621],{"id":620},"the-lcp-image-checklist","The LCP image checklist",[10,623,624],{},"Before blaming your image service, check the page itself:",[626,627,628,631,634,648,651,662,665,668],"ol",{},[43,629,630],{},"Is the LCP image the right size for mobile?",[43,632,633],{},"Is it present in the initial HTML?",[43,635,636,637,639,640,643,644,647],{},"Is it prioritised with ",[20,638,298],{},", ",[20,641,642],{},"preload"," or ",[20,645,646],{},"fetchpriority=\"high\""," where appropriate?",[43,649,650],{},"Is it accidentally lazy-loaded?",[43,652,653,654,657,658,661],{},"Are ",[20,655,656],{},"width"," and ",[20,659,660],{},"height"," set?",[43,663,664],{},"Is it a CSS background image that the browser discovers late?",[43,666,667],{},"Is TTFB slow before the image even starts loading?",[43,669,670],{},"Are third-party scripts or heavy JavaScript delaying render?",[10,672,673],{},"Most bad LCP images fail more than one of those checks.",[32,675,677],{"id":676},"example-hero-image-markup","Example hero image markup",[10,679,680],{},"For a non-Next.js site:",[126,682,684],{"className":374,"code":683,"language":376,"meta":131,"style":131},"\u003Clink\n  rel=\"preload\"\n  as=\"image\"\n  href=\"/images/hero-1200.webp\"\n  imagesrcset=\"/images/hero-600.webp 600w, /images/hero-1200.webp 1200w\"\n  imagesizes=\"100vw\"\n/>\n\n\u003Cimg\n  src=\"/images/hero-1200.webp\"\n  srcset=\"/images/hero-600.webp 600w, /images/hero-1200.webp 1200w\"\n  sizes=\"100vw\"\n  width=\"1200\"\n  height=\"700\"\n  fetchpriority=\"high\"\n  decoding=\"async\"\n  alt=\"Product dashboard showing performance metrics\"\n/>\n",[20,685,686,693,703,713,723,733,743,747,751,757,765,774,783,792,801,812,823,833],{"__ignoreMap":131},[135,687,688,690],{"class":137,"line":138},[135,689,383],{"class":145},[135,691,692],{"class":386},"link\n",[135,694,695,698,700],{"class":137,"line":159},[135,696,697],{"class":175},"  rel",[135,699,207],{"class":145},[135,701,702],{"class":152},"\"preload\"\n",[135,704,705,708,710],{"class":137,"line":166},[135,706,707],{"class":175},"  as",[135,709,207],{"class":145},[135,711,712],{"class":152},"\"image\"\n",[135,714,715,718,720],{"class":137,"line":182},[135,716,717],{"class":175},"  href",[135,719,207],{"class":145},[135,721,722],{"class":152},"\"/images/hero-1200.webp\"\n",[135,724,725,728,730],{"class":137,"line":191},[135,726,727],{"class":175},"  imagesrcset",[135,729,207],{"class":145},[135,731,732],{"class":152},"\"/images/hero-600.webp 600w, /images/hero-1200.webp 1200w\"\n",[135,734,735,738,740],{"class":137,"line":201},[135,736,737],{"class":175},"  imagesizes",[135,739,207],{"class":145},[135,741,742],{"class":152},"\"100vw\"\n",[135,744,745],{"class":137,"line":213},[135,746,432],{"class":145},[135,748,749],{"class":137,"line":224},[135,750,163],{"emptyLinePlaceholder":162},[135,752,753,755],{"class":137,"line":241},[135,754,383],{"class":145},[135,756,387],{"class":386},[135,758,759,761,763],{"class":137,"line":256},[135,760,392],{"class":175},[135,762,207],{"class":145},[135,764,722],{"class":152},[135,766,767,770,772],{"class":137,"line":262},[135,768,769],{"class":175},"  srcset",[135,771,207],{"class":145},[135,773,732],{"class":152},[135,775,776,779,781],{"class":137,"line":273},[135,777,778],{"class":175},"  sizes",[135,780,207],{"class":145},[135,782,742],{"class":152},[135,784,785,787,789],{"class":137,"line":279},[135,786,402],{"class":175},[135,788,207],{"class":145},[135,790,791],{"class":152},"\"1200\"\n",[135,793,794,796,798],{"class":137,"line":285},[135,795,412],{"class":175},[135,797,207],{"class":145},[135,799,800],{"class":152},"\"700\"\n",[135,802,804,807,809],{"class":137,"line":803},15,[135,805,806],{"class":175},"  fetchpriority",[135,808,207],{"class":145},[135,810,811],{"class":152},"\"high\"\n",[135,813,815,818,820],{"class":137,"line":814},16,[135,816,817],{"class":175},"  decoding",[135,819,207],{"class":145},[135,821,822],{"class":152},"\"async\"\n",[135,824,826,828,830],{"class":137,"line":825},17,[135,827,422],{"class":175},[135,829,207],{"class":145},[135,831,832],{"class":152},"\"Product dashboard showing performance metrics\"\n",[135,834,836],{"class":137,"line":835},18,[135,837,432],{"class":145},[10,839,840],{},"Preload one image carefully. Do not preload every image above the fold and hope for the best. Preload the actual LCP candidate, then check the waterfall.",[32,842,844],{"id":843},"which-option-should-you-choose","Which option should you choose?",[10,846,847],{},"Choose framework-native optimization when the stack already supports it, image sources are simple and you do not need cross-site media management.",[10,849,850],{},"Choose an image CDN when images come from a CMS, multiple sites share assets, non-technical users upload media, or image traffic is commercially important.",[10,852,853],{},"Choose build-time compression when images live in the repo and content changes slowly. It is boring, cheap and often enough.",[32,855,857],{"id":856},"related-pagespeedfix-guides","Related PageSpeedFix guides",[40,859,860,867,873,879],{},[43,861,862],{},[863,864,866],"a",{"href":865},"/blog/how-to-improve-lcp/","How to improve LCP",[43,868,869],{},[863,870,872],{"href":871},"/blog/astro-image-optimization/","Astro image optimization",[43,874,875],{},[863,876,878],{"href":877},"/blog/nextjs-core-web-vitals/","Next.js Core Web Vitals",[43,880,881],{},[863,882,884],{"href":883},"/blog/vite-react-performance/","Vite React performance",[32,886,888],{"id":887},"bottom-line","Bottom line",[10,890,891,892,894],{},"For many Next.js sites, ",[20,893,22],{}," is the right first move. For CMS-heavy sites, agencies and ecommerce, an image CDN is usually worth it. For small static sites, a build-time script may be all you need.",[10,896,897],{},"Do not buy a tool before fixing loading priority, responsive sizes and LCP discovery. Those mistakes can wipe out most of the benefit.",[899,900,901],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}",{"title":131,"searchDepth":159,"depth":159,"links":903},[904,905,906,907,908,909,910,911,912,913,914,915,916],{"id":34,"depth":159,"text":35},{"id":72,"depth":159,"text":73},{"id":96,"depth":159,"text":97},{"id":341,"depth":159,"text":342},{"id":448,"depth":159,"text":449},{"id":533,"depth":159,"text":534},{"id":560,"depth":159,"text":561},{"id":587,"depth":159,"text":588},{"id":620,"depth":159,"text":621},{"id":676,"depth":159,"text":677},{"id":843,"depth":159,"text":844},{"id":856,"depth":159,"text":857},{"id":887,"depth":159,"text":888},"A practical guide to Next.js image optimization, React image CDNs, WebP/AVIF, LCP hero images, Cloudinary, ImageKit, Imgix and build-time compression.","md",[920,923,926,929],{"question":921,"answer":922},"What is the best image optimization tool for Next.js?","For most Next.js sites, start with the built-in Image component and make sure your hosting supports the optimization flow. Move to Cloudinary, ImageKit, Imgix or another image CDN when you need shared asset management, transformations, editorial cropping, remote CMS images, or the same image workflow across multiple sites.",{"question":924,"answer":925},"Do image CDNs improve Core Web Vitals?","They can improve LCP when they serve the right image size, format and cache headers close to the user. They will not fix a lazy-loaded hero image, missing dimensions, slow JavaScript rendering, or an image discovered too late in the page.",{"question":927,"answer":928},"Should I use WebP or AVIF?","Use AVIF where it gives a clear size win and the quality still looks right. Use WebP or JPEG fallbacks where needed. The bigger mistake is usually serving the wrong dimensions, not choosing the wrong modern format.",{"question":930,"answer":931},"Why is my LCP image still slow after compression?","Common causes include lazy-loading the hero image, missing preload or fetchpriority, slow TTFB, oversized responsive candidates, render-blocking CSS, third-party scripts, or the image being added only after JavaScript runs.","/og/best-image-optimization-tools-nextjs-react.png","Best image optimization tools for Next.js and React performance",null,{},"/blog/best-image-optimization-tools-nextjs-react","2026-06-12",[939,942,945,948],{"title":940,"url":941},"Next.js Image Optimization","https://nextjs.org/docs/app/getting-started/images",{"title":943,"url":944},"Optimize images","https://web.dev/learn/images/",{"title":946,"url":947},"Largest Contentful Paint","https://web.dev/articles/lcp",{"title":949,"url":950},"AVIF image format","https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types#avif_image",{"title":5,"description":917},"blog/best-image-optimization-tools-nextjs-react",[954,955,956,957,958,959],"image-optimization","next.js","react","lcp","performance","tools","gdH7RtUHHy11sEhtMbXdJ6aboUvKX2Lw4WTwpJfblKU",1783436339751]