[{"data":1,"prerenderedAt":66},["Reactive",2],{"blog-post-markdown-image-optimization-compression-complete-guide":3},{"slug":4,"title":5,"description":6,"excerpt":7,"date":8,"category":9,"author":10,"keywords":11,"readingMinutes":12,"html":13,"headings":14,"tools":40,"related":41},"markdown-image-optimization-compression-complete-guide","Markdown Image Optimization and Compression: Complete Guide for Performance and Quality Balance","Master image optimization and compression in Markdown documents. Learn automated compression workflows, responsive image techniques, and performance optimization strategies for fast-loading documentation and web content.","Image optimization and compression in Markdown documents provide essential performance benefits while maintaining visual quality, ensuring fast page load times, reduced bandwidth usage, and…","2025-09-22","Tutorial","Matthew Rathbone","markdown image optimization, image compression markdown, responsive images markdown, markdown performance, image formats, webp markdown, lazy loading, image optimization workflow",16,"\u003Cp>Image optimization and compression in Markdown documents provide essential performance benefits while maintaining visual quality, ensuring fast page load times, reduced bandwidth usage, and improved user experience across devices and network conditions. While Markdown&#39;s simple image syntax enables easy content creation, modern web performance requires sophisticated optimization strategies that balance file size reduction with visual fidelity through automated workflows and responsive delivery systems.\u003C/p>\n\u003Ch2 id=\"why-master-image-optimization-for-markdown\">Why Master Image Optimization for Markdown?\u003C/h2>\n\u003Cp>Professional image optimization provides critical benefits for content performance:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Page Speed Enhancement\u003C/strong>: Optimized images dramatically reduce page load times and improve Core Web Vitals scores\u003C/li>\n\u003Cli>\u003Cstrong>Bandwidth Efficiency\u003C/strong>: Compressed images reduce data usage for users on mobile networks and limited connections\u003C/li>\n\u003Cli>\u003Cstrong>SEO Performance\u003C/strong>: Faster-loading pages with properly optimized images rank higher in search results\u003C/li>\n\u003Cli>\u003Cstrong>User Experience\u003C/strong>: Quick image loading prevents layout shifts and maintains engagement across devices\u003C/li>\n\u003Cli>\u003Cstrong>Storage Cost Reduction\u003C/strong>: Smaller files reduce hosting and CDN costs for content-heavy documentation sites\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"understanding-image-optimization-fundamentals\">Understanding Image Optimization Fundamentals\u003C/h2>\n\u003Ch3 id=\"modern-image-format-selection\">Modern Image Format Selection\u003C/h3>\n\u003Cp>Strategic format selection optimizes file size while maintaining quality across different content types:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-markdown\">\u003Cspan class=\"hljs-section\"># Image Format Decision Matrix\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## JPEG/JPG - Best for Photographs\u003C/span>\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-strong\">**Use Cases**\u003C/span>: Photos, complex images with many colors\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-strong\">**Optimization**\u003C/span>: Quality 85-90% provides excellent balance\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-strong\">**Compression**\u003C/span>: Lossy compression ideal for photographic content\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-strong\">**Browser Support**\u003C/span>: Universal support across all browsers\n\n![\u003Cspan class=\"hljs-string\">Optimized photograph\u003C/span>](\u003Cspan class=\"hljs-link\">images/landscape-optimized.jpg &quot;Professional photograph at 85% quality - 45KB vs 180KB original&quot;\u003C/span>)\n\n\u003Cspan class=\"hljs-section\">## PNG - Best for Graphics and Transparency\u003C/span>\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-strong\">**Use Cases**\u003C/span>: Logos, icons, graphics with transparency\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-strong\">**Optimization**\u003C/span>: PNG-8 for simple graphics, PNG-24 for complex transparency\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-strong\">**Compression**\u003C/span>: Lossless compression preserves exact quality\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-strong\">**Browser Support**\u003C/span>: Universal support with transparency capabilities\n\n![\u003Cspan class=\"hljs-string\">Company logo with transparency\u003C/span>](\u003Cspan class=\"hljs-link\">images/logo-transparent.png &quot;PNG logo with alpha channel - 12KB optimized&quot;\u003C/span>)\n\n\u003Cspan class=\"hljs-section\">## WebP - Best for Modern Performance\u003C/span>\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-strong\">**Use Cases**\u003C/span>: All image types with superior compression\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-strong\">**Optimization**\u003C/span>: 80-90% quality provides 25-50% smaller files than JPEG\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-strong\">**Compression**\u003C/span>: Advanced algorithms with both lossy and lossless options\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-strong\">**Browser Support**\u003C/span>: 95%+ modern browser support with fallbacks needed\n\n![\u003Cspan class=\"hljs-string\">WebP optimized image\u003C/span>](\u003Cspan class=\"hljs-link\">images/hero-banner.webp &quot;WebP format - 30% smaller than JPEG equivalent&quot;\u003C/span>)\n\n\u003Cspan class=\"hljs-section\">## AVIF - Next-Generation Format\u003C/span>\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-strong\">**Use Cases**\u003C/span>: Cutting-edge optimization for modern browsers\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-strong\">**Optimization**\u003C/span>: Superior compression with excellent quality retention\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-strong\">**Compression**\u003C/span>: Up to 50% smaller than WebP with better quality\n\u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-strong\">**Browser Support**\u003C/span>: Growing support, requires comprehensive fallbacks\n\n![\u003Cspan class=\"hljs-string\">AVIF next-generation format\u003C/span>](\u003Cspan class=\"hljs-link\">images/product-showcase.avif &quot;AVIF format - 50% smaller than WebP with same visual quality&quot;\u003C/span>)\n\u003C/code>\u003C/pre>\u003Ch3 id=\"responsive-image-implementation\">Responsive Image Implementation\u003C/h3>\n\u003Cp>Responsive images deliver appropriate sizes for different devices and screen densities:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-html\">\u003Cspan class=\"hljs-comment\">&lt;!-- Progressive Enhancement with Picture Element --&gt;\u003C/span>\n\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">picture\u003C/span>&gt;\u003C/span>\n  \u003Cspan class=\"hljs-comment\">&lt;!-- Next-generation formats for modern browsers --&gt;\u003C/span>\n  \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">source\u003C/span> \n    \u003Cspan class=\"hljs-attr\">srcset\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;images/hero-320.avif 320w,\n            images/hero-640.avif 640w,\n            images/hero-960.avif 960w,\n            images/hero-1280.avif 1280w,\n            images/hero-1920.avif 1920w&quot;\u003C/span>\n    \u003Cspan class=\"hljs-attr\">sizes\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;(max-width: 640px) 100vw,\n           (max-width: 960px) 640px,\n           (max-width: 1280px) 960px,\n           1280px&quot;\u003C/span>\n    \u003Cspan class=\"hljs-attr\">type\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;image/avif&quot;\u003C/span>&gt;\u003C/span>\n  \n  \u003Cspan class=\"hljs-comment\">&lt;!-- WebP fallback for broader support --&gt;\u003C/span>\n  \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">source\u003C/span> \n    \u003Cspan class=\"hljs-attr\">srcset\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;images/hero-320.webp 320w,\n            images/hero-640.webp 640w,\n            images/hero-960.webp 960w,\n            images/hero-1280.webp 1280w,\n            images/hero-1920.webp 1920w&quot;\u003C/span>\n    \u003Cspan class=\"hljs-attr\">sizes\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;(max-width: 640px) 100vw,\n           (max-width: 960px) 640px,\n           (max-width: 1280px) 960px,\n           1280px&quot;\u003C/span>\n    \u003Cspan class=\"hljs-attr\">type\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;image/webp&quot;\u003C/span>&gt;\u003C/span>\n  \n  \u003Cspan class=\"hljs-comment\">&lt;!-- JPEG fallback for maximum compatibility --&gt;\u003C/span>\n  \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">img\u003C/span> \n    \u003Cspan class=\"hljs-attr\">src\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;images/hero-960.jpg&quot;\u003C/span>\n    \u003Cspan class=\"hljs-attr\">srcset\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;images/hero-320.jpg 320w,\n            images/hero-640.jpg 640w,\n            images/hero-960.jpg 960w,\n            images/hero-1280.jpg 1280w,\n            images/hero-1920.jpg 1920w&quot;\u003C/span>\n    \u003Cspan class=\"hljs-attr\">sizes\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;(max-width: 640px) 100vw,\n           (max-width: 960px) 640px,\n           (max-width: 1280px) 960px,\n           1280px&quot;\u003C/span>\n    \u003Cspan class=\"hljs-attr\">alt\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;Hero banner showcasing responsive image optimization&quot;\u003C/span>\n    \u003Cspan class=\"hljs-attr\">loading\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;lazy&quot;\u003C/span>\n    \u003Cspan class=\"hljs-attr\">decoding\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;async&quot;\u003C/span>&gt;\u003C/span>\n\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">picture\u003C/span>&gt;\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch2 id=\"automated-optimization-workflows\">Automated Optimization Workflows\u003C/h2>\n\u003Ch3 id=\"command-line-image-processing\">Command-Line Image Processing\u003C/h3>\n\u003Cp>Streamlined command-line tools enable batch optimization for content workflows:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-bash\">\u003Cspan class=\"hljs-meta\">#!/bin/bash\u003C/span>\n\u003Cspan class=\"hljs-comment\"># image-optimization.sh - Comprehensive image optimization script\u003C/span>\n\n\u003Cspan class=\"hljs-comment\"># Create optimized image directories\u003C/span>\n\u003Cspan class=\"hljs-built_in\">mkdir\u003C/span> -p images/optimized/{webp,avif,jpeg}\n\u003Cspan class=\"hljs-built_in\">mkdir\u003C/span> -p images/responsive/{320,640,960,1280,1920}\n\n\u003Cspan class=\"hljs-comment\"># Function to optimize JPEG images\u003C/span>\n\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-title\">optimize_jpeg\u003C/span>\u003C/span>() {\n    \u003Cspan class=\"hljs-built_in\">local\u003C/span> input_file=\u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$1\u003C/span>&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">local\u003C/span> output_file=\u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$2\u003C/span>&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">local\u003C/span> quality=\u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">${3:-85}\u003C/span>&quot;\u003C/span>\n    \n    \u003Cspan class=\"hljs-comment\"># Use ImageMagick for JPEG optimization\u003C/span>\n    magick \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$input_file\u003C/span>&quot;\u003C/span> \\\n        -quality \u003Cspan class=\"hljs-variable\">$quality\u003C/span> \\\n        -sampling-factor 4:2:0 \\\n        -strip \\\n        -interlace Plane \\\n        \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$output_file\u003C/span>&quot;\u003C/span>\n}\n\n\u003Cspan class=\"hljs-comment\"># Function to generate WebP images\u003C/span>\n\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-title\">generate_webp\u003C/span>\u003C/span>() {\n    \u003Cspan class=\"hljs-built_in\">local\u003C/span> input_file=\u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$1\u003C/span>&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">local\u003C/span> output_file=\u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$2\u003C/span>&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">local\u003C/span> quality=\u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">${3:-80}\u003C/span>&quot;\u003C/span>\n    \n    \u003Cspan class=\"hljs-comment\"># Use cwebp for WebP generation\u003C/span>\n    cwebp -q \u003Cspan class=\"hljs-variable\">$quality\u003C/span> \\\n        -m 6 \\\n        -pass 10 \\\n        -mt \\\n        -crop 0 0 0 0 \\\n        \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$input_file\u003C/span>&quot;\u003C/span> \\\n        -o \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$output_file\u003C/span>&quot;\u003C/span>\n}\n\n\u003Cspan class=\"hljs-comment\"># Function to generate AVIF images\u003C/span>\n\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-title\">generate_avif\u003C/span>\u003C/span>() {\n    \u003Cspan class=\"hljs-built_in\">local\u003C/span> input_file=\u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$1\u003C/span>&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">local\u003C/span> output_file=\u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$2\u003C/span>&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">local\u003C/span> quality=\u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">${3:-50}\u003C/span>&quot;\u003C/span>\n    \n    \u003Cspan class=\"hljs-comment\"># Use avifenc for AVIF generation\u003C/span>\n    avifenc --min \u003Cspan class=\"hljs-variable\">$quality\u003C/span> --max \u003Cspan class=\"hljs-variable\">$quality\u003C/span> \\\n        --speed 6 \\\n        --\u003Cspan class=\"hljs-built_in\">jobs\u003C/span> all \\\n        \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$input_file\u003C/span>&quot;\u003C/span> \\\n        \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$output_file\u003C/span>&quot;\u003C/span>\n}\n\n\u003Cspan class=\"hljs-comment\"># Function to generate responsive sizes\u003C/span>\n\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-title\">generate_responsive_sizes\u003C/span>\u003C/span>() {\n    \u003Cspan class=\"hljs-built_in\">local\u003C/span> input_file=\u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$1\u003C/span>&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">local\u003C/span> base_name=$(\u003Cspan class=\"hljs-built_in\">basename\u003C/span> \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$input_file\u003C/span>&quot;\u003C/span> .jpg)\n    \n    \u003Cspan class=\"hljs-comment\"># Generate different sizes\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">local\u003C/span> sizes=(320 640 960 1280 1920)\n    \n    \u003Cspan class=\"hljs-keyword\">for\u003C/span> size \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">${sizes[@]}\u003C/span>&quot;\u003C/span>; \u003Cspan class=\"hljs-keyword\">do\u003C/span>\n        \u003Cspan class=\"hljs-comment\"># JPEG versions\u003C/span>\n        magick \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$input_file\u003C/span>&quot;\u003C/span> \\\n            -resize \u003Cspan class=\"hljs-variable\">${size}\u003C/span>x\u003Cspan class=\"hljs-variable\">${size}\u003C/span>\\&gt; \\\n            -quality 85 \\\n            -strip \\\n            \u003Cspan class=\"hljs-string\">&quot;images/responsive/\u003Cspan class=\"hljs-variable\">${size}\u003C/span>/\u003Cspan class=\"hljs-variable\">${base_name}\u003C/span>-\u003Cspan class=\"hljs-variable\">${size}\u003C/span>.jpg&quot;\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># WebP versions\u003C/span>\n        magick \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$input_file\u003C/span>&quot;\u003C/span> \\\n            -resize \u003Cspan class=\"hljs-variable\">${size}\u003C/span>x\u003Cspan class=\"hljs-variable\">${size}\u003C/span>\\&gt; \\\n            -quality 80 \\\n            -strip \\\n            \u003Cspan class=\"hljs-string\">&quot;images/responsive/\u003Cspan class=\"hljs-variable\">${size}\u003C/span>/\u003Cspan class=\"hljs-variable\">${base_name}\u003C/span>-\u003Cspan class=\"hljs-variable\">${size}\u003C/span>.webp&quot;\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># AVIF versions (if avifenc available)\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">command\u003C/span> -v avifenc &amp;&gt; /dev/null; \u003Cspan class=\"hljs-keyword\">then\u003C/span>\n            magick \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$input_file\u003C/span>&quot;\u003C/span> \\\n                -resize \u003Cspan class=\"hljs-variable\">${size}\u003C/span>x\u003Cspan class=\"hljs-variable\">${size}\u003C/span>\\&gt; \\\n                -strip \\\n                \u003Cspan class=\"hljs-string\">&quot;temp-\u003Cspan class=\"hljs-variable\">${size}\u003C/span>.png&quot;\u003C/span>\n            \n            avifenc --min 50 --max 50 \\\n                --speed 6 \\\n                \u003Cspan class=\"hljs-string\">&quot;temp-\u003Cspan class=\"hljs-variable\">${size}\u003C/span>.png&quot;\u003C/span> \\\n                \u003Cspan class=\"hljs-string\">&quot;images/responsive/\u003Cspan class=\"hljs-variable\">${size}\u003C/span>/\u003Cspan class=\"hljs-variable\">${base_name}\u003C/span>-\u003Cspan class=\"hljs-variable\">${size}\u003C/span>.avif&quot;\u003C/span>\n            \n            \u003Cspan class=\"hljs-built_in\">rm\u003C/span> \u003Cspan class=\"hljs-string\">&quot;temp-\u003Cspan class=\"hljs-variable\">${size}\u003C/span>.png&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">done\u003C/span>\n}\n\n\u003Cspan class=\"hljs-comment\"># Process all images in source directory\u003C/span>\n\u003Cspan class=\"hljs-keyword\">for\u003C/span> image \u003Cspan class=\"hljs-keyword\">in\u003C/span> images/source/*.{jpg,jpeg,png}; \u003Cspan class=\"hljs-keyword\">do\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> [[ -f \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$image\u003C/span>&quot;\u003C/span> ]]; \u003Cspan class=\"hljs-keyword\">then\u003C/span>\n        filename=$(\u003Cspan class=\"hljs-built_in\">basename\u003C/span> \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$image\u003C/span>&quot;\u003C/span>)\n        name=\u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">${filename%.*}\u003C/span>&quot;\u003C/span>\n        extension=\u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">${filename##*.}\u003C/span>&quot;\u003C/span>\n        \n        \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Processing: \u003Cspan class=\"hljs-variable\">$filename\u003C/span>&quot;\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Generate optimized versions\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">case\u003C/span> \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$extension\u003C/span>&quot;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span>\n            jpg|jpeg)\n                optimize_jpeg \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$image\u003C/span>&quot;\u003C/span> \u003Cspan class=\"hljs-string\">&quot;images/optimized/jpeg/\u003Cspan class=\"hljs-variable\">${name}\u003C/span>.jpg&quot;\u003C/span> 85\n                generate_webp \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$image\u003C/span>&quot;\u003C/span> \u003Cspan class=\"hljs-string\">&quot;images/optimized/webp/\u003Cspan class=\"hljs-variable\">${name}\u003C/span>.webp&quot;\u003C/span> 80\n                generate_avif \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$image\u003C/span>&quot;\u003C/span> \u003Cspan class=\"hljs-string\">&quot;images/optimized/avif/\u003Cspan class=\"hljs-variable\">${name}\u003C/span>.avif&quot;\u003C/span> 50\n                generate_responsive_sizes \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$image\u003C/span>&quot;\u003C/span>\n                ;;\n            png)\n                \u003Cspan class=\"hljs-comment\"># PNG optimization with pngquant\u003C/span>\n                pngquant --quality=65-80 --ext .png --force \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$image\u003C/span>&quot;\u003C/span>\n                \u003Cspan class=\"hljs-built_in\">mv\u003C/span> \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$image\u003C/span>&quot;\u003C/span> \u003Cspan class=\"hljs-string\">&quot;images/optimized/jpeg/\u003Cspan class=\"hljs-variable\">${name}\u003C/span>.png&quot;\u003C/span>\n                \n                \u003Cspan class=\"hljs-comment\"># Convert PNG to WebP and AVIF\u003C/span>\n                generate_webp \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$image\u003C/span>&quot;\u003C/span> \u003Cspan class=\"hljs-string\">&quot;images/optimized/webp/\u003Cspan class=\"hljs-variable\">${name}\u003C/span>.webp&quot;\u003C/span> 80\n                generate_avif \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$image\u003C/span>&quot;\u003C/span> \u003Cspan class=\"hljs-string\">&quot;images/optimized/avif/\u003Cspan class=\"hljs-variable\">${name}\u003C/span>.avif&quot;\u003C/span> 50\n                ;;\n        \u003Cspan class=\"hljs-keyword\">esac\u003C/span>\n        \n        \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;✓ Completed: \u003Cspan class=\"hljs-variable\">$filename\u003C/span>&quot;\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n\u003Cspan class=\"hljs-keyword\">done\u003C/span>\n\n\u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Image optimization complete!&quot;\u003C/span>\n\n\u003Cspan class=\"hljs-comment\"># Generate optimization report\u003C/span>\n\u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Optimization Summary:&quot;\u003C/span> &gt; optimization-report.txt\n\u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;===================&quot;\u003C/span> &gt;&gt; optimization-report.txt\noriginal_size=$(\u003Cspan class=\"hljs-built_in\">du\u003C/span> -sh images/source | \u003Cspan class=\"hljs-built_in\">cut\u003C/span> -f1)\noptimized_size=$(\u003Cspan class=\"hljs-built_in\">du\u003C/span> -sh images/optimized | \u003Cspan class=\"hljs-built_in\">cut\u003C/span> -f1)\nresponsive_size=$(\u003Cspan class=\"hljs-built_in\">du\u003C/span> -sh images/responsive | \u003Cspan class=\"hljs-built_in\">cut\u003C/span> -f1)\n\n\u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Original images: \u003Cspan class=\"hljs-variable\">$original_size\u003C/span>&quot;\u003C/span> &gt;&gt; optimization-report.txt\n\u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Optimized images: \u003Cspan class=\"hljs-variable\">$optimized_size\u003C/span>&quot;\u003C/span> &gt;&gt; optimization-report.txt  \n\u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Responsive images: \u003Cspan class=\"hljs-variable\">$responsive_size\u003C/span>&quot;\u003C/span> &gt;&gt; optimization-report.txt\n\u003C/code>\u003C/pre>\u003Ch3 id=\"nodejs-optimization-pipeline\">Node.js Optimization Pipeline\u003C/h3>\n\u003Cp>Advanced JavaScript-based optimization for development workflows:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-javascript\">\u003Cspan class=\"hljs-comment\">// image-optimizer.js - Advanced Node.js image optimization\u003C/span>\n\u003Cspan class=\"hljs-keyword\">const\u003C/span> sharp = \u003Cspan class=\"hljs-built_in\">require\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;sharp&#x27;\u003C/span>);\n\u003Cspan class=\"hljs-keyword\">const\u003C/span> fs = \u003Cspan class=\"hljs-built_in\">require\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;fs&#x27;\u003C/span>).\u003Cspan class=\"hljs-property\">promises\u003C/span>;\n\u003Cspan class=\"hljs-keyword\">const\u003C/span> path = \u003Cspan class=\"hljs-built_in\">require\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;path&#x27;\u003C/span>);\n\u003Cspan class=\"hljs-keyword\">const\u003C/span> glob = \u003Cspan class=\"hljs-built_in\">require\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;glob&#x27;\u003C/span>);\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">ImageOptimizer\u003C/span> {\n    \u003Cspan class=\"hljs-title function_\">constructor\u003C/span>(\u003Cspan class=\"hljs-params\">options = {}\u003C/span>) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">inputDir\u003C/span> = options.\u003Cspan class=\"hljs-property\">inputDir\u003C/span> || \u003Cspan class=\"hljs-string\">&#x27;images/source&#x27;\u003C/span>;\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">outputDir\u003C/span> = options.\u003Cspan class=\"hljs-property\">outputDir\u003C/span> || \u003Cspan class=\"hljs-string\">&#x27;images/optimized&#x27;\u003C/span>;\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">formats\u003C/span> = options.\u003Cspan class=\"hljs-property\">formats\u003C/span> || [\u003Cspan class=\"hljs-string\">&#x27;webp&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;avif&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;jpeg&#x27;\u003C/span>];\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sizes\u003C/span> = options.\u003Cspan class=\"hljs-property\">sizes\u003C/span> || [\u003Cspan class=\"hljs-number\">320\u003C/span>, \u003Cspan class=\"hljs-number\">640\u003C/span>, \u003Cspan class=\"hljs-number\">960\u003C/span>, \u003Cspan class=\"hljs-number\">1280\u003C/span>, \u003Cspan class=\"hljs-number\">1920\u003C/span>];\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">quality\u003C/span> = {\n            \u003Cspan class=\"hljs-attr\">jpeg\u003C/span>: options.\u003Cspan class=\"hljs-property\">jpegQuality\u003C/span> || \u003Cspan class=\"hljs-number\">85\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">webp\u003C/span>: options.\u003Cspan class=\"hljs-property\">webpQuality\u003C/span> || \u003Cspan class=\"hljs-number\">80\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">avif\u003C/span>: options.\u003Cspan class=\"hljs-property\">avifQuality\u003C/span> || \u003Cspan class=\"hljs-number\">50\u003C/span>\n        };\n        \n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">stats\u003C/span> = {\n            \u003Cspan class=\"hljs-attr\">processed\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">originalSize\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">optimizedSize\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">savedBytes\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>\n        };\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">init\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-comment\">// Create output directories\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">createDirectories\u003C/span>();\n        \n        \u003Cspan class=\"hljs-comment\">// Process all images\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> imageFiles = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">getImageFiles\u003C/span>();\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> (\u003Cspan class=\"hljs-keyword\">const\u003C/span> filePath \u003Cspan class=\"hljs-keyword\">of\u003C/span> imageFiles) {\n            \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">processImage\u003C/span>(filePath);\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Generate optimization report\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">generateReport\u003C/span>();\n        \n        \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">`✓ Processed \u003Cspan class=\"hljs-subst\">${\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.stats.processed}\u003C/span> images`\u003C/span>);\n        \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">`💾 Saved \u003Cspan class=\"hljs-subst\">${\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.formatBytes(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.stats.savedBytes)}\u003C/span> (\u003Cspan class=\"hljs-subst\">${\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.getSavingsPercentage()}\u003C/span>%)`\u003C/span>);\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">createDirectories\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> dirs = [\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">outputDir\u003C/span>,\n            ...\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">formats\u003C/span>.\u003Cspan class=\"hljs-title function_\">map\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">format\u003C/span> =&gt;\u003C/span> path.\u003Cspan class=\"hljs-title function_\">join\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">outputDir\u003C/span>, format)),\n            ...\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sizes\u003C/span>.\u003Cspan class=\"hljs-title function_\">map\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">size\u003C/span> =&gt;\u003C/span> path.\u003Cspan class=\"hljs-title function_\">join\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">outputDir\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;responsive&#x27;\u003C/span>, size.\u003Cspan class=\"hljs-title function_\">toString\u003C/span>()))\n        ];\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> (\u003Cspan class=\"hljs-keyword\">const\u003C/span> dir \u003Cspan class=\"hljs-keyword\">of\u003C/span> dirs) {\n            \u003Cspan class=\"hljs-keyword\">await\u003C/span> fs.\u003Cspan class=\"hljs-title function_\">mkdir\u003C/span>(dir, { \u003Cspan class=\"hljs-attr\">recursive\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span> });\n        }\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">getImageFiles\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Promise\u003C/span>(\u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">resolve, reject\u003C/span>) =&gt;\u003C/span> {\n            \u003Cspan class=\"hljs-title function_\">glob\u003C/span>(path.\u003Cspan class=\"hljs-title function_\">join\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">inputDir\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;**/*.{jpg,jpeg,png,gif}&#x27;\u003C/span>), \u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">err, files\u003C/span>) =&gt;\u003C/span> {\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> (err) \u003Cspan class=\"hljs-title function_\">reject\u003C/span>(err);\n                \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-title function_\">resolve\u003C/span>(files);\n            });\n        });\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">processImage\u003C/span>(\u003Cspan class=\"hljs-params\">filePath\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> filename = path.\u003Cspan class=\"hljs-title function_\">basename\u003C/span>(filePath, path.\u003Cspan class=\"hljs-title function_\">extname\u003C/span>(filePath));\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> originalStats = \u003Cspan class=\"hljs-keyword\">await\u003C/span> fs.\u003Cspan class=\"hljs-title function_\">stat\u003C/span>(filePath);\n        \n        \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">`Processing: \u003Cspan class=\"hljs-subst\">${path.basename(filePath)}\u003C/span>`\u003C/span>);\n        \n        \u003Cspan class=\"hljs-comment\">// Get image metadata\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> image = \u003Cspan class=\"hljs-title function_\">sharp\u003C/span>(filePath);\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> metadata = \u003Cspan class=\"hljs-keyword\">await\u003C/span> image.\u003Cspan class=\"hljs-title function_\">metadata\u003C/span>();\n        \n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">stats\u003C/span>.\u003Cspan class=\"hljs-property\">originalSize\u003C/span> += originalStats.\u003Cspan class=\"hljs-property\">size\u003C/span>;\n        \n        \u003Cspan class=\"hljs-comment\">// Generate different formats\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title class_\">Promise\u003C/span>.\u003Cspan class=\"hljs-title function_\">all\u003C/span>([\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">generateFormats\u003C/span>(image, filename, metadata),\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">generateResponsiveSizes\u003C/span>(image, filename)\n        ]);\n        \n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">stats\u003C/span>.\u003Cspan class=\"hljs-property\">processed\u003C/span>++;\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">generateFormats\u003C/span>(\u003Cspan class=\"hljs-params\">image, filename, metadata\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> formatPromises = [];\n        \n        \u003Cspan class=\"hljs-comment\">// JPEG optimization\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">formats\u003C/span>.\u003Cspan class=\"hljs-title function_\">includes\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;jpeg&#x27;\u003C/span>)) {\n            formatPromises.\u003Cspan class=\"hljs-title function_\">push\u003C/span>(\n                \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">optimizeJPEG\u003C/span>(image, filename)\n            );\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// WebP generation\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">formats\u003C/span>.\u003Cspan class=\"hljs-title function_\">includes\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;webp&#x27;\u003C/span>)) {\n            formatPromises.\u003Cspan class=\"hljs-title function_\">push\u003C/span>(\n                \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">generateWebP\u003C/span>(image, filename)\n            );\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// AVIF generation\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">formats\u003C/span>.\u003Cspan class=\"hljs-title function_\">includes\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;avif&#x27;\u003C/span>)) {\n            formatPromises.\u003Cspan class=\"hljs-title function_\">push\u003C/span>(\n                \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">generateAVIF\u003C/span>(image, filename)\n            );\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title class_\">Promise\u003C/span>.\u003Cspan class=\"hljs-title function_\">all\u003C/span>(formatPromises);\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">optimizeJPEG\u003C/span>(\u003Cspan class=\"hljs-params\">image, filename\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> outputPath = path.\u003Cspan class=\"hljs-title function_\">join\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">outputDir\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;jpeg&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">`\u003Cspan class=\"hljs-subst\">${filename}\u003C/span>.jpg`\u003C/span>);\n        \n        \u003Cspan class=\"hljs-keyword\">await\u003C/span> image\n            .\u003Cspan class=\"hljs-title function_\">jpeg\u003C/span>({\n                \u003Cspan class=\"hljs-attr\">quality\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">quality\u003C/span>.\u003Cspan class=\"hljs-property\">jpeg\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">progressive\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">mozjpeg\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span>\n            })\n            .\u003Cspan class=\"hljs-title function_\">toFile\u003C/span>(outputPath);\n        \n        \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">updateStats\u003C/span>(outputPath);\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">generateWebP\u003C/span>(\u003Cspan class=\"hljs-params\">image, filename\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> outputPath = path.\u003Cspan class=\"hljs-title function_\">join\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">outputDir\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;webp&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">`\u003Cspan class=\"hljs-subst\">${filename}\u003C/span>.webp`\u003C/span>);\n        \n        \u003Cspan class=\"hljs-keyword\">await\u003C/span> image\n            .\u003Cspan class=\"hljs-title function_\">webp\u003C/span>({\n                \u003Cspan class=\"hljs-attr\">quality\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">quality\u003C/span>.\u003Cspan class=\"hljs-property\">webp\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">effort\u003C/span>: \u003Cspan class=\"hljs-number\">6\u003C/span>\n            })\n            .\u003Cspan class=\"hljs-title function_\">toFile\u003C/span>(outputPath);\n        \n        \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">updateStats\u003C/span>(outputPath);\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">generateAVIF\u003C/span>(\u003Cspan class=\"hljs-params\">image, filename\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> outputPath = path.\u003Cspan class=\"hljs-title function_\">join\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">outputDir\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;avif&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">`\u003Cspan class=\"hljs-subst\">${filename}\u003C/span>.avif`\u003C/span>);\n        \n        \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n            \u003Cspan class=\"hljs-keyword\">await\u003C/span> image\n                .\u003Cspan class=\"hljs-title function_\">avif\u003C/span>({\n                    \u003Cspan class=\"hljs-attr\">quality\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">quality\u003C/span>.\u003Cspan class=\"hljs-property\">avif\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">effort\u003C/span>: \u003Cspan class=\"hljs-number\">9\u003C/span>\n                })\n                .\u003Cspan class=\"hljs-title function_\">toFile\u003C/span>(outputPath);\n            \n            \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">updateStats\u003C/span>(outputPath);\n        } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n            \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">warn\u003C/span>(\u003Cspan class=\"hljs-string\">`AVIF generation failed for \u003Cspan class=\"hljs-subst\">${filename}\u003C/span>: \u003Cspan class=\"hljs-subst\">${error.message}\u003C/span>`\u003C/span>);\n        }\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">generateResponsiveSizes\u003C/span>(\u003Cspan class=\"hljs-params\">image, filename\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> sizePromises = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sizes\u003C/span>.\u003Cspan class=\"hljs-title function_\">map\u003C/span>(\u003Cspan class=\"hljs-keyword\">async\u003C/span> (size) =&gt; {\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> resizedImage = image.\u003Cspan class=\"hljs-title function_\">clone\u003C/span>().\u003Cspan class=\"hljs-title function_\">resize\u003C/span>(size, size, {\n                \u003Cspan class=\"hljs-attr\">fit\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;inside&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">withoutEnlargement\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span>\n            });\n            \n            \u003Cspan class=\"hljs-comment\">// Generate all formats for this size\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> formatPromises = [];\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">formats\u003C/span>.\u003Cspan class=\"hljs-title function_\">includes\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;jpeg&#x27;\u003C/span>)) {\n                \u003Cspan class=\"hljs-keyword\">const\u003C/span> jpegPath = path.\u003Cspan class=\"hljs-title function_\">join\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">outputDir\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;responsive&#x27;\u003C/span>, size.\u003Cspan class=\"hljs-title function_\">toString\u003C/span>(), \u003Cspan class=\"hljs-string\">`\u003Cspan class=\"hljs-subst\">${filename}\u003C/span>-\u003Cspan class=\"hljs-subst\">${size}\u003C/span>.jpg`\u003C/span>);\n                formatPromises.\u003Cspan class=\"hljs-title function_\">push\u003C/span>(\n                    resizedImage.\u003Cspan class=\"hljs-title function_\">clone\u003C/span>().\u003Cspan class=\"hljs-title function_\">jpeg\u003C/span>({\n                        \u003Cspan class=\"hljs-attr\">quality\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">quality\u003C/span>.\u003Cspan class=\"hljs-property\">jpeg\u003C/span>,\n                        \u003Cspan class=\"hljs-attr\">progressive\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span>\n                    }).\u003Cspan class=\"hljs-title function_\">toFile\u003C/span>(jpegPath)\n                );\n            }\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">formats\u003C/span>.\u003Cspan class=\"hljs-title function_\">includes\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;webp&#x27;\u003C/span>)) {\n                \u003Cspan class=\"hljs-keyword\">const\u003C/span> webpPath = path.\u003Cspan class=\"hljs-title function_\">join\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">outputDir\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;responsive&#x27;\u003C/span>, size.\u003Cspan class=\"hljs-title function_\">toString\u003C/span>(), \u003Cspan class=\"hljs-string\">`\u003Cspan class=\"hljs-subst\">${filename}\u003C/span>-\u003Cspan class=\"hljs-subst\">${size}\u003C/span>.webp`\u003C/span>);\n                formatPromises.\u003Cspan class=\"hljs-title function_\">push\u003C/span>(\n                    resizedImage.\u003Cspan class=\"hljs-title function_\">clone\u003C/span>().\u003Cspan class=\"hljs-title function_\">webp\u003C/span>({\n                        \u003Cspan class=\"hljs-attr\">quality\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">quality\u003C/span>.\u003Cspan class=\"hljs-property\">webp\u003C/span>,\n                        \u003Cspan class=\"hljs-attr\">effort\u003C/span>: \u003Cspan class=\"hljs-number\">6\u003C/span>\n                    }).\u003Cspan class=\"hljs-title function_\">toFile\u003C/span>(webpPath)\n                );\n            }\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">formats\u003C/span>.\u003Cspan class=\"hljs-title function_\">includes\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;avif&#x27;\u003C/span>)) {\n                \u003Cspan class=\"hljs-keyword\">const\u003C/span> avifPath = path.\u003Cspan class=\"hljs-title function_\">join\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">outputDir\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;responsive&#x27;\u003C/span>, size.\u003Cspan class=\"hljs-title function_\">toString\u003C/span>(), \u003Cspan class=\"hljs-string\">`\u003Cspan class=\"hljs-subst\">${filename}\u003C/span>-\u003Cspan class=\"hljs-subst\">${size}\u003C/span>.avif`\u003C/span>);\n                formatPromises.\u003Cspan class=\"hljs-title function_\">push\u003C/span>(\n                    resizedImage.\u003Cspan class=\"hljs-title function_\">clone\u003C/span>().\u003Cspan class=\"hljs-title function_\">avif\u003C/span>({\n                        \u003Cspan class=\"hljs-attr\">quality\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">quality\u003C/span>.\u003Cspan class=\"hljs-property\">avif\u003C/span>,\n                        \u003Cspan class=\"hljs-attr\">effort\u003C/span>: \u003Cspan class=\"hljs-number\">9\u003C/span>\n                    }).\u003Cspan class=\"hljs-title function_\">toFile\u003C/span>(avifPath).\u003Cspan class=\"hljs-title function_\">catch\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">err\u003C/span> =&gt;\u003C/span> {\n                        \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">warn\u003C/span>(\u003Cspan class=\"hljs-string\">`AVIF generation failed for \u003Cspan class=\"hljs-subst\">${filename}\u003C/span>-\u003Cspan class=\"hljs-subst\">${size}\u003C/span>: \u003Cspan class=\"hljs-subst\">${err.message}\u003C/span>`\u003C/span>);\n                    })\n                );\n            }\n            \n            \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title class_\">Promise\u003C/span>.\u003Cspan class=\"hljs-title function_\">all\u003C/span>(formatPromises);\n        });\n        \n        \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title class_\">Promise\u003C/span>.\u003Cspan class=\"hljs-title function_\">all\u003C/span>(sizePromises);\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">updateStats\u003C/span>(\u003Cspan class=\"hljs-params\">filePath\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> stats = \u003Cspan class=\"hljs-keyword\">await\u003C/span> fs.\u003Cspan class=\"hljs-title function_\">stat\u003C/span>(filePath);\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">stats\u003C/span>.\u003Cspan class=\"hljs-property\">optimizedSize\u003C/span> += stats.\u003Cspan class=\"hljs-property\">size\u003C/span>;\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">getSavingsPercentage\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">stats\u003C/span>.\u003Cspan class=\"hljs-property\">originalSize\u003C/span> === \u003Cspan class=\"hljs-number\">0\u003C/span>) \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span>;\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">stats\u003C/span>.\u003Cspan class=\"hljs-property\">savedBytes\u003C/span> = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">stats\u003C/span>.\u003Cspan class=\"hljs-property\">originalSize\u003C/span> - \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">stats\u003C/span>.\u003Cspan class=\"hljs-property\">optimizedSize\u003C/span>;\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-title class_\">Math\u003C/span>.\u003Cspan class=\"hljs-title function_\">round\u003C/span>((\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">stats\u003C/span>.\u003Cspan class=\"hljs-property\">savedBytes\u003C/span> / \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">stats\u003C/span>.\u003Cspan class=\"hljs-property\">originalSize\u003C/span>) * \u003Cspan class=\"hljs-number\">100\u003C/span>);\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">formatBytes\u003C/span>(\u003Cspan class=\"hljs-params\">bytes\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (bytes === \u003Cspan class=\"hljs-number\">0\u003C/span>) \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;0 Bytes&#x27;\u003C/span>;\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> k = \u003Cspan class=\"hljs-number\">1024\u003C/span>;\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> sizes = [\u003Cspan class=\"hljs-string\">&#x27;Bytes&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;KB&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;MB&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;GB&#x27;\u003C/span>];\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> i = \u003Cspan class=\"hljs-title class_\">Math\u003C/span>.\u003Cspan class=\"hljs-title function_\">floor\u003C/span>(\u003Cspan class=\"hljs-title class_\">Math\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(bytes) / \u003Cspan class=\"hljs-title class_\">Math\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(k));\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-built_in\">parseFloat\u003C/span>((bytes / \u003Cspan class=\"hljs-title class_\">Math\u003C/span>.\u003Cspan class=\"hljs-title function_\">pow\u003C/span>(k, i)).\u003Cspan class=\"hljs-title function_\">toFixed\u003C/span>(\u003Cspan class=\"hljs-number\">2\u003C/span>)) + \u003Cspan class=\"hljs-string\">&#x27; &#x27;\u003C/span> + sizes[i];\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">generateReport\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> report = {\n            \u003Cspan class=\"hljs-attr\">timestamp\u003C/span>: \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Date\u003C/span>().\u003Cspan class=\"hljs-title function_\">toISOString\u003C/span>(),\n            \u003Cspan class=\"hljs-attr\">summary\u003C/span>: {\n                \u003Cspan class=\"hljs-attr\">filesProcessed\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">stats\u003C/span>.\u003Cspan class=\"hljs-property\">processed\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">originalSize\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">formatBytes\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">stats\u003C/span>.\u003Cspan class=\"hljs-property\">originalSize\u003C/span>),\n                \u003Cspan class=\"hljs-attr\">optimizedSize\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">formatBytes\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">stats\u003C/span>.\u003Cspan class=\"hljs-property\">optimizedSize\u003C/span>),\n                \u003Cspan class=\"hljs-attr\">savedBytes\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">formatBytes\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">stats\u003C/span>.\u003Cspan class=\"hljs-property\">savedBytes\u003C/span>),\n                \u003Cspan class=\"hljs-attr\">savingsPercentage\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">getSavingsPercentage\u003C/span>() + \u003Cspan class=\"hljs-string\">&#x27;%&#x27;\u003C/span>\n            },\n            \u003Cspan class=\"hljs-attr\">configuration\u003C/span>: {\n                \u003Cspan class=\"hljs-attr\">formats\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">formats\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">sizes\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">sizes\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">quality\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">quality\u003C/span>\n            }\n        };\n        \n        \u003Cspan class=\"hljs-keyword\">await\u003C/span> fs.\u003Cspan class=\"hljs-title function_\">writeFile\u003C/span>(\n            path.\u003Cspan class=\"hljs-title function_\">join\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">outputDir\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;optimization-report.json&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-title class_\">JSON\u003C/span>.\u003Cspan class=\"hljs-title function_\">stringify\u003C/span>(report, \u003Cspan class=\"hljs-literal\">null\u003C/span>, \u003Cspan class=\"hljs-number\">2\u003C/span>)\n        );\n    }\n}\n\n\u003Cspan class=\"hljs-comment\">// Usage example\u003C/span>\n\u003Cspan class=\"hljs-keyword\">const\u003C/span> optimizer = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">ImageOptimizer\u003C/span>({\n    \u003Cspan class=\"hljs-attr\">inputDir\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;images/source&#x27;\u003C/span>,\n    \u003Cspan class=\"hljs-attr\">outputDir\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;images/optimized&#x27;\u003C/span>,\n    \u003Cspan class=\"hljs-attr\">formats\u003C/span>: [\u003Cspan class=\"hljs-string\">&#x27;jpeg&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;webp&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;avif&#x27;\u003C/span>],\n    \u003Cspan class=\"hljs-attr\">sizes\u003C/span>: [\u003Cspan class=\"hljs-number\">320\u003C/span>, \u003Cspan class=\"hljs-number\">640\u003C/span>, \u003Cspan class=\"hljs-number\">960\u003C/span>, \u003Cspan class=\"hljs-number\">1280\u003C/span>, \u003Cspan class=\"hljs-number\">1920\u003C/span>],\n    \u003Cspan class=\"hljs-attr\">jpegQuality\u003C/span>: \u003Cspan class=\"hljs-number\">85\u003C/span>,\n    \u003Cspan class=\"hljs-attr\">webpQuality\u003C/span>: \u003Cspan class=\"hljs-number\">80\u003C/span>,\n    \u003Cspan class=\"hljs-attr\">avifQuality\u003C/span>: \u003Cspan class=\"hljs-number\">50\u003C/span>\n});\n\noptimizer.\u003Cspan class=\"hljs-title function_\">init\u003C/span>().\u003Cspan class=\"hljs-title function_\">catch\u003C/span>(\u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-property\">error\u003C/span>);\n\u003C/code>\u003C/pre>\u003Ch2 id=\"jekyll-and-hugo-integration\">Jekyll and Hugo Integration\u003C/h2>\n\u003Ch3 id=\"jekyll-image-optimization-plugin\">Jekyll Image Optimization Plugin\u003C/h3>\n\u003Cp>Automated optimization integrated with Jekyll build process:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-ruby\">\u003Cspan class=\"hljs-comment\"># _plugins/image_optimizer.rb - Jekyll image optimization plugin\u003C/span>\n\u003Cspan class=\"hljs-keyword\">require\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;mini_magick&#x27;\u003C/span>\n\u003Cspan class=\"hljs-keyword\">require\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;fileutils&#x27;\u003C/span>\n\n\u003Cspan class=\"hljs-keyword\">module\u003C/span> \u003Cspan class=\"hljs-title class_\">Jekyll\u003C/span>\n  \u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">ImageOptimizer\u003C/span> &lt; \u003Cspan class=\"hljs-title class_ inherited__\">Generator\u003C/span>\n    safe \u003Cspan class=\"hljs-literal\">true\u003C/span>\n    priority \u003Cspan class=\"hljs-symbol\">:low\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate\u003C/span>(\u003Cspan class=\"hljs-params\">site\u003C/span>)\n      \u003Cspan class=\"hljs-variable\">@site\u003C/span> = site\n      \u003Cspan class=\"hljs-variable\">@config\u003C/span> = site.config[\u003Cspan class=\"hljs-string\">&#x27;image_optimizer&#x27;\u003C/span>] |\u003Cspan class=\"hljs-params\">\u003C/span>| {}\n      \n      setup_directories\n      process_images\n      generate_responsive_images\n      create_optimization_data\n    \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">private\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">setup_directories\u003C/span>\n      \u003Cspan class=\"hljs-variable\">@input_dir\u003C/span> = \u003Cspan class=\"hljs-variable\">@config\u003C/span>[\u003Cspan class=\"hljs-string\">&#x27;input_dir&#x27;\u003C/span>] |\u003Cspan class=\"hljs-params\">\u003C/span>| \u003Cspan class=\"hljs-string\">&#x27;images/source&#x27;\u003C/span>\n      \u003Cspan class=\"hljs-variable\">@output_dir\u003C/span> = \u003Cspan class=\"hljs-variable\">@config\u003C/span>[\u003Cspan class=\"hljs-string\">&#x27;output_dir&#x27;\u003C/span>] |\u003Cspan class=\"hljs-params\">\u003C/span>| \u003Cspan class=\"hljs-string\">&#x27;images/optimized&#x27;\u003C/span>\n      \u003Cspan class=\"hljs-variable\">@formats\u003C/span> = \u003Cspan class=\"hljs-variable\">@config\u003C/span>[\u003Cspan class=\"hljs-string\">&#x27;formats&#x27;\u003C/span>] |\u003Cspan class=\"hljs-params\">\u003C/span>| [\u003Cspan class=\"hljs-string\">&#x27;webp&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;jpeg&#x27;\u003C/span>]\n      \u003Cspan class=\"hljs-variable\">@sizes\u003C/span> = \u003Cspan class=\"hljs-variable\">@config\u003C/span>[\u003Cspan class=\"hljs-string\">&#x27;sizes&#x27;\u003C/span>] |\u003Cspan class=\"hljs-params\">\u003C/span>| [\u003Cspan class=\"hljs-number\">320\u003C/span>, \u003Cspan class=\"hljs-number\">640\u003C/span>, \u003Cspan class=\"hljs-number\">960\u003C/span>, \u003Cspan class=\"hljs-number\">1280\u003C/span>, \u003Cspan class=\"hljs-number\">1920\u003C/span>]\n      \u003Cspan class=\"hljs-variable\">@quality\u003C/span> = \u003Cspan class=\"hljs-variable\">@config\u003C/span>[\u003Cspan class=\"hljs-string\">&#x27;quality&#x27;\u003C/span>] |\u003Cspan class=\"hljs-params\">\u003C/span>| { \u003Cspan class=\"hljs-string\">&#x27;jpeg&#x27;\u003C/span> =&gt; \u003Cspan class=\"hljs-number\">85\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;webp&#x27;\u003C/span> =&gt; \u003Cspan class=\"hljs-number\">80\u003C/span> }\n      \n      \u003Cspan class=\"hljs-title class_\">FileUtils\u003C/span>.mkdir_p(\u003Cspan class=\"hljs-variable\">@output_dir\u003C/span>)\n      \u003Cspan class=\"hljs-variable\">@formats\u003C/span>.each { |\u003Cspan class=\"hljs-params\">format\u003C/span>| \u003Cspan class=\"hljs-title class_\">FileUtils\u003C/span>.mkdir_p(\u003Cspan class=\"hljs-title class_\">File\u003C/span>.join(\u003Cspan class=\"hljs-variable\">@output_dir\u003C/span>, format)) }\n      \u003Cspan class=\"hljs-variable\">@sizes\u003C/span>.each { |\u003Cspan class=\"hljs-params\">size\u003C/span>| \u003Cspan class=\"hljs-title class_\">FileUtils\u003C/span>.mkdir_p(\u003Cspan class=\"hljs-title class_\">File\u003C/span>.join(\u003Cspan class=\"hljs-variable\">@output_dir\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;responsive&#x27;\u003C/span>, size.to_s)) }\n    \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">process_images\u003C/span>\n      \u003Cspan class=\"hljs-title class_\">Dir\u003C/span>.glob(\u003Cspan class=\"hljs-title class_\">File\u003C/span>.join(\u003Cspan class=\"hljs-variable\">@input_dir\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;**/*.{jpg,jpeg,png,gif}&#x27;\u003C/span>)).each \u003Cspan class=\"hljs-keyword\">do\u003C/span> |\u003Cspan class=\"hljs-params\">image_path\u003C/span>|\n        filename = \u003Cspan class=\"hljs-title class_\">File\u003C/span>.basename(image_path, \u003Cspan class=\"hljs-title class_\">File\u003C/span>.extname(image_path))\n        \n        optimize_formats(image_path, filename)\n        \u003Cspan class=\"hljs-title class_\">Jekyll\u003C/span>.logger.info \u003Cspan class=\"hljs-string\">&quot;Image Optimizer:&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;Processed \u003Cspan class=\"hljs-subst\">#{\u003Cspan class=\"hljs-title class_\">File\u003C/span>.basename(image_path)}\u003C/span>&quot;\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">optimize_formats\u003C/span>(\u003Cspan class=\"hljs-params\">image_path, filename\u003C/span>)\n      image = \u003Cspan class=\"hljs-title class_\">MiniMagick\u003C/span>\u003Cspan class=\"hljs-symbol\">:\u003C/span>\u003Cspan class=\"hljs-symbol\">:Image\u003C/span>.open(image_path)\n      \n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-variable\">@formats\u003C/span>.\u003Cspan class=\"hljs-keyword\">include\u003C/span>?(\u003Cspan class=\"hljs-string\">&#x27;jpeg&#x27;\u003C/span>)\n        jpeg_path = \u003Cspan class=\"hljs-title class_\">File\u003C/span>.join(\u003Cspan class=\"hljs-variable\">@output_dir\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;jpeg&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-subst\">#{filename}\u003C/span>.jpg&quot;\u003C/span>)\n        image.format(\u003Cspan class=\"hljs-string\">&#x27;jpg&#x27;\u003C/span>)\n        image.quality(\u003Cspan class=\"hljs-variable\">@quality\u003C/span>[\u003Cspan class=\"hljs-string\">&#x27;jpeg&#x27;\u003C/span>])\n        image.sampling_factor(\u003Cspan class=\"hljs-string\">&#x27;4:2:0&#x27;\u003C/span>)\n        image.strip\n        image.interlace(\u003Cspan class=\"hljs-string\">&#x27;Plane&#x27;\u003C/span>)\n        image.write(jpeg_path)\n      \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n      \n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-variable\">@formats\u003C/span>.\u003Cspan class=\"hljs-keyword\">include\u003C/span>?(\u003Cspan class=\"hljs-string\">&#x27;webp&#x27;\u003C/span>)\n        webp_path = \u003Cspan class=\"hljs-title class_\">File\u003C/span>.join(\u003Cspan class=\"hljs-variable\">@output_dir\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;webp&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-subst\">#{filename}\u003C/span>.webp&quot;\u003C/span>)\n        image.format(\u003Cspan class=\"hljs-string\">&#x27;webp&#x27;\u003C/span>)\n        image.quality(\u003Cspan class=\"hljs-variable\">@quality\u003C/span>[\u003Cspan class=\"hljs-string\">&#x27;webp&#x27;\u003C/span>])\n        image.write(webp_path)\n      \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_responsive_images\u003C/span>\n      \u003Cspan class=\"hljs-title class_\">Dir\u003C/span>.glob(\u003Cspan class=\"hljs-title class_\">File\u003C/span>.join(\u003Cspan class=\"hljs-variable\">@input_dir\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;**/*.{jpg,jpeg,png,gif}&#x27;\u003C/span>)).each \u003Cspan class=\"hljs-keyword\">do\u003C/span> |\u003Cspan class=\"hljs-params\">image_path\u003C/span>|\n        filename = \u003Cspan class=\"hljs-title class_\">File\u003C/span>.basename(image_path, \u003Cspan class=\"hljs-title class_\">File\u003C/span>.extname(image_path))\n        \n        \u003Cspan class=\"hljs-variable\">@sizes\u003C/span>.each \u003Cspan class=\"hljs-keyword\">do\u003C/span> |\u003Cspan class=\"hljs-params\">size\u003C/span>|\n          \u003Cspan class=\"hljs-variable\">@formats\u003C/span>.each \u003Cspan class=\"hljs-keyword\">do\u003C/span> |\u003Cspan class=\"hljs-params\">format\u003C/span>|\n            generate_responsive_variant(image_path, filename, size, format)\n          \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_responsive_variant\u003C/span>(\u003Cspan class=\"hljs-params\">image_path, filename, size, format\u003C/span>)\n      image = \u003Cspan class=\"hljs-title class_\">MiniMagick\u003C/span>\u003Cspan class=\"hljs-symbol\">:\u003C/span>\u003Cspan class=\"hljs-symbol\">:Image\u003C/span>.open(image_path)\n      image.resize(\u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-subst\">#{size}\u003C/span>x\u003Cspan class=\"hljs-subst\">#{size}\u003C/span>&gt;&quot;\u003C/span>)\n      \n      extension = format == \u003Cspan class=\"hljs-string\">&#x27;jpeg&#x27;\u003C/span> ? \u003Cspan class=\"hljs-string\">&#x27;jpg&#x27;\u003C/span> : format\n      output_path = \u003Cspan class=\"hljs-title class_\">File\u003C/span>.join(\u003Cspan class=\"hljs-variable\">@output_dir\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;responsive&#x27;\u003C/span>, size.to_s, \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-subst\">#{filename}\u003C/span>-\u003Cspan class=\"hljs-subst\">#{size}\u003C/span>.\u003Cspan class=\"hljs-subst\">#{extension}\u003C/span>&quot;\u003C/span>)\n      \n      \u003Cspan class=\"hljs-keyword\">case\u003C/span> format\n      \u003Cspan class=\"hljs-keyword\">when\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;jpeg&#x27;\u003C/span>\n        image.format(\u003Cspan class=\"hljs-string\">&#x27;jpg&#x27;\u003C/span>)\n        image.quality(\u003Cspan class=\"hljs-variable\">@quality\u003C/span>[\u003Cspan class=\"hljs-string\">&#x27;jpeg&#x27;\u003C/span>])\n        image.sampling_factor(\u003Cspan class=\"hljs-string\">&#x27;4:2:0&#x27;\u003C/span>)\n      \u003Cspan class=\"hljs-keyword\">when\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;webp&#x27;\u003C/span>\n        image.format(\u003Cspan class=\"hljs-string\">&#x27;webp&#x27;\u003C/span>)\n        image.quality(\u003Cspan class=\"hljs-variable\">@quality\u003C/span>[\u003Cspan class=\"hljs-string\">&#x27;webp&#x27;\u003C/span>])\n      \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n      \n      image.strip\n      image.write(output_path)\n    \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">create_optimization_data\u003C/span>\n      \u003Cspan class=\"hljs-comment\"># Create data file for templates to use\u003C/span>\n      optimization_data = {\n        \u003Cspan class=\"hljs-string\">&#x27;formats&#x27;\u003C/span> =&gt; \u003Cspan class=\"hljs-variable\">@formats\u003C/span>,\n        \u003Cspan class=\"hljs-string\">&#x27;sizes&#x27;\u003C/span> =&gt; \u003Cspan class=\"hljs-variable\">@sizes\u003C/span>,\n        \u003Cspan class=\"hljs-string\">&#x27;quality&#x27;\u003C/span> =&gt; \u003Cspan class=\"hljs-variable\">@quality\u003C/span>,\n        \u003Cspan class=\"hljs-string\">&#x27;output_dir&#x27;\u003C/span> =&gt; \u003Cspan class=\"hljs-variable\">@output_dir\u003C/span>\n      }\n      \n      \u003Cspan class=\"hljs-variable\">@site\u003C/span>.data[\u003Cspan class=\"hljs-string\">&#x27;image_optimization&#x27;\u003C/span>] = optimization_data\n    \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n  \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n  \n  \u003Cspan class=\"hljs-comment\"># Liquid tag for optimized images\u003C/span>\n  \u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">OptimizedImageTag\u003C/span> &lt; \u003Cspan class=\"hljs-title class_ inherited__\">Liquid::Tag\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">initialize\u003C/span>(\u003Cspan class=\"hljs-params\">tag_name, markup, tokens\u003C/span>)\n      \u003Cspan class=\"hljs-variable language_\">super\u003C/span>\n      \u003Cspan class=\"hljs-variable\">@markup\u003C/span> = markup.strip\n    \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">render\u003C/span>(\u003Cspan class=\"hljs-params\">context\u003C/span>)\n      site = context.registers[\u003Cspan class=\"hljs-symbol\">:site\u003C/span>]\n      config = site.data[\u003Cspan class=\"hljs-string\">&#x27;image_optimization&#x27;\u003C/span>] |\u003Cspan class=\"hljs-params\">\u003C/span>| {}\n      \n      \u003Cspan class=\"hljs-comment\"># Parse parameters\u003C/span>\n      params = {}\n      \u003Cspan class=\"hljs-variable\">@markup\u003C/span>.scan(\u003Cspan class=\"hljs-regexp\">/(\\w+):\\s*&quot;([^&quot;]*)&quot;|\\s*&quot;([^&quot;]*)&quot;/\u003C/span>) \u003Cspan class=\"hljs-keyword\">do\u003C/span> |\u003Cspan class=\"hljs-params\">key, quoted_value, unquoted_value\u003C/span>|\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> key\n          params[key] = quoted_value\n        \u003Cspan class=\"hljs-keyword\">else\u003C/span>\n          params[\u003Cspan class=\"hljs-string\">&#x27;src&#x27;\u003C/span>] = unquoted_value\n        \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n      \n      src = params[\u003Cspan class=\"hljs-string\">&#x27;src&#x27;\u003C/span>]\n      alt = params[\u003Cspan class=\"hljs-string\">&#x27;alt&#x27;\u003C/span>] |\u003Cspan class=\"hljs-params\">\u003C/span>| \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>\n      class_name = params[\u003Cspan class=\"hljs-string\">&#x27;class&#x27;\u003C/span>] |\u003Cspan class=\"hljs-params\">\u003C/span>| \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>\n      sizes = params[\u003Cspan class=\"hljs-string\">&#x27;sizes&#x27;\u003C/span>] |\u003Cspan class=\"hljs-params\">\u003C/span>| \u003Cspan class=\"hljs-string\">&#x27;(max-width: 640px) 100vw, (max-width: 960px) 640px, 960px&#x27;\u003C/span>\n      \n      \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">unless\u003C/span> src\n      \n      filename = \u003Cspan class=\"hljs-title class_\">File\u003C/span>.basename(src, \u003Cspan class=\"hljs-title class_\">File\u003C/span>.extname(src))\n      output_dir = config[\u003Cspan class=\"hljs-string\">&#x27;output_dir&#x27;\u003C/span>] |\u003Cspan class=\"hljs-params\">\u003C/span>| \u003Cspan class=\"hljs-string\">&#x27;images/optimized&#x27;\u003C/span>\n      responsive_sizes = config[\u003Cspan class=\"hljs-string\">&#x27;sizes&#x27;\u003C/span>] |\u003Cspan class=\"hljs-params\">\u003C/span>| [\u003Cspan class=\"hljs-number\">320\u003C/span>, \u003Cspan class=\"hljs-number\">640\u003C/span>, \u003Cspan class=\"hljs-number\">960\u003C/span>, \u003Cspan class=\"hljs-number\">1280\u003C/span>, \u003Cspan class=\"hljs-number\">1920\u003C/span>]\n      \n      \u003Cspan class=\"hljs-comment\"># Generate picture element\u003C/span>\n      picture_html = \u003Cspan class=\"hljs-string\">%{&lt;picture class=&quot;\u003Cspan class=\"hljs-subst\">#{class_name}\u003C/span>&quot;&gt;}\u003C/span>\n      \n      \u003Cspan class=\"hljs-comment\"># WebP source\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">if\u003C/span> config[\u003Cspan class=\"hljs-string\">&#x27;formats&#x27;\u003C/span>].\u003Cspan class=\"hljs-keyword\">include\u003C/span>?(\u003Cspan class=\"hljs-string\">&#x27;webp&#x27;\u003C/span>)\n        webp_srcset = responsive_sizes.map { |\u003Cspan class=\"hljs-params\">size\u003C/span>| \n          \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-subst\">#{output_dir}\u003C/span>/responsive/\u003Cspan class=\"hljs-subst\">#{size}\u003C/span>/\u003Cspan class=\"hljs-subst\">#{filename}\u003C/span>-\u003Cspan class=\"hljs-subst\">#{size}\u003C/span>.webp \u003Cspan class=\"hljs-subst\">#{size}\u003C/span>w&quot;\u003C/span> \n        }.join(\u003Cspan class=\"hljs-string\">&#x27;, &#x27;\u003C/span>)\n        \n        picture_html += \u003Cspan class=\"hljs-string\">%{\n          &lt;source srcset=&quot;\u003Cspan class=\"hljs-subst\">#{webp_srcset}\u003C/span>&quot; \n                  sizes=&quot;\u003Cspan class=\"hljs-subst\">#{sizes}\u003C/span>&quot; \n                  type=&quot;image/webp&quot;&gt;\n        }\u003C/span>\n      \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n      \n      \u003Cspan class=\"hljs-comment\"># JPEG fallback\u003C/span>\n      jpeg_srcset = responsive_sizes.map { |\u003Cspan class=\"hljs-params\">size\u003C/span>| \n        \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-subst\">#{output_dir}\u003C/span>/responsive/\u003Cspan class=\"hljs-subst\">#{size}\u003C/span>/\u003Cspan class=\"hljs-subst\">#{filename}\u003C/span>-\u003Cspan class=\"hljs-subst\">#{size}\u003C/span>.jpg \u003Cspan class=\"hljs-subst\">#{size}\u003C/span>w&quot;\u003C/span> \n      }.join(\u003Cspan class=\"hljs-string\">&#x27;, &#x27;\u003C/span>)\n      \n      picture_html += \u003Cspan class=\"hljs-string\">%{\n        &lt;img src=&quot;\u003Cspan class=\"hljs-subst\">#{output_dir}\u003C/span>/responsive/960/\u003Cspan class=\"hljs-subst\">#{filename}\u003C/span>-960.jpg&quot;\n             srcset=&quot;\u003Cspan class=\"hljs-subst\">#{jpeg_srcset}\u003C/span>&quot;\n             sizes=&quot;\u003Cspan class=\"hljs-subst\">#{sizes}\u003C/span>&quot;\n             alt=&quot;\u003Cspan class=\"hljs-subst\">#{alt}\u003C/span>&quot;\n             loading=&quot;lazy&quot;\n             decoding=&quot;async&quot;&gt;\n      }\u003C/span>\n      \n      picture_html += \u003Cspan class=\"hljs-string\">%{&lt;/picture&gt;}\u003C/span>\n      \n      picture_html\n    \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n  \u003Cspan class=\"hljs-keyword\">end\u003C/span>\n\u003Cspan class=\"hljs-keyword\">end\u003C/span>\n\n\u003Cspan class=\"hljs-title class_\">Liquid\u003C/span>\u003Cspan class=\"hljs-symbol\">:\u003C/span>\u003Cspan class=\"hljs-symbol\">:Template\u003C/span>.register_tag(\u003Cspan class=\"hljs-string\">&#x27;optimized_image&#x27;\u003C/span>, \u003Cspan class=\"hljs-title class_\">Jekyll\u003C/span>\u003Cspan class=\"hljs-symbol\">:\u003C/span>\u003Cspan class=\"hljs-symbol\">:OptimizedImageTag\u003C/span>)\n\u003C/code>\u003C/pre>\u003Ch3 id=\"hugo-image-processing\">Hugo Image Processing\u003C/h3>\n\u003Cp>Built-in Hugo image processing for automated optimization:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-yaml\">\u003Cspan class=\"hljs-comment\"># config.yml - Hugo image processing configuration\u003C/span>\n\u003Cspan class=\"hljs-attr\">imaging:\u003C/span>\n  \u003Cspan class=\"hljs-comment\"># Image processing quality (1-100)\u003C/span>\n  \u003Cspan class=\"hljs-attr\">quality:\u003C/span> \u003Cspan class=\"hljs-number\">85\u003C/span>\n  \n  \u003Cspan class=\"hljs-comment\"># Resampling filter for resizing\u003C/span>\n  \u003Cspan class=\"hljs-attr\">resampleFilter:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;lanczos&quot;\u003C/span>\n  \n  \u003Cspan class=\"hljs-comment\"># Anchor for cropping (smart, center, topleft, etc.)\u003C/span>\n  \u003Cspan class=\"hljs-attr\">anchor:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;smart&quot;\u003C/span>\n  \n  \u003Cspan class=\"hljs-comment\"># Background color for transparent images\u003C/span>\n  \u003Cspan class=\"hljs-attr\">bgColor:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;#ffffff&quot;\u003C/span>\n  \n  \u003Cspan class=\"hljs-comment\"># Image formats and settings\u003C/span>\n  \u003Cspan class=\"hljs-attr\">formats:\u003C/span>\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">webp\u003C/span>\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">jpeg\u003C/span>\n    \n  \u003Cspan class=\"hljs-comment\"># Default processing settings\u003C/span>\n  \u003Cspan class=\"hljs-attr\">processing:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">jpeg:\u003C/span>\n      \u003Cspan class=\"hljs-attr\">quality:\u003C/span> \u003Cspan class=\"hljs-number\">85\u003C/span>\n      \u003Cspan class=\"hljs-attr\">progressive:\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>\n    \u003Cspan class=\"hljs-attr\">webp:\u003C/span>\n      \u003Cspan class=\"hljs-attr\">quality:\u003C/span> \u003Cspan class=\"hljs-number\">80\u003C/span>\n      \u003Cspan class=\"hljs-attr\">lossless:\u003C/span> \u003Cspan class=\"hljs-literal\">false\u003C/span>\n\n\u003Cspan class=\"hljs-comment\"># Custom image shortcode settings\u003C/span>\n\u003Cspan class=\"hljs-attr\">params:\u003C/span>\n  \u003Cspan class=\"hljs-attr\">images:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">responsive_sizes:\u003C/span> [\u003Cspan class=\"hljs-number\">320\u003C/span>, \u003Cspan class=\"hljs-number\">640\u003C/span>, \u003Cspan class=\"hljs-number\">960\u003C/span>, \u003Cspan class=\"hljs-number\">1280\u003C/span>, \u003Cspan class=\"hljs-number\">1920\u003C/span>]\n    \u003Cspan class=\"hljs-attr\">default_quality:\u003C/span> \u003Cspan class=\"hljs-number\">85\u003C/span>\n    \u003Cspan class=\"hljs-attr\">lazy_loading:\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>\n    \u003Cspan class=\"hljs-attr\">formats:\u003C/span> [\u003Cspan class=\"hljs-string\">&quot;webp&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;jpeg&quot;\u003C/span>]\n\u003C/code>\u003C/pre>\u003Cpre>\u003Ccode class=\"hljs language-go-html-template\">{{/* layouts/shortcodes/responsive-image.html - Hugo responsive image shortcode */}}\n{{- $src := .Get &quot;src&quot; -}}\n{{- $alt := .Get &quot;alt&quot; | default &quot;&quot; -}}\n{{- $class := .Get &quot;class&quot; | default &quot;&quot; -}}\n{{- $sizes := .Get &quot;sizes&quot; | default &quot;(max-width: 640px) 100vw, (max-width: 960px) 640px, 960px&quot; -}}\n{{- $quality := .Get &quot;quality&quot; | default 85 -}}\n\n{{- $image := resources.Get $src -}}\n{{- if $image -}}\n  {{- $responsive_sizes := site.Params.images.responsive_sizes | default (slice 320 640 960 1280 1920) -}}\n  {{- $formats := site.Params.images.formats | default (slice &quot;webp&quot; &quot;jpeg&quot;) -}}\n  \n  &lt;picture class=&quot;{{ $class }}&quot;&gt;\n    {{- if in $formats &quot;webp&quot; -}}\n      {{- $webp_srcset := slice -}}\n      {{- range $responsive_sizes -}}\n        {{- $resized := $image.Resize (printf &quot;%dx webp q%d&quot; . $quality) -}}\n        {{- $webp_srcset = $webp_srcset | append (printf &quot;%s %dw&quot; $resized.RelPermalink .) -}}\n      {{- end -}}\n      \n      &lt;source srcset=&quot;{{ delimit $webp_srcset &quot;, &quot; }}&quot; \n              sizes=&quot;{{ $sizes }}&quot; \n              type=&quot;image/webp&quot;&gt;\n    {{- end -}}\n    \n    {{- $jpeg_srcset := slice -}}\n    {{- range $responsive_sizes -}}\n      {{- $resized := $image.Resize (printf &quot;%dx jpeg q%d&quot; . $quality) -}}\n      {{- $jpeg_srcset = $jpeg_srcset | append (printf &quot;%s %dw&quot; $resized.RelPermalink .) -}}\n    {{- end -}}\n    \n    {{- $default_image := $image.Resize (printf &quot;960x jpeg q%d&quot; $quality) -}}\n    \n    &lt;img src=&quot;{{ $default_image.RelPermalink }}&quot;\n         srcset=&quot;{{ delimit $jpeg_srcset &quot;, &quot; }}&quot;\n         sizes=&quot;{{ $sizes }}&quot;\n         alt=&quot;{{ $alt }}&quot;\n         {{- if site.Params.images.lazy_loading }} loading=&quot;lazy&quot;{{- end }}\n         decoding=&quot;async&quot;\n         width=&quot;{{ $default_image.Width }}&quot;\n         height=&quot;{{ $default_image.Height }}&quot;&gt;\n  &lt;/picture&gt;\n{{- else -}}\n  &lt;p class=&quot;image-error&quot;&gt;Image not found: {{ $src }}&lt;/p&gt;\n{{- end -}}\n\u003C/code>\u003C/pre>\u003Ch2 id=\"lazy-loading-and-performance-enhancement\">Lazy Loading and Performance Enhancement\u003C/h2>\n\u003Ch3 id=\"modern-lazy-loading-implementation\">Modern Lazy Loading Implementation\u003C/h3>\n\u003Cp>Advanced lazy loading techniques for optimal performance:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-javascript\">\u003Cspan class=\"hljs-comment\">// lazy-loading.js - Advanced lazy loading with intersection observer\u003C/span>\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">AdvancedLazyLoader\u003C/span> {\n    \u003Cspan class=\"hljs-title function_\">constructor\u003C/span>(\u003Cspan class=\"hljs-params\">options = {}\u003C/span>) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">imageSelector\u003C/span> = options.\u003Cspan class=\"hljs-property\">imageSelector\u003C/span> || \u003Cspan class=\"hljs-string\">&#x27;img[data-src], img[loading=&quot;lazy&quot;]&#x27;\u003C/span>;\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">rootMargin\u003C/span> = options.\u003Cspan class=\"hljs-property\">rootMargin\u003C/span> || \u003Cspan class=\"hljs-string\">&#x27;50px 0px&#x27;\u003C/span>;\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">threshold\u003C/span> = options.\u003Cspan class=\"hljs-property\">threshold\u003C/span> || \u003Cspan class=\"hljs-number\">0.01\u003C/span>;\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">enableBlur\u003C/span> = options.\u003Cspan class=\"hljs-property\">enableBlur\u003C/span> !== \u003Cspan class=\"hljs-literal\">false\u003C/span>;\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">enableFadeIn\u003C/span> = options.\u003Cspan class=\"hljs-property\">enableFadeIn\u003C/span> !== \u003Cspan class=\"hljs-literal\">false\u003C/span>;\n        \n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">observer\u003C/span> = \u003Cspan class=\"hljs-literal\">null\u003C/span>;\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">images\u003C/span> = [];\n        \n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">init\u003C/span>();\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">init\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-comment\">// Check for Intersection Observer support\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!(\u003Cspan class=\"hljs-string\">&#x27;IntersectionObserver&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-variable language_\">window\u003C/span>)) {\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">fallbackLoading\u003C/span>();\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span>;\n        }\n        \n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">setupObserver\u003C/span>();\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">observeImages\u003C/span>();\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">setupErrorHandling\u003C/span>();\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">setupObserver\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> options = {\n            \u003Cspan class=\"hljs-attr\">root\u003C/span>: \u003Cspan class=\"hljs-literal\">null\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">rootMargin\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">rootMargin\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">threshold\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">threshold\u003C/span>\n        };\n        \n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">observer\u003C/span> = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">IntersectionObserver\u003C/span>(\u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">entries, observer\u003C/span>) =&gt;\u003C/span> {\n            entries.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">entry\u003C/span> =&gt;\u003C/span> {\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> (entry.\u003Cspan class=\"hljs-property\">isIntersecting\u003C/span>) {\n                    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">loadImage\u003C/span>(entry.\u003Cspan class=\"hljs-property\">target\u003C/span>);\n                    observer.\u003Cspan class=\"hljs-title function_\">unobserve\u003C/span>(entry.\u003Cspan class=\"hljs-property\">target\u003C/span>);\n                }\n            });\n        }, options);\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">observeImages\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">images\u003C/span> = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">imageSelector\u003C/span>);\n        \n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">images\u003C/span>.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">img\u003C/span> =&gt;\u003C/span> {\n            \u003Cspan class=\"hljs-comment\">// Add loading placeholder if enabled\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">enableBlur\u003C/span>) {\n                \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">addBlurPlaceholder\u003C/span>(img);\n            }\n            \n            \u003Cspan class=\"hljs-comment\">// Add fade-in class if enabled\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">enableFadeIn\u003C/span>) {\n                img.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">add\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;lazy-fade&#x27;\u003C/span>);\n            }\n            \n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">observer\u003C/span>.\u003Cspan class=\"hljs-title function_\">observe\u003C/span>(img);\n        });\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">addBlurPlaceholder\u003C/span>(\u003Cspan class=\"hljs-params\">img\u003C/span>) {\n        \u003Cspan class=\"hljs-comment\">// Create low-quality placeholder if data-placeholder exists\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> placeholder = img.\u003Cspan class=\"hljs-property\">dataset\u003C/span>.\u003Cspan class=\"hljs-property\">placeholder\u003C/span>;\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (placeholder) {\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> placeholderImg = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Image\u003C/span>();\n            placeholderImg.\u003Cspan class=\"hljs-property\">onload\u003C/span> = \u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n                img.\u003Cspan class=\"hljs-property\">style\u003C/span>.\u003Cspan class=\"hljs-property\">backgroundImage\u003C/span> = \u003Cspan class=\"hljs-string\">`url(\u003Cspan class=\"hljs-subst\">${placeholder}\u003C/span>)`\u003C/span>;\n                img.\u003Cspan class=\"hljs-property\">style\u003C/span>.\u003Cspan class=\"hljs-property\">backgroundSize\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;cover&#x27;\u003C/span>;\n                img.\u003Cspan class=\"hljs-property\">style\u003C/span>.\u003Cspan class=\"hljs-property\">backgroundPosition\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;center&#x27;\u003C/span>;\n                img.\u003Cspan class=\"hljs-property\">style\u003C/span>.\u003Cspan class=\"hljs-property\">filter\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;blur(5px)&#x27;\u003C/span>;\n                img.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">add\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;lazy-placeholder&#x27;\u003C/span>);\n            };\n            placeholderImg.\u003Cspan class=\"hljs-property\">src\u003C/span> = placeholder;\n        }\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">loadImage\u003C/span>(\u003Cspan class=\"hljs-params\">img\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Promise\u003C/span>(\u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">resolve, reject\u003C/span>) =&gt;\u003C/span> {\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> imageLoader = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Image\u003C/span>();\n            \n            imageLoader.\u003Cspan class=\"hljs-property\">onload\u003C/span> = \u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n                \u003Cspan class=\"hljs-comment\">// Update src from data-src if present\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> (img.\u003Cspan class=\"hljs-property\">dataset\u003C/span>.\u003Cspan class=\"hljs-property\">src\u003C/span>) {\n                    img.\u003Cspan class=\"hljs-property\">src\u003C/span> = img.\u003Cspan class=\"hljs-property\">dataset\u003C/span>.\u003Cspan class=\"hljs-property\">src\u003C/span>;\n                }\n                \n                \u003Cspan class=\"hljs-comment\">// Update srcset from data-srcset if present\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> (img.\u003Cspan class=\"hljs-property\">dataset\u003C/span>.\u003Cspan class=\"hljs-property\">srcset\u003C/span>) {\n                    img.\u003Cspan class=\"hljs-property\">srcset\u003C/span> = img.\u003Cspan class=\"hljs-property\">dataset\u003C/span>.\u003Cspan class=\"hljs-property\">srcset\u003C/span>;\n                }\n                \n                \u003Cspan class=\"hljs-comment\">// Handle responsive picture elements\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">const\u003C/span> picture = img.\u003Cspan class=\"hljs-title function_\">closest\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;picture&#x27;\u003C/span>);\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> (picture) {\n                    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">loadPictureSources\u003C/span>(picture);\n                }\n                \n                \u003Cspan class=\"hljs-comment\">// Apply loading effects\u003C/span>\n                \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">applyLoadingEffects\u003C/span>(img);\n                \n                \u003Cspan class=\"hljs-comment\">// Remove data attributes\u003C/span>\n                \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">cleanupDataAttributes\u003C/span>(img);\n                \n                \u003Cspan class=\"hljs-title function_\">resolve\u003C/span>(img);\n            };\n            \n            imageLoader.\u003Cspan class=\"hljs-property\">onerror\u003C/span> = \u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n                \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">handleImageError\u003C/span>(img);\n                \u003Cspan class=\"hljs-title function_\">reject\u003C/span>(\u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Error\u003C/span>(\u003Cspan class=\"hljs-string\">`Failed to load image: \u003Cspan class=\"hljs-subst\">${img.src}\u003C/span>`\u003C/span>));\n            };\n            \n            \u003Cspan class=\"hljs-comment\">// Start loading\u003C/span>\n            imageLoader.\u003Cspan class=\"hljs-property\">src\u003C/span> = img.\u003Cspan class=\"hljs-property\">dataset\u003C/span>.\u003Cspan class=\"hljs-property\">src\u003C/span> || img.\u003Cspan class=\"hljs-property\">src\u003C/span>;\n        });\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">loadPictureSources\u003C/span>(\u003Cspan class=\"hljs-params\">picture\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> sources = picture.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;source[data-srcset]&#x27;\u003C/span>);\n        \n        sources.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">source\u003C/span> =&gt;\u003C/span> {\n            source.\u003Cspan class=\"hljs-property\">srcset\u003C/span> = source.\u003Cspan class=\"hljs-property\">dataset\u003C/span>.\u003Cspan class=\"hljs-property\">srcset\u003C/span>;\n            \u003Cspan class=\"hljs-keyword\">delete\u003C/span> source.\u003Cspan class=\"hljs-property\">dataset\u003C/span>.\u003Cspan class=\"hljs-property\">srcset\u003C/span>;\n        });\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">applyLoadingEffects\u003C/span>(\u003Cspan class=\"hljs-params\">img\u003C/span>) {\n        \u003Cspan class=\"hljs-comment\">// Remove blur effect\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">enableBlur\u003C/span> &amp;&amp; img.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">contains\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;lazy-placeholder&#x27;\u003C/span>)) {\n            img.\u003Cspan class=\"hljs-property\">style\u003C/span>.\u003Cspan class=\"hljs-property\">filter\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>;\n            img.\u003Cspan class=\"hljs-property\">style\u003C/span>.\u003Cspan class=\"hljs-property\">backgroundImage\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>;\n            img.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">remove\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;lazy-placeholder&#x27;\u003C/span>);\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Add fade-in effect\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">enableFadeIn\u003C/span>) {\n            img.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">add\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;lazy-loaded&#x27;\u003C/span>);\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Mark as loaded\u003C/span>\n        img.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">add\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;loaded&#x27;\u003C/span>);\n        img.\u003Cspan class=\"hljs-title function_\">setAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;data-loaded&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;true&#x27;\u003C/span>);\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">cleanupDataAttributes\u003C/span>(\u003Cspan class=\"hljs-params\">img\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">delete\u003C/span> img.\u003Cspan class=\"hljs-property\">dataset\u003C/span>.\u003Cspan class=\"hljs-property\">src\u003C/span>;\n        \u003Cspan class=\"hljs-keyword\">delete\u003C/span> img.\u003Cspan class=\"hljs-property\">dataset\u003C/span>.\u003Cspan class=\"hljs-property\">srcset\u003C/span>;\n        \u003Cspan class=\"hljs-keyword\">delete\u003C/span> img.\u003Cspan class=\"hljs-property\">dataset\u003C/span>.\u003Cspan class=\"hljs-property\">placeholder\u003C/span>;\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">handleImageError\u003C/span>(\u003Cspan class=\"hljs-params\">img\u003C/span>) {\n        img.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">add\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;lazy-error&#x27;\u003C/span>);\n        \n        \u003Cspan class=\"hljs-comment\">// Add error placeholder if configured\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> errorSrc = img.\u003Cspan class=\"hljs-property\">dataset\u003C/span>.\u003Cspan class=\"hljs-property\">error\u003C/span> || \u003Cspan class=\"hljs-string\">&#x27;/images/placeholder-error.jpg&#x27;\u003C/span>;\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (errorSrc &amp;&amp; img.\u003Cspan class=\"hljs-property\">src\u003C/span> !== errorSrc) {\n            img.\u003Cspan class=\"hljs-property\">src\u003C/span> = errorSrc;\n        }\n        \n        \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">warn\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Image failed to load:&#x27;\u003C/span>, img.\u003Cspan class=\"hljs-property\">src\u003C/span>);\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">setupErrorHandling\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-comment\">// Global error handler for images\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;error&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">e\u003C/span>) =&gt;\u003C/span> {\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (e.\u003Cspan class=\"hljs-property\">target\u003C/span>.\u003Cspan class=\"hljs-property\">tagName\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;IMG&#x27;\u003C/span>) {\n                \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">handleImageError\u003C/span>(e.\u003Cspan class=\"hljs-property\">target\u003C/span>);\n            }\n        }, \u003Cspan class=\"hljs-literal\">true\u003C/span>);\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">fallbackLoading\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-comment\">// Fallback for browsers without Intersection Observer\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">warn\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;Intersection Observer not supported, loading all images immediately&#x27;\u003C/span>);\n        \n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> images = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">imageSelector\u003C/span>);\n        images.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">img\u003C/span> =&gt;\u003C/span> {\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">loadImage\u003C/span>(img);\n        });\n    }\n    \n    \u003Cspan class=\"hljs-comment\">// Public methods\u003C/span>\n    \u003Cspan class=\"hljs-title function_\">loadAll\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">images\u003C/span>.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">img\u003C/span> =&gt;\u003C/span> {\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!img.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">contains\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;loaded&#x27;\u003C/span>)) {\n                \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">loadImage\u003C/span>(img);\n            }\n        });\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">destroy\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">observer\u003C/span>) {\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">observer\u003C/span>.\u003Cspan class=\"hljs-title function_\">disconnect\u003C/span>();\n        }\n    }\n}\n\n\u003Cspan class=\"hljs-comment\">// CSS for lazy loading effects\u003C/span>\n\u003Cspan class=\"hljs-keyword\">const\u003C/span> lazyLoadingCSS = \u003Cspan class=\"hljs-string\">`\n.lazy-fade {\n    opacity: 0;\n    transition: opacity 0.3s ease-in-out;\n}\n\n.lazy-fade.lazy-loaded {\n    opacity: 1;\n}\n\n.lazy-placeholder {\n    transition: filter 0.3s ease-in-out;\n}\n\n.lazy-error {\n    opacity: 0.5;\n    filter: grayscale(100%);\n}\n\n.loaded {\n    animation: fadeIn 0.3s ease-in-out;\n}\n\n@keyframes fadeIn {\n    from { opacity: 0; }\n    to { opacity: 1; }\n}\n\n/* Loading spinner for images */\n.image-container {\n    position: relative;\n    overflow: hidden;\n}\n\n.image-container::before {\n    content: &#x27;&#x27;;\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    width: 20px;\n    height: 20px;\n    margin: -10px 0 0 -10px;\n    border: 2px solid #f3f3f3;\n    border-top: 2px solid #3498db;\n    border-radius: 50%;\n    animation: spin 1s linear infinite;\n    opacity: 1;\n    transition: opacity 0.3s ease-in-out;\n}\n\n.image-container img.loaded + ::before {\n    opacity: 0;\n}\n\n@keyframes spin {\n    0% { transform: rotate(0deg); }\n    100% { transform: rotate(360deg); }\n}\n`\u003C/span>;\n\n\u003Cspan class=\"hljs-comment\">// Inject CSS\u003C/span>\n\u003Cspan class=\"hljs-keyword\">const\u003C/span> style = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;style&#x27;\u003C/span>);\nstyle.\u003Cspan class=\"hljs-property\">textContent\u003C/span> = lazyLoadingCSS;\n\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">head\u003C/span>.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(style);\n\n\u003Cspan class=\"hljs-comment\">// Initialize lazy loading\u003C/span>\n\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;DOMContentLoaded&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n    \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">AdvancedLazyLoader\u003C/span>({\n        \u003Cspan class=\"hljs-attr\">rootMargin\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;50px 0px&#x27;\u003C/span>,\n        \u003Cspan class=\"hljs-attr\">threshold\u003C/span>: \u003Cspan class=\"hljs-number\">0.01\u003C/span>,\n        \u003Cspan class=\"hljs-attr\">enableBlur\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span>,\n        \u003Cspan class=\"hljs-attr\">enableFadeIn\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span>\n    });\n});\n\u003C/code>\u003C/pre>\u003Ch2 id=\"integration-with-modern-workflows\">Integration with Modern Workflows\u003C/h2>\n\u003Cp>Image optimization and compression work seamlessly with comprehensive Markdown content systems. When combined with \u003Ca href=\"/blog/markdown-responsive-images-complete-guide\">responsive images and modern formatting techniques\u003C/a>, automated optimization ensures fast-loading documentation that maintains visual quality across all devices while reducing bandwidth costs and improving user experience.\u003C/p>\n\u003Cp>For content-heavy documentation sites, image optimization complements \u003Ca href=\"/blog/markdown-custom-css-classes-styling-complete-guide\">custom CSS styling and performance optimization\u003C/a> to create comprehensive publishing workflows that automatically generate appropriately sized and formatted images for different viewing contexts and network conditions.\u003C/p>\n\u003Cp>When developing documentation with multimedia content, image optimization works effectively with \u003Ca href=\"/blog/markdown-table-sorting-filtering-interactive-guide\">table formatting and data visualization\u003C/a> to ensure all visual content loads quickly while maintaining the clarity and impact necessary for effective technical communication and user engagement.\u003C/p>\n\u003Ch2 id=\"troubleshooting-common-optimization-issues\">Troubleshooting Common Optimization Issues\u003C/h2>\n\u003Ch3 id=\"format-compatibility-problems\">Format Compatibility Problems\u003C/h3>\n\u003Cp>\u003Cstrong>Problem\u003C/strong>: Images not displaying correctly across different browsers or formats not supported\u003C/p>\n\u003Cp>\u003Cstrong>Solutions\u003C/strong>:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-html\">\u003Cspan class=\"hljs-comment\">&lt;!-- Comprehensive fallback strategy --&gt;\u003C/span>\n\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">picture\u003C/span>&gt;\u003C/span>\n  \u003Cspan class=\"hljs-comment\">&lt;!-- Next-generation formats with feature detection --&gt;\u003C/span>\n  \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">source\u003C/span> \u003Cspan class=\"hljs-attr\">srcset\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;image.avif&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">type\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;image/avif&quot;\u003C/span>&gt;\u003C/span>\n  \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">source\u003C/span> \u003Cspan class=\"hljs-attr\">srcset\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;image.webp&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">type\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;image/webp&quot;\u003C/span>&gt;\u003C/span>\n  \n  \u003Cspan class=\"hljs-comment\">&lt;!-- Universal fallback --&gt;\u003C/span>\n  \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">img\u003C/span> \u003Cspan class=\"hljs-attr\">src\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;image.jpg&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">alt\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;Description&quot;\u003C/span> \n       \u003Cspan class=\"hljs-attr\">onerror\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;this.onerror=null; this.src=&#x27;fallback-image.jpg&#x27;;&quot;\u003C/span>&gt;\u003C/span>\n\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">picture\u003C/span>&gt;\u003C/span>\n\n\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">script\u003C/span>&gt;\u003C/span>\u003Cspan class=\"language-javascript\">\n\u003Cspan class=\"hljs-comment\">// JavaScript feature detection\u003C/span>\n\u003Cspan class=\"hljs-keyword\">function\u003C/span> \u003Cspan class=\"hljs-title function_\">checkImageFormat\u003C/span>(\u003Cspan class=\"hljs-params\">format\u003C/span>) {\n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> img = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Image\u003C/span>();\n    img.\u003Cspan class=\"hljs-property\">onload\u003C/span> = img.\u003Cspan class=\"hljs-property\">onerror\u003C/span> = \u003Cspan class=\"hljs-keyword\">function\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> isSupported = img.\u003Cspan class=\"hljs-property\">height\u003C/span> === \u003Cspan class=\"hljs-number\">1\u003C/span>;\n        \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">documentElement\u003C/span>.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">toggle\u003C/span>(\u003Cspan class=\"hljs-string\">`\u003Cspan class=\"hljs-subst\">${format}\u003C/span>-support`\u003C/span>, isSupported);\n    };\n    \n    \u003Cspan class=\"hljs-keyword\">const\u003C/span> testImages = {\n        \u003Cspan class=\"hljs-attr\">webp\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoBAAEAAwA0JaQAA3AA/vuUAAA=&#x27;\u003C/span>,\n        \u003Cspan class=\"hljs-attr\">avif\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAA==&#x27;\u003C/span>\n    };\n    \n    img.\u003Cspan class=\"hljs-property\">src\u003C/span> = testImages[format];\n}\n\n\u003Cspan class=\"hljs-comment\">// Check format support\u003C/span>\n\u003Cspan class=\"hljs-title function_\">checkImageFormat\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;webp&#x27;\u003C/span>);\n\u003Cspan class=\"hljs-title function_\">checkImageFormat\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;avif&#x27;\u003C/span>);\n\u003C/span>\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">script\u003C/span>&gt;\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch3 id=\"performance-issues-with-large-images\">Performance Issues with Large Images\u003C/h3>\n\u003Cp>\u003Cstrong>Problem\u003C/strong>: Slow loading times despite optimization efforts\u003C/p>\n\u003Cp>\u003Cstrong>Solutions\u003C/strong>:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-javascript\">\u003Cspan class=\"hljs-comment\">// Progressive loading with quality scaling\u003C/span>\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">ProgressiveImageLoader\u003C/span> {\n    \u003Cspan class=\"hljs-title function_\">constructor\u003C/span>(\u003Cspan class=\"hljs-params\">img\u003C/span>) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">img\u003C/span> = img;\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">loadProgressive\u003C/span>();\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">loadProgressive\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-comment\">// Load low-quality placeholder first\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> placeholder = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">img\u003C/span>.\u003Cspan class=\"hljs-property\">dataset\u003C/span>.\u003Cspan class=\"hljs-property\">placeholder\u003C/span>;\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (placeholder) {\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">img\u003C/span>.\u003Cspan class=\"hljs-property\">src\u003C/span> = placeholder;\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">img\u003C/span>.\u003Cspan class=\"hljs-property\">style\u003C/span>.\u003Cspan class=\"hljs-property\">filter\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;blur(2px)&#x27;\u003C/span>;\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Load medium quality version\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> mediumQuality = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">img\u003C/span>.\u003Cspan class=\"hljs-property\">dataset\u003C/span>.\u003Cspan class=\"hljs-property\">medium\u003C/span>;\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (mediumQuality) {\n            \u003Cspan class=\"hljs-built_in\">setTimeout\u003C/span>(\u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">loadImage\u003C/span>(mediumQuality, \u003Cspan class=\"hljs-string\">&#x27;blur(1px)&#x27;\u003C/span>), \u003Cspan class=\"hljs-number\">100\u003C/span>);\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Load high quality version\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> highQuality = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">img\u003C/span>.\u003Cspan class=\"hljs-property\">dataset\u003C/span>.\u003Cspan class=\"hljs-property\">src\u003C/span>;\n        \u003Cspan class=\"hljs-built_in\">setTimeout\u003C/span>(\u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">loadImage\u003C/span>(highQuality, \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>), \u003Cspan class=\"hljs-number\">300\u003C/span>);\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">loadImage\u003C/span>(\u003Cspan class=\"hljs-params\">src, filter\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> img = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Image\u003C/span>();\n        img.\u003Cspan class=\"hljs-property\">onload\u003C/span> = \u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">img\u003C/span>.\u003Cspan class=\"hljs-property\">src\u003C/span> = src;\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">img\u003C/span>.\u003Cspan class=\"hljs-property\">style\u003C/span>.\u003Cspan class=\"hljs-property\">filter\u003C/span> = filter;\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">img\u003C/span>.\u003Cspan class=\"hljs-property\">style\u003C/span>.\u003Cspan class=\"hljs-property\">transition\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;filter 0.3s ease&#x27;\u003C/span>;\n        };\n        img.\u003Cspan class=\"hljs-property\">src\u003C/span> = src;\n    }\n}\n\n\u003Cspan class=\"hljs-comment\">// Initialize progressive loading\u003C/span>\n\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;img[data-progressive]&#x27;\u003C/span>).\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">img\u003C/span> =&gt;\u003C/span> {\n    \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">ProgressiveImageLoader\u003C/span>(img);\n});\n\u003C/code>\u003C/pre>\u003Ch3 id=\"memory-usage-issues\">Memory Usage Issues\u003C/h3>\n\u003Cp>\u003Cstrong>Problem\u003C/strong>: High memory consumption from loading multiple large images\u003C/p>\n\u003Cp>\u003Cstrong>Solutions\u003C/strong>:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-javascript\">\u003Cspan class=\"hljs-comment\">// Memory-efficient image management\u003C/span>\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">ImageMemoryManager\u003C/span> {\n    \u003Cspan class=\"hljs-title function_\">constructor\u003C/span>(\u003Cspan class=\"hljs-params\">options = {}\u003C/span>) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">maxImages\u003C/span> = options.\u003Cspan class=\"hljs-property\">maxImages\u003C/span> || \u003Cspan class=\"hljs-number\">20\u003C/span>;\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">loadedImages\u003C/span> = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Map\u003C/span>();\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">observer\u003C/span> = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">IntersectionObserver\u003C/span>(\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">handleIntersection\u003C/span>.\u003Cspan class=\"hljs-title function_\">bind\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>),\n            { \u003Cspan class=\"hljs-attr\">rootMargin\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;200px 0px&#x27;\u003C/span> }\n        );\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">handleIntersection\u003C/span>(\u003Cspan class=\"hljs-params\">entries\u003C/span>) {\n        entries.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">entry\u003C/span> =&gt;\u003C/span> {\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (entry.\u003Cspan class=\"hljs-property\">isIntersecting\u003C/span>) {\n                \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">loadImage\u003C/span>(entry.\u003Cspan class=\"hljs-property\">target\u003C/span>);\n            } \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">isInViewport\u003C/span>(entry.\u003Cspan class=\"hljs-property\">target\u003C/span>)) {\n                \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">unloadImage\u003C/span>(entry.\u003Cspan class=\"hljs-property\">target\u003C/span>);\n            }\n        });\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">loadImage\u003C/span>(\u003Cspan class=\"hljs-params\">img\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">loadedImages\u003C/span>.\u003Cspan class=\"hljs-property\">size\u003C/span> &gt;= \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">maxImages\u003C/span>) {\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">unloadOldestImage\u003C/span>();\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> originalSrc = img.\u003Cspan class=\"hljs-property\">dataset\u003C/span>.\u003Cspan class=\"hljs-property\">src\u003C/span>;\n        img.\u003Cspan class=\"hljs-property\">src\u003C/span> = originalSrc;\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">loadedImages\u003C/span>.\u003Cspan class=\"hljs-title function_\">set\u003C/span>(img, {\n            \u003Cspan class=\"hljs-attr\">src\u003C/span>: originalSrc,\n            \u003Cspan class=\"hljs-attr\">loadTime\u003C/span>: \u003Cspan class=\"hljs-title class_\">Date\u003C/span>.\u003Cspan class=\"hljs-title function_\">now\u003C/span>()\n        });\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">unloadImage\u003C/span>(\u003Cspan class=\"hljs-params\">img\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">loadedImages\u003C/span>.\u003Cspan class=\"hljs-title function_\">has\u003C/span>(img)) {\n            img.\u003Cspan class=\"hljs-property\">src\u003C/span> = img.\u003Cspan class=\"hljs-property\">dataset\u003C/span>.\u003Cspan class=\"hljs-property\">placeholder\u003C/span> || \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>;\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">loadedImages\u003C/span>.\u003Cspan class=\"hljs-title function_\">delete\u003C/span>(img);\n        }\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">unloadOldestImage\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">let\u003C/span> oldestImg = \u003Cspan class=\"hljs-literal\">null\u003C/span>;\n        \u003Cspan class=\"hljs-keyword\">let\u003C/span> oldestTime = \u003Cspan class=\"hljs-title class_\">Date\u003C/span>.\u003Cspan class=\"hljs-title function_\">now\u003C/span>();\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> (\u003Cspan class=\"hljs-keyword\">const\u003C/span> [img, data] \u003Cspan class=\"hljs-keyword\">of\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">loadedImages\u003C/span>) {\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (data.\u003Cspan class=\"hljs-property\">loadTime\u003C/span> &lt; oldestTime &amp;&amp; !\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">isInViewport\u003C/span>(img)) {\n                oldestTime = data.\u003Cspan class=\"hljs-property\">loadTime\u003C/span>;\n                oldestImg = img;\n            }\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (oldestImg) {\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">unloadImage\u003C/span>(oldestImg);\n        }\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">isInViewport\u003C/span>(\u003Cspan class=\"hljs-params\">img\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> rect = img.\u003Cspan class=\"hljs-title function_\">getBoundingClientRect\u003C/span>();\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> rect.\u003Cspan class=\"hljs-property\">bottom\u003C/span> &gt;= \u003Cspan class=\"hljs-number\">0\u003C/span> &amp;&amp; rect.\u003Cspan class=\"hljs-property\">top\u003C/span> &lt;= \u003Cspan class=\"hljs-variable language_\">window\u003C/span>.\u003Cspan class=\"hljs-property\">innerHeight\u003C/span>;\n    }\n}\n\n\u003Cspan class=\"hljs-comment\">// Initialize memory management\u003C/span>\n\u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">ImageMemoryManager\u003C/span>({ \u003Cspan class=\"hljs-attr\">maxImages\u003C/span>: \u003Cspan class=\"hljs-number\">15\u003C/span> });\n\u003C/code>\u003C/pre>\u003Ch2 id=\"conclusion\">Conclusion\u003C/h2>\n\u003Cp>Image optimization and compression represent critical performance factors in modern Markdown documentation and content systems, directly impacting user experience, search engine rankings, and operational costs. By implementing comprehensive optimization workflows that balance quality with file size, automated processing pipelines, and progressive loading strategies, content creators can deliver visually rich documentation that loads quickly across all devices and network conditions.\u003C/p>\n\u003Cp>The key to successful image optimization lies in understanding the trade-offs between different formats, implementing responsive delivery systems, and automating optimization processes to maintain consistency as content scales. Whether you&#39;re building technical documentation, knowledge bases, or content-heavy websites, the techniques covered in this guide provide the foundation for image optimization that enhances user experience while reducing bandwidth costs and improving search engine performance.\u003C/p>\n\u003Cp>Remember to test your optimization strategies across different devices and connection speeds, monitor Core Web Vitals to measure real-world performance impact, and continuously refine your workflows based on usage patterns and user feedback. With proper image optimization implementation, your Markdown content can deliver exceptional visual experiences without compromising the speed and accessibility that modern users expect from professional documentation systems.\u003C/p>\n",[15,19,22,25,28,31,34,37],{"id":16,"text":17,"level":18},"why-master-image-optimization-for-markdown","Why Master Image Optimization for Markdown?",2,{"id":20,"text":21,"level":18},"understanding-image-optimization-fundamentals","Understanding Image Optimization Fundamentals",{"id":23,"text":24,"level":18},"automated-optimization-workflows","Automated Optimization Workflows",{"id":26,"text":27,"level":18},"jekyll-and-hugo-integration","Jekyll and Hugo Integration",{"id":29,"text":30,"level":18},"lazy-loading-and-performance-enhancement","Lazy Loading and Performance Enhancement",{"id":32,"text":33,"level":18},"integration-with-modern-workflows","Integration with Modern Workflows",{"id":35,"text":36,"level":18},"troubleshooting-common-optimization-issues","Troubleshooting Common Optimization Issues",{"id":38,"text":39,"level":18},"conclusion","Conclusion",[],[42,50,58],{"slug":43,"title":44,"description":45,"excerpt":46,"date":47,"category":9,"author":10,"keywords":48,"readingMinutes":49},"markdown-performance-optimization-best-practices-complete-guide","Markdown Performance Optimization and Best Practices: Complete Guide for High-Performance Documentation Systems","Master advanced Markdown performance optimization techniques for fast-loading documentation, efficient parsing, and scalable content systems. Learn caching strategies, asset optimization, and performance monitoring for Markdown-based sites.","Advanced Markdown performance optimization and best practices enable high-performance documentation systems that deliver exceptional user experiences while maintaining scalability across large…","2025-11-24","markdown performance optimization, markdown best practices, documentation performance, markdown parsing optimization, static site performance, markdown caching, content delivery optimization, markdown asset management",28,{"slug":51,"title":52,"description":53,"excerpt":54,"date":55,"category":9,"author":10,"keywords":56,"readingMinutes":57},"markdown-performance-optimization-rendering-speed-guide","Markdown Performance Optimization and Rendering Speed: Complete Guide for High-Performance Documentation Systems","Master Markdown performance optimization techniques for faster rendering, efficient processing, and scalable documentation systems. Learn caching strategies, parser optimization, and performance monitoring for large-scale content management.","Advanced Markdown performance optimization enables high-speed rendering and efficient processing for large-scale documentation systems that handle thousands of documents with complex content…","2025-09-30","markdown performance, markdown rendering speed, markdown optimization, markdown parser performance, documentation performance, markdown caching, static site performance, markdown processing speed",25,{"slug":59,"title":60,"description":61,"excerpt":62,"date":63,"category":9,"author":10,"keywords":64,"readingMinutes":65},"markdown-performance-optimization-complete-guide","Markdown Performance Optimization: Complete Guide for High-Volume Content Processing and Rendering Efficiency","Master advanced Markdown performance optimization techniques for large-scale content processing, rendering efficiency, and high-volume documentation systems. Learn caching strategies, parsing optimization, and performance monitoring for Markdown workflows.","Advanced Markdown performance optimization techniques enable high-volume content processing systems that deliver exceptional rendering speeds, efficient memory usage, and scalable processing…","2025-10-28","markdown performance optimization, markdown parsing performance, markdown rendering speed, markdown content caching, large scale markdown, markdown processing efficiency, markdown performance monitoring, markdown optimization techniques",22,1792184942206]