{"id":235,"date":"2026-09-22T19:48:56","date_gmt":"2026-09-22T19:48:56","guid":{"rendered":"https:\/\/allmediatools.com\/blog\/developer-checklist-image-optimization\/"},"modified":"2026-09-22T19:48:56","modified_gmt":"2026-09-22T19:48:56","slug":"developer-checklist-image-optimization","status":"publish","type":"post","link":"https:\/\/allmediatools.com\/blog\/developer-checklist-image-optimization\/","title":{"rendered":"A Developer&#8217;s Checklist for Image Optimization and Page Speed"},"content":{"rendered":"\n<p class=\"article-intro wp-block-paragraph\">Images are still the single biggest chunk of most pages&#8217; total weight, and unlike a lot of performance work, fixing them doesn&#8217;t require touching your framework, your build tooling, or your hosting setup. This is the checklist version \u2014 work down it once per project, then again any time a designer drops a fresh batch of hero images into the CMS without thinking about any of this.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">1. Pick the Right Format Before Anything Else<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Format choice is the single highest-leverage decision, made before compression settings even matter.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Format<\/th><th>Use for<\/th><\/tr><\/thead><tbody><tr><td>JPEG<\/td><td>Photos, complex gradients, anything without hard edges or transparency<\/td><\/tr><tr><td>PNG<\/td><td>Logos, icons, screenshots, anything needing true transparency or sharp edges<\/td><\/tr><tr><td>WebP<\/td><td>A solid default replacement for both JPEG and PNG on the modern web \u2014 smaller at equivalent quality, wide browser support<\/td><\/tr><tr><td>SVG<\/td><td>Logos, icons, and any vector graphic \u2014 scales infinitely with a tiny file size<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"\/blog\/webp-vs-jpeg-vs-png\">WebP vs. JPEG vs. PNG<\/a> covers the tradeoffs in more depth, and <a href=\"\/blog\/lossy-vs-lossless-compression\">lossy vs. lossless compression<\/a> explains why some content compresses far better as one type than the other.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Honest gap to flag here:<\/strong> AVIF is a newer format that can beat WebP on file size in some cases, but AllMediaTools&#8217; own format converter doesn&#8217;t currently output AVIF (it handles JPEG, PNG, WebP, GIF, BMP, and TIFF). If AVIF is a hard requirement for your project, that specific conversion step needs a different tool \u2014 <a href=\"\/blog\/what-is-avif-format\">what AVIF is and where it fits<\/a> covers whether it&#8217;s actually worth chasing for your use case.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">2. Compress Before It Ever Reaches Your Repo or CMS<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">An uncompressed image from a design handoff or a stock photo library is routinely 5-10x larger than it needs to be for web display. Run every image through a compressor before it goes into version control or gets uploaded to a CMS \u2014 <a href=\"https:\/\/allmediatools.com\/image-compressor\">AllMediaTools&#8217; image compressor<\/a> handles this in a browser without installing anything, which matters when you want a non-technical teammate to be able to do this step too, not just the dev team.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Don&#8217;t rely on &#8220;the CDN will handle it&#8221; as an excuse to skip this \u2014 a CDN doing on-the-fly optimization is a good second layer, not a reason to commit a 15MB source PNG in the first place.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/allmediatools.com\/image-compressor\">Compress an Image \u2192<\/a><\/div>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">3. Resize to Actual Display Dimensions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A 4000px-wide photo displayed in a 600px-wide card is wasting well over 90% of its pixel data on detail nobody&#8217;s screen will render. Resize (or generate) images at the dimensions they&#8217;re actually displayed at, accounting for the largest breakpoint that image appears at \u2014 not the resolution the source file happened to arrive in.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">4. Serve Responsive Images with srcset and sizes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A single image tag serving one fixed file to every device means mobile users download the same bytes as a 4K desktop monitor. The <code>srcset<\/code>\/<code>sizes<\/code> attributes (or the <code>&lt;picture&gt;<\/code> element for format switching) let the browser choose the right file for its own viewport:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;img\n  src=\"hero-800.jpg\"\n  srcset=\"hero-400.jpg 400w, hero-800.jpg 800w, hero-1600.jpg 1600w\"\n  sizes=\"(max-width: 600px) 100vw, 800px\"\n  alt=\"Descriptive alt text\"\n  width=\"800\" height=\"450\"\n\/&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Generating 2-3 sizes per image is usually enough to capture most of the benefit \u2014 you don&#8217;t need a size for every possible viewport width.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">5. Lazy-Load Offscreen Images<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Native lazy loading needs one attribute and no library:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;img src=\"below-fold.jpg\" loading=\"lazy\" alt=\"...\" \/&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Apply it to anything below the initial viewport. Don&#8217;t apply it to your largest above-the-fold image (usually the hero\/LCP candidate) \u2014 lazy-loading that one actually delays it and hurts your Largest Contentful Paint score instead of helping.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">6. Serve Through a CDN<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A CDN puts images physically closer to the visitor and typically adds automatic format negotiation (serving WebP to browsers that support it, JPEG as a fallback) and on-the-fly resizing based on URL parameters. This is a genuine second layer on top of pre-compressing your source images, not a replacement for it \u2014 a CDN optimizing an already-bloated source file still produces a bigger result than one optimizing a properly-compressed source file.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">7. Reserve Layout Space to Avoid Cumulative Layout Shift<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Always set explicit <code>width<\/code> and <code>height<\/code> attributes (or <code>aspect-ratio<\/code> in CSS) on every image. Without them, the browser doesn&#8217;t know how much vertical space to reserve before the image loads, causing the page to visibly jump as images pop in \u2014 this directly hurts your Cumulative Layout Shift score, one of the three Core Web Vitals.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">8. Automate It in Your Build Pipeline<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Manual optimization works until someone forgets to do it. Where possible, wire compression and resizing into the build or upload pipeline itself \u2014 a build step (imagemin, sharp, a CMS plugin) that runs automatically means the checklist above happens by default instead of by discipline. For teams without that infrastructure yet, a documented manual step (run every new image through <a href=\"https:\/\/allmediatools.com\/image-compressor\">AllMediaTools&#8217; image compressor<\/a> and <a href=\"https:\/\/allmediatools.com\/convert-image-format\">format converter<\/a> before it ships) is a reasonable stopgap.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">9. Measure, Don&#8217;t Guess<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Run Lighthouse or PageSpeed Insights before and after making changes. The specific things to watch:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Metric<\/th><th>What images affect<\/th><\/tr><\/thead><tbody><tr><td>Largest Contentful Paint (LCP)<\/td><td>Directly, if the LCP element is an image (very common on hero-image pages)<\/td><\/tr><tr><td>Cumulative Layout Shift (CLS)<\/td><td>Directly, if images don&#8217;t have reserved dimensions<\/td><\/tr><tr><td>Total page weight<\/td><td>Directly \u2014 images are usually the largest asset category on a typical page<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">The Checklist, All in One Place<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Choose the right format for each image&#8217;s content (photo vs. graphic vs. icon)<\/li>\n\n\n\n<li>Compress every image before it enters your repo or CMS<\/li>\n\n\n\n<li>Resize to the actual display dimensions, not the source resolution<\/li>\n\n\n\n<li>Add srcset\/sizes for responsive delivery<\/li>\n\n\n\n<li>Lazy-load everything below the fold; never lazy-load the LCP candidate<\/li>\n\n\n\n<li>Serve through a CDN with format negotiation if available<\/li>\n\n\n\n<li>Set explicit width\/height or aspect-ratio to prevent layout shift<\/li>\n\n\n\n<li>Automate compression in the build pipeline where possible<\/li>\n\n\n\n<li>Verify the impact with Lighthouse\/PageSpeed Insights, not assumptions<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"\/blog\/image-optimization-complete-guide\">Our complete image optimization guide<\/a> goes deeper into several of these individually if you want more than the checklist version, and <a href=\"\/blog\/dpi-vs-ppi-explained\">DPI vs. PPI<\/a> is worth a read if print-derived assets (DPI-heavy exports from design tools) keep ending up oversized on your site.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Frequently Asked Questions<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What&#8217;s the single highest-impact item on this list if I only have time for one?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Compressing and correctly sizing your images (items 2 and 3) together usually account for the largest share of total savings \u2014 a 4000px, uncompressed source image resized and compressed properly can drop from several megabytes to under 100-200KB with no visible quality change at display size.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Should I lazy-load my hero image?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No. Lazy-loading is for offscreen content; applying it to the image visible on initial page load (often your LCP element) delays its load and actively hurts your Largest Contentful Paint score. Load it eagerly instead.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Is WebP good enough, or do I really need AVIF too?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">WebP alone gets you the vast majority of the available savings over JPEG\/PNG with far simpler tooling and universal current browser support. AVIF can shave off further bytes in some cases but comes with more encoding overhead and less consistent tooling support \u2014 treat it as an optional refinement, not a requirement, unless a specific project mandates it.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Does image optimization actually move the needle on Core Web Vitals, or is it overrated?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">It&#8217;s one of the more reliable levers available, specifically because images are so often the LCP element and such a large share of total page weight on typical content sites. It won&#8217;t fix a fundamentally slow backend or bloated JavaScript bundle, but for image-heavy pages it&#8217;s frequently the highest-leverage fix available.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Do I need a CDN if I&#8217;m already compressing and resizing images properly?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Not strictly required, but it adds real value on top \u2014 geographic proximity to the visitor and automatic format negotiation are things compression alone doesn&#8217;t solve. Think of it as layer two, not a replacement for doing the basics first.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What&#8217;s a reasonable target file size for a typical hero image?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">There&#8217;s no universal number, but for a full-width hero image at reasonable display dimensions (say 1600-2000px wide), landing under 200-300KB after compression is a solid target for most photographic content without visible quality loss.<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>Images are still the single biggest chunk of most pages&#8217; total weight, and unlike a lot of performance work, fixing them doesn&#8217;t require touching your framework, your build tooling, or your hosting setup. This is the checklist version \u2014 work down it once per project, then again any time a designer drops a fresh batch &#8230; <a title=\"A Developer&#8217;s Checklist for Image Optimization and Page Speed\" class=\"read-more\" href=\"https:\/\/allmediatools.com\/blog\/developer-checklist-image-optimization\/\" aria-label=\"Read more about A Developer&#8217;s Checklist for Image Optimization and Page Speed\">Read more<\/a><\/p>\n","protected":false},"author":0,"featured_media":236,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_hide_featured_image":false,"_jetpack_featured_image_duplicate_dismissed":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[505],"tags":[612],"class_list":["post-235","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-image","tag-image-compression"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/allmediatools.com\/blog\/wp-content\/uploads\/2026\/09\/seo-publish-developer-checklist-image-optimization.jpg","_links":{"self":[{"href":"https:\/\/allmediatools.com\/blog\/wp-json\/wp\/v2\/posts\/235","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/allmediatools.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/allmediatools.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/allmediatools.com\/blog\/wp-json\/wp\/v2\/comments?post=235"}],"version-history":[{"count":0,"href":"https:\/\/allmediatools.com\/blog\/wp-json\/wp\/v2\/posts\/235\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/allmediatools.com\/blog\/wp-json\/wp\/v2\/media\/236"}],"wp:attachment":[{"href":"https:\/\/allmediatools.com\/blog\/wp-json\/wp\/v2\/media?parent=235"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/allmediatools.com\/blog\/wp-json\/wp\/v2\/categories?post=235"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/allmediatools.com\/blog\/wp-json\/wp\/v2\/tags?post=235"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}