[{"data":1,"prerenderedAt":8874},["ShallowReactive",2],{"blog-suitecommerce-image-optimization-developer-guide":3,"all-blog-posts":8677},{"id":4,"title":5,"author":6,"body":7,"categories":8659,"date":8662,"description":8663,"extension":8664,"heroImage":8665,"meta":8666,"navigation":287,"path":8667,"relatedArticles":8668,"seo":8669,"stem":8670,"tags":8671,"__hash__":8676},"content\u002Fblog\u002Fsuitecommerce-image-optimization-developer-guide.md","SuiteCommerce Image Optimization: A Developer's Guide","Stenbase Team",{"type":8,"value":9,"toc":8599},"minimark",[10,14,22,25,28,33,98,100,103,106,109,114,196,199,203,206,209,213,216,231,234,236,239,242,246,249,254,257,398,401,421,425,428,529,533,540,672,677,1173,1177,1180,1795,1797,1800,1803,1807,1810,1860,1874,1878,1881,2796,2801,2864,2869,3161,3165,3172,3215,3221,3227,3229,3232,3235,3241,3245,3255,3364,3367,3381,3385,3390,4132,4137,4433,4438,4508,4512,4515,4990,4992,4995,4998,5002,5005,5031,5034,5038,5041,5046,5054,5059,5065,5070,5076,5081,5087,5091,5094,5243,5247,5250,5569,5571,5574,5577,5581,5584,5669,5673,5676,6298,6302,6305,6891,6893,6896,6899,6903,6909,6913,7899,7903,7969,7971,7974,7977,7983,7987,8057,8061,8064,8277,8281,8284,8375,8377,8380,8384,8390,8401,8405,8410,8424,8483,8487,8492,8502,8506,8511,8516,8520,8525,8530,8532,8535,8539,8545,8549,8552,8556,8559,8563,8566,8570,8573,8575,8579,8582,8590,8595],[11,12,5],"h1",{"id":13},"suitecommerce-image-optimization-a-developers-guide",[15,16,17,21],"p",{},[18,19,20],"strong",{},"Images account for 75% of total page weight on the average SuiteCommerce store."," They're also the single largest contributor to poor Largest Contentful Paint (LCP) scores—the Core Web Vital that Google uses to evaluate loading performance. After auditing hundreds of SuiteCommerce sites, we've found that image optimization alone can reduce page weight by 40-60% and cut LCP times in half.",[15,23,24],{},"This isn't about vague best practices. This guide gives you specific implementation details for WebP conversion, lazy loading, responsive images, CDN configuration, and building custom image optimization extensions. Every technique includes code examples you can deploy today.",[26,27],"hr",{},[29,30,32],"h2",{"id":31},"table-of-contents","Table of Contents",[34,35,36,44,50,56,62,68,74,80,86,92],"ol",{},[37,38,39],"li",{},[40,41,43],"a",{"href":42},"#why-images-matter-for-suitecommerce-performance","Why Images Matter for SuiteCommerce Performance",[37,45,46],{},[40,47,49],{"href":48},"#image-format-selection-webp-avif-and-fallbacks","Image Format Selection: WebP, AVIF, and Fallbacks",[37,51,52],{},[40,53,55],{"href":54},"#implementing-lazy-loading-in-suitecommerce","Implementing Lazy Loading in SuiteCommerce",[37,57,58],{},[40,59,61],{"href":60},"#responsive-images-for-suitecommerce-themes","Responsive Images for SuiteCommerce Themes",[37,63,64],{},[40,65,67],{"href":66},"#cdn-configuration-for-images","CDN Configuration for Images",[37,69,70],{},[40,71,73],{"href":72},"#optimizing-product-images-at-upload","Optimizing Product Images at Upload",[37,75,76],{},[40,77,79],{"href":78},"#building-an-image-optimization-extension","Building an Image Optimization Extension",[37,81,82],{},[40,83,85],{"href":84},"#measuring-image-performance-impact","Measuring Image Performance Impact",[37,87,88],{},[40,89,91],{"href":90},"#common-pitfalls-and-how-to-avoid-them","Common Pitfalls and How to Avoid Them",[37,93,94],{},[40,95,97],{"href":96},"#faq","FAQ",[26,99],{},[29,101,43],{"id":102},"why-images-matter-for-suitecommerce-performance",[15,104,105],{},"Let's put numbers to the problem.",[15,107,108],{},"A typical SuiteCommerce product listing page loads 20-40 product images. Without optimization, each image averages 200-500KB. That's 4-20MB of images per page—before any other assets load.",[110,111,113],"h3",{"id":112},"the-performance-impact","The Performance Impact",[115,116,117,136],"table",{},[118,119,120],"thead",{},[121,122,123,127,130,133],"tr",{},[124,125,126],"th",{},"Metric",[124,128,129],{},"Unoptimized",[124,131,132],{},"Optimized",[124,134,135],{},"Improvement",[137,138,139,154,168,182],"tbody",{},[121,140,141,145,148,151],{},[142,143,144],"td",{},"Product listing page weight",[142,146,147],{},"8.2MB",[142,149,150],{},"2.1MB",[142,152,153],{},"74% reduction",[121,155,156,159,162,165],{},[142,157,158],{},"Time to LCP",[142,160,161],{},"4.8s",[142,163,164],{},"1.9s",[142,166,167],{},"60% faster",[121,169,170,173,176,179],{},[142,171,172],{},"Mobile load time (3G)",[142,174,175],{},"18s+",[142,177,178],{},"6s",[142,180,181],{},"66% faster",[121,183,184,187,190,193],{},[142,185,186],{},"Image requests",[142,188,189],{},"45",[142,191,192],{},"12 (above fold)",[142,194,195],{},"73% fewer initial",[15,197,198],{},"Those aren't theoretical numbers. They're from a recent SuiteCommerce optimization project where images were the primary bottleneck.",[110,200,202],{"id":201},"the-business-impact","The Business Impact",[15,204,205],{},"Google's research shows that a 100ms delay in load time reduces conversion rates by 7%. When your competitor's page loads in 2 seconds and yours takes 5 seconds, you're losing sales—not because of your products, but because of your image delivery.",[15,207,208],{},"Mobile users are even less patient. 53% of mobile users abandon sites that take longer than 3 seconds to load. If your images are pushing you past that threshold, you're sending traffic to competitors.",[110,210,212],{"id":211},"how-suitecommerce-handles-images-by-default","How SuiteCommerce Handles Images by Default",[15,214,215],{},"Out of the box, SuiteCommerce:",[217,218,219,222,225,228],"ul",{},[37,220,221],{},"Serves images in their original upload format (usually JPEG or PNG)",[37,223,224],{},"Doesn't implement lazy loading",[37,226,227],{},"Doesn't generate responsive image variants",[37,229,230],{},"Relies on basic browser caching with limited control",[15,232,233],{},"This default configuration was acceptable in 2018. It's a serious liability in 2025.",[26,235],{},[29,237,49],{"id":238},"image-format-selection-webp-avif-and-fallbacks",[15,240,241],{},"Modern image formats deliver the same visual quality at 30-50% smaller file sizes. Supporting them requires format detection and fallback logic.",[110,243,245],{"id":244},"webp-the-current-standard","WebP: The Current Standard",[15,247,248],{},"WebP provides 25-35% smaller file sizes than JPEG at equivalent quality. Browser support is now universal—97%+ of global users can view WebP images natively.",[15,250,251],{},[18,252,253],{},"Converting images to WebP:",[15,255,256],{},"If you're managing product images through NetSuite's File Cabinet, convert images before upload:",[258,259,264],"pre",{"className":260,"code":261,"language":262,"meta":263,"style":263},"language-bash shiki shiki-themes github-light github-dark","# Using cwebp (Google's WebP converter)\n# Install: brew install webp (macOS) or apt install webp (Linux)\n\n# Convert single image\ncwebp -q 80 input.jpg -o output.webp\n\n# Batch convert directory\nfor file in *.jpg; do\n    cwebp -q 80 \"$file\" -o \"${file%.jpg}.webp\"\ndone\n","bash","",[265,266,267,276,282,289,295,319,324,330,353,392],"code",{"__ignoreMap":263},[268,269,272],"span",{"class":270,"line":271},"line",1,[268,273,275],{"class":274},"sJ8bj","# Using cwebp (Google's WebP converter)\n",[268,277,279],{"class":270,"line":278},2,[268,280,281],{"class":274},"# Install: brew install webp (macOS) or apt install webp (Linux)\n",[268,283,285],{"class":270,"line":284},3,[268,286,288],{"emptyLinePlaceholder":287},true,"\n",[268,290,292],{"class":270,"line":291},4,[268,293,294],{"class":274},"# Convert single image\n",[268,296,298,302,306,309,313,316],{"class":270,"line":297},5,[268,299,301],{"class":300},"sScJk","cwebp",[268,303,305],{"class":304},"sj4cs"," -q",[268,307,308],{"class":304}," 80",[268,310,312],{"class":311},"sZZnC"," input.jpg",[268,314,315],{"class":304}," -o",[268,317,318],{"class":311}," output.webp\n",[268,320,322],{"class":270,"line":321},6,[268,323,288],{"emptyLinePlaceholder":287},[268,325,327],{"class":270,"line":326},7,[268,328,329],{"class":274},"# Batch convert directory\n",[268,331,333,337,341,344,347,350],{"class":270,"line":332},8,[268,334,336],{"class":335},"szBVR","for",[268,338,340],{"class":339},"sVt8B"," file ",[268,342,343],{"class":335},"in",[268,345,346],{"class":311}," *.jpg",[268,348,349],{"class":339},"; ",[268,351,352],{"class":335},"do\n",[268,354,356,359,361,363,366,369,372,374,377,380,383,386,389],{"class":270,"line":355},9,[268,357,358],{"class":300},"    cwebp",[268,360,305],{"class":304},[268,362,308],{"class":304},[268,364,365],{"class":311}," \"",[268,367,368],{"class":339},"$file",[268,370,371],{"class":311},"\"",[268,373,315],{"class":304},[268,375,376],{"class":311}," \"${",[268,378,379],{"class":339},"file",[268,381,382],{"class":335},"%",[268,384,385],{"class":311},".",[268,387,388],{"class":339},"jpg",[268,390,391],{"class":311},"}.webp\"\n",[268,393,395],{"class":270,"line":394},10,[268,396,397],{"class":335},"done\n",[15,399,400],{},"For quality settings:",[217,402,403,409,415],{},[37,404,405,408],{},[18,406,407],{},"Product images",": Quality 80-85 (balances file size and detail)",[37,410,411,414],{},[18,412,413],{},"Lifestyle\u002Fhero images",": Quality 85-90 (preserves more detail)",[37,416,417,420],{},[18,418,419],{},"Thumbnails",": Quality 70-75 (detail matters less at small sizes)",[110,422,424],{"id":423},"avif-the-next-generation","AVIF: The Next Generation",[15,426,427],{},"AVIF offers 20% additional compression over WebP with better color depth. Browser support is at 92% and growing. The catch: encoding is significantly slower.",[258,429,431],{"className":260,"code":430,"language":262,"meta":263,"style":263},"# Using avifenc\navifenc --min 20 --max 40 --speed 4 input.jpg output.avif\n\n# Batch convert\nfor file in *.jpg; do\n    avifenc --min 20 --max 40 --speed 4 \"$file\" \"${file%.jpg}.avif\"\ndone\n",[265,432,433,438,466,470,475,489,525],{"__ignoreMap":263},[268,434,435],{"class":270,"line":271},[268,436,437],{"class":274},"# Using avifenc\n",[268,439,440,443,446,449,452,455,458,461,463],{"class":270,"line":278},[268,441,442],{"class":300},"avifenc",[268,444,445],{"class":304}," --min",[268,447,448],{"class":304}," 20",[268,450,451],{"class":304}," --max",[268,453,454],{"class":304}," 40",[268,456,457],{"class":304}," --speed",[268,459,460],{"class":304}," 4",[268,462,312],{"class":311},[268,464,465],{"class":311}," output.avif\n",[268,467,468],{"class":270,"line":284},[268,469,288],{"emptyLinePlaceholder":287},[268,471,472],{"class":270,"line":291},[268,473,474],{"class":274},"# Batch convert\n",[268,476,477,479,481,483,485,487],{"class":270,"line":297},[268,478,336],{"class":335},[268,480,340],{"class":339},[268,482,343],{"class":335},[268,484,346],{"class":311},[268,486,349],{"class":339},[268,488,352],{"class":335},[268,490,491,494,496,498,500,502,504,506,508,510,512,514,516,518,520,522],{"class":270,"line":321},[268,492,493],{"class":300},"    avifenc",[268,495,445],{"class":304},[268,497,448],{"class":304},[268,499,451],{"class":304},[268,501,454],{"class":304},[268,503,457],{"class":304},[268,505,460],{"class":304},[268,507,365],{"class":311},[268,509,368],{"class":339},[268,511,371],{"class":311},[268,513,376],{"class":311},[268,515,379],{"class":339},[268,517,382],{"class":335},[268,519,385],{"class":311},[268,521,388],{"class":339},[268,523,524],{"class":311},"}.avif\"\n",[268,526,527],{"class":270,"line":326},[268,528,397],{"class":335},[110,530,532],{"id":531},"implementing-format-fallbacks-in-suitecommerce","Implementing Format Fallbacks in SuiteCommerce",[15,534,535,536,539],{},"The ",[265,537,538],{},"\u003Cpicture>"," element lets you serve modern formats with fallbacks:",[258,541,545],{"className":542,"code":543,"language":544,"meta":263,"style":263},"language-handlebars shiki shiki-themes github-light github-dark","{{!-- product_image.tpl --}}\n\u003Cpicture class=\"product-image-container\">\n    {{#if hasAvif}}\n        \u003Csource \n            srcset=\"{{avifUrl}}\" \n            type=\"image\u002Favif\"\n        \u002F>\n    {{\u002Fif}}\n    {{#if hasWebp}}\n        \u003Csource \n            srcset=\"{{webpUrl}}\" \n            type=\"image\u002Fwebp\"\n        \u002F>\n    {{\u002Fif}}\n    \u003Cimg \n        src=\"{{imageUrl}}\" \n        alt=\"{{altText}}\"\n        class=\"product-image\"\n        loading=\"lazy\"\n        width=\"{{width}}\"\n        height=\"{{height}}\"\n    \u002F>\n\u003C\u002Fpicture>\n","handlebars",[265,546,547,552,557,562,567,572,577,582,587,592,596,602,608,613,618,624,630,636,642,648,654,660,666],{"__ignoreMap":263},[268,548,549],{"class":270,"line":271},[268,550,551],{},"{{!-- product_image.tpl --}}\n",[268,553,554],{"class":270,"line":278},[268,555,556],{},"\u003Cpicture class=\"product-image-container\">\n",[268,558,559],{"class":270,"line":284},[268,560,561],{},"    {{#if hasAvif}}\n",[268,563,564],{"class":270,"line":291},[268,565,566],{},"        \u003Csource \n",[268,568,569],{"class":270,"line":297},[268,570,571],{},"            srcset=\"{{avifUrl}}\" \n",[268,573,574],{"class":270,"line":321},[268,575,576],{},"            type=\"image\u002Favif\"\n",[268,578,579],{"class":270,"line":326},[268,580,581],{},"        \u002F>\n",[268,583,584],{"class":270,"line":332},[268,585,586],{},"    {{\u002Fif}}\n",[268,588,589],{"class":270,"line":355},[268,590,591],{},"    {{#if hasWebp}}\n",[268,593,594],{"class":270,"line":394},[268,595,566],{},[268,597,599],{"class":270,"line":598},11,[268,600,601],{},"            srcset=\"{{webpUrl}}\" \n",[268,603,605],{"class":270,"line":604},12,[268,606,607],{},"            type=\"image\u002Fwebp\"\n",[268,609,611],{"class":270,"line":610},13,[268,612,581],{},[268,614,616],{"class":270,"line":615},14,[268,617,586],{},[268,619,621],{"class":270,"line":620},15,[268,622,623],{},"    \u003Cimg \n",[268,625,627],{"class":270,"line":626},16,[268,628,629],{},"        src=\"{{imageUrl}}\" \n",[268,631,633],{"class":270,"line":632},17,[268,634,635],{},"        alt=\"{{altText}}\"\n",[268,637,639],{"class":270,"line":638},18,[268,640,641],{},"        class=\"product-image\"\n",[268,643,645],{"class":270,"line":644},19,[268,646,647],{},"        loading=\"lazy\"\n",[268,649,651],{"class":270,"line":650},20,[268,652,653],{},"        width=\"{{width}}\"\n",[268,655,657],{"class":270,"line":656},21,[268,658,659],{},"        height=\"{{height}}\"\n",[268,661,663],{"class":270,"line":662},22,[268,664,665],{},"    \u002F>\n",[268,667,669],{"class":270,"line":668},23,[268,670,671],{},"\u003C\u002Fpicture>\n",[15,673,674],{},[18,675,676],{},"Creating a View helper for format detection:",[258,678,682],{"className":679,"code":680,"language":681,"meta":263,"style":263},"language-javascript shiki shiki-themes github-light github-dark","\u002F\u002F ImageFormatHelper.js\ndefine('ImageFormatHelper', [\n    'underscore'\n], function(_) {\n    'use strict';\n\n    var formatSuffixes = {\n        webp: '.webp',\n        avif: '.avif'\n    };\n\n    return {\n        \u002F**\n         * Generate URLs for multiple image formats\n         * @param {string} baseUrl - Original image URL\n         * @returns {Object} URLs for different formats\n         *\u002F\n        getFormatUrls: function(baseUrl) {\n            if (!baseUrl) {\n                return {};\n            }\n\n            \u002F\u002F Extract base path without extension\n            var lastDot = baseUrl.lastIndexOf('.');\n            var basePath = baseUrl.substring(0, lastDot);\n            var originalExt = baseUrl.substring(lastDot);\n\n            return {\n                original: baseUrl,\n                webp: basePath + formatSuffixes.webp,\n                avif: basePath + formatSuffixes.avif,\n                hasWebp: this.webpExists(basePath + formatSuffixes.webp),\n                hasAvif: this.avifExists(basePath + formatSuffixes.avif)\n            };\n        },\n\n        \u002F**\n         * Check if WebP version exists\n         * In practice, this checks your CDN\u002Ffile naming convention\n         *\u002F\n        webpExists: function(url) {\n            \u002F\u002F If you're auto-generating WebP, assume it exists\n            \u002F\u002F For explicit file checking, implement server-side validation\n            return true;\n        },\n\n        avifExists: function(url) {\n            \u002F\u002F AVIF support may be selective\n            return false; \u002F\u002F Enable when AVIF generation is configured\n        }\n    };\n});\n","javascript",[265,683,684,689,703,708,725,733,737,751,762,770,775,779,786,791,796,813,826,831,848,862,870,875,879,884,909,932,949,954,962,968,980,991,1013,1033,1039,1045,1050,1055,1061,1067,1072,1089,1095,1101,1111,1116,1121,1137,1143,1156,1162,1167],{"__ignoreMap":263},[268,685,686],{"class":270,"line":271},[268,687,688],{"class":274},"\u002F\u002F ImageFormatHelper.js\n",[268,690,691,694,697,700],{"class":270,"line":278},[268,692,693],{"class":300},"define",[268,695,696],{"class":339},"(",[268,698,699],{"class":311},"'ImageFormatHelper'",[268,701,702],{"class":339},", [\n",[268,704,705],{"class":270,"line":284},[268,706,707],{"class":311},"    'underscore'\n",[268,709,710,713,716,718,722],{"class":270,"line":291},[268,711,712],{"class":339},"], ",[268,714,715],{"class":335},"function",[268,717,696],{"class":339},[268,719,721],{"class":720},"s4XuR","_",[268,723,724],{"class":339},") {\n",[268,726,727,730],{"class":270,"line":297},[268,728,729],{"class":311},"    'use strict'",[268,731,732],{"class":339},";\n",[268,734,735],{"class":270,"line":321},[268,736,288],{"emptyLinePlaceholder":287},[268,738,739,742,745,748],{"class":270,"line":326},[268,740,741],{"class":335},"    var",[268,743,744],{"class":339}," formatSuffixes ",[268,746,747],{"class":335},"=",[268,749,750],{"class":339}," {\n",[268,752,753,756,759],{"class":270,"line":332},[268,754,755],{"class":339},"        webp: ",[268,757,758],{"class":311},"'.webp'",[268,760,761],{"class":339},",\n",[268,763,764,767],{"class":270,"line":355},[268,765,766],{"class":339},"        avif: ",[268,768,769],{"class":311},"'.avif'\n",[268,771,772],{"class":270,"line":394},[268,773,774],{"class":339},"    };\n",[268,776,777],{"class":270,"line":598},[268,778,288],{"emptyLinePlaceholder":287},[268,780,781,784],{"class":270,"line":604},[268,782,783],{"class":335},"    return",[268,785,750],{"class":339},[268,787,788],{"class":270,"line":610},[268,789,790],{"class":274},"        \u002F**\n",[268,792,793],{"class":270,"line":615},[268,794,795],{"class":274},"         * Generate URLs for multiple image formats\n",[268,797,798,801,804,807,810],{"class":270,"line":620},[268,799,800],{"class":274},"         * ",[268,802,803],{"class":335},"@param",[268,805,806],{"class":300}," {string}",[268,808,809],{"class":339}," baseUrl",[268,811,812],{"class":274}," - Original image URL\n",[268,814,815,817,820,823],{"class":270,"line":626},[268,816,800],{"class":274},[268,818,819],{"class":335},"@returns",[268,821,822],{"class":300}," {Object}",[268,824,825],{"class":274}," URLs for different formats\n",[268,827,828],{"class":270,"line":632},[268,829,830],{"class":274},"         *\u002F\n",[268,832,833,836,839,841,843,846],{"class":270,"line":638},[268,834,835],{"class":300},"        getFormatUrls",[268,837,838],{"class":339},": ",[268,840,715],{"class":335},[268,842,696],{"class":339},[268,844,845],{"class":720},"baseUrl",[268,847,724],{"class":339},[268,849,850,853,856,859],{"class":270,"line":644},[268,851,852],{"class":335},"            if",[268,854,855],{"class":339}," (",[268,857,858],{"class":335},"!",[268,860,861],{"class":339},"baseUrl) {\n",[268,863,864,867],{"class":270,"line":650},[268,865,866],{"class":335},"                return",[268,868,869],{"class":339}," {};\n",[268,871,872],{"class":270,"line":656},[268,873,874],{"class":339},"            }\n",[268,876,877],{"class":270,"line":662},[268,878,288],{"emptyLinePlaceholder":287},[268,880,881],{"class":270,"line":668},[268,882,883],{"class":274},"            \u002F\u002F Extract base path without extension\n",[268,885,887,890,893,895,898,901,903,906],{"class":270,"line":886},24,[268,888,889],{"class":335},"            var",[268,891,892],{"class":339}," lastDot ",[268,894,747],{"class":335},[268,896,897],{"class":339}," baseUrl.",[268,899,900],{"class":300},"lastIndexOf",[268,902,696],{"class":339},[268,904,905],{"class":311},"'.'",[268,907,908],{"class":339},");\n",[268,910,912,914,917,919,921,924,926,929],{"class":270,"line":911},25,[268,913,889],{"class":335},[268,915,916],{"class":339}," basePath ",[268,918,747],{"class":335},[268,920,897],{"class":339},[268,922,923],{"class":300},"substring",[268,925,696],{"class":339},[268,927,928],{"class":304},"0",[268,930,931],{"class":339},", lastDot);\n",[268,933,935,937,940,942,944,946],{"class":270,"line":934},26,[268,936,889],{"class":335},[268,938,939],{"class":339}," originalExt ",[268,941,747],{"class":335},[268,943,897],{"class":339},[268,945,923],{"class":300},[268,947,948],{"class":339},"(lastDot);\n",[268,950,952],{"class":270,"line":951},27,[268,953,288],{"emptyLinePlaceholder":287},[268,955,957,960],{"class":270,"line":956},28,[268,958,959],{"class":335},"            return",[268,961,750],{"class":339},[268,963,965],{"class":270,"line":964},29,[268,966,967],{"class":339},"                original: baseUrl,\n",[268,969,971,974,977],{"class":270,"line":970},30,[268,972,973],{"class":339},"                webp: basePath ",[268,975,976],{"class":335},"+",[268,978,979],{"class":339}," formatSuffixes.webp,\n",[268,981,983,986,988],{"class":270,"line":982},31,[268,984,985],{"class":339},"                avif: basePath ",[268,987,976],{"class":335},[268,989,990],{"class":339}," formatSuffixes.avif,\n",[268,992,994,997,1000,1002,1005,1008,1010],{"class":270,"line":993},32,[268,995,996],{"class":339},"                hasWebp: ",[268,998,999],{"class":304},"this",[268,1001,385],{"class":339},[268,1003,1004],{"class":300},"webpExists",[268,1006,1007],{"class":339},"(basePath ",[268,1009,976],{"class":335},[268,1011,1012],{"class":339}," formatSuffixes.webp),\n",[268,1014,1016,1019,1021,1023,1026,1028,1030],{"class":270,"line":1015},33,[268,1017,1018],{"class":339},"                hasAvif: ",[268,1020,999],{"class":304},[268,1022,385],{"class":339},[268,1024,1025],{"class":300},"avifExists",[268,1027,1007],{"class":339},[268,1029,976],{"class":335},[268,1031,1032],{"class":339}," formatSuffixes.avif)\n",[268,1034,1036],{"class":270,"line":1035},34,[268,1037,1038],{"class":339},"            };\n",[268,1040,1042],{"class":270,"line":1041},35,[268,1043,1044],{"class":339},"        },\n",[268,1046,1048],{"class":270,"line":1047},36,[268,1049,288],{"emptyLinePlaceholder":287},[268,1051,1053],{"class":270,"line":1052},37,[268,1054,790],{"class":274},[268,1056,1058],{"class":270,"line":1057},38,[268,1059,1060],{"class":274},"         * Check if WebP version exists\n",[268,1062,1064],{"class":270,"line":1063},39,[268,1065,1066],{"class":274},"         * In practice, this checks your CDN\u002Ffile naming convention\n",[268,1068,1070],{"class":270,"line":1069},40,[268,1071,830],{"class":274},[268,1073,1075,1078,1080,1082,1084,1087],{"class":270,"line":1074},41,[268,1076,1077],{"class":300},"        webpExists",[268,1079,838],{"class":339},[268,1081,715],{"class":335},[268,1083,696],{"class":339},[268,1085,1086],{"class":720},"url",[268,1088,724],{"class":339},[268,1090,1092],{"class":270,"line":1091},42,[268,1093,1094],{"class":274},"            \u002F\u002F If you're auto-generating WebP, assume it exists\n",[268,1096,1098],{"class":270,"line":1097},43,[268,1099,1100],{"class":274},"            \u002F\u002F For explicit file checking, implement server-side validation\n",[268,1102,1104,1106,1109],{"class":270,"line":1103},44,[268,1105,959],{"class":335},[268,1107,1108],{"class":304}," true",[268,1110,732],{"class":339},[268,1112,1114],{"class":270,"line":1113},45,[268,1115,1044],{"class":339},[268,1117,1119],{"class":270,"line":1118},46,[268,1120,288],{"emptyLinePlaceholder":287},[268,1122,1124,1127,1129,1131,1133,1135],{"class":270,"line":1123},47,[268,1125,1126],{"class":300},"        avifExists",[268,1128,838],{"class":339},[268,1130,715],{"class":335},[268,1132,696],{"class":339},[268,1134,1086],{"class":720},[268,1136,724],{"class":339},[268,1138,1140],{"class":270,"line":1139},48,[268,1141,1142],{"class":274},"            \u002F\u002F AVIF support may be selective\n",[268,1144,1146,1148,1151,1153],{"class":270,"line":1145},49,[268,1147,959],{"class":335},[268,1149,1150],{"class":304}," false",[268,1152,349],{"class":339},[268,1154,1155],{"class":274},"\u002F\u002F Enable when AVIF generation is configured\n",[268,1157,1159],{"class":270,"line":1158},50,[268,1160,1161],{"class":339},"        }\n",[268,1163,1165],{"class":270,"line":1164},51,[268,1166,774],{"class":339},[268,1168,1170],{"class":270,"line":1169},52,[268,1171,1172],{"class":339},"});\n",[110,1174,1176],{"id":1175},"server-side-format-selection","Server-Side Format Selection",[15,1178,1179],{},"For dynamic format selection, modify your image service controller:",[258,1181,1183],{"className":679,"code":1182,"language":681,"meta":263,"style":263},"\u002F\u002F ImageService.ServiceController.js\ndefine('ImageService.ServiceController', [\n    'ServiceController'\n], function(ServiceController) {\n    'use strict';\n\n    return ServiceController.extend({\n        \n        name: 'ImageService.ServiceController',\n\n        get: function() {\n            var imageId = this.request.getParameter('id');\n            var requestedFormat = this.request.getParameter('format');\n            var accept = this.request.getHeader('Accept') || '';\n            \n            \u002F\u002F Auto-detect best format from Accept header\n            var format = requestedFormat || this.detectBestFormat(accept);\n            \n            var imageUrl = this.getImageUrl(imageId, format);\n            \n            \u002F\u002F Redirect to optimized image\n            this.response.setHeader('Cache-Control', 'public, max-age=31536000');\n            this.response.setHeader('Vary', 'Accept');\n            \n            return {\n                url: imageUrl,\n                format: format\n            };\n        },\n        \n        detectBestFormat: function(acceptHeader) {\n            if (acceptHeader.indexOf('image\u002Favif') !== -1) {\n                return 'avif';\n            }\n            if (acceptHeader.indexOf('image\u002Fwebp') !== -1) {\n                return 'webp';\n            }\n            return 'jpeg';\n        },\n        \n        getImageUrl: function(imageId, format) {\n            \u002F\u002F Implementation depends on your image storage\n            var baseUrl = this.getBaseImageUrl(imageId);\n            \n            switch (format) {\n                case 'avif':\n                    return baseUrl.replace(\u002F\\.(jpg|jpeg|png)$\u002Fi, '.avif');\n                case 'webp':\n                    return baseUrl.replace(\u002F\\.(jpg|jpeg|png)$\u002Fi, '.webp');\n                default:\n                    return baseUrl;\n            }\n        }\n    });\n});\n",[265,1184,1185,1190,1201,1206,1219,1225,1229,1242,1247,1256,1260,1272,1297,1319,1351,1356,1361,1384,1388,1407,1411,1416,1440,1459,1463,1469,1474,1479,1483,1487,1491,1507,1535,1544,1548,1571,1580,1584,1593,1597,1601,1622,1627,1646,1650,1658,1668,1717,1725,1761,1768,1775,1779,1784,1790],{"__ignoreMap":263},[268,1186,1187],{"class":270,"line":271},[268,1188,1189],{"class":274},"\u002F\u002F ImageService.ServiceController.js\n",[268,1191,1192,1194,1196,1199],{"class":270,"line":278},[268,1193,693],{"class":300},[268,1195,696],{"class":339},[268,1197,1198],{"class":311},"'ImageService.ServiceController'",[268,1200,702],{"class":339},[268,1202,1203],{"class":270,"line":284},[268,1204,1205],{"class":311},"    'ServiceController'\n",[268,1207,1208,1210,1212,1214,1217],{"class":270,"line":291},[268,1209,712],{"class":339},[268,1211,715],{"class":335},[268,1213,696],{"class":339},[268,1215,1216],{"class":720},"ServiceController",[268,1218,724],{"class":339},[268,1220,1221,1223],{"class":270,"line":297},[268,1222,729],{"class":311},[268,1224,732],{"class":339},[268,1226,1227],{"class":270,"line":321},[268,1228,288],{"emptyLinePlaceholder":287},[268,1230,1231,1233,1236,1239],{"class":270,"line":326},[268,1232,783],{"class":335},[268,1234,1235],{"class":339}," ServiceController.",[268,1237,1238],{"class":300},"extend",[268,1240,1241],{"class":339},"({\n",[268,1243,1244],{"class":270,"line":332},[268,1245,1246],{"class":339},"        \n",[268,1248,1249,1252,1254],{"class":270,"line":355},[268,1250,1251],{"class":339},"        name: ",[268,1253,1198],{"class":311},[268,1255,761],{"class":339},[268,1257,1258],{"class":270,"line":394},[268,1259,288],{"emptyLinePlaceholder":287},[268,1261,1262,1265,1267,1269],{"class":270,"line":598},[268,1263,1264],{"class":300},"        get",[268,1266,838],{"class":339},[268,1268,715],{"class":335},[268,1270,1271],{"class":339},"() {\n",[268,1273,1274,1276,1279,1281,1284,1287,1290,1292,1295],{"class":270,"line":604},[268,1275,889],{"class":335},[268,1277,1278],{"class":339}," imageId ",[268,1280,747],{"class":335},[268,1282,1283],{"class":304}," this",[268,1285,1286],{"class":339},".request.",[268,1288,1289],{"class":300},"getParameter",[268,1291,696],{"class":339},[268,1293,1294],{"class":311},"'id'",[268,1296,908],{"class":339},[268,1298,1299,1301,1304,1306,1308,1310,1312,1314,1317],{"class":270,"line":610},[268,1300,889],{"class":335},[268,1302,1303],{"class":339}," requestedFormat ",[268,1305,747],{"class":335},[268,1307,1283],{"class":304},[268,1309,1286],{"class":339},[268,1311,1289],{"class":300},[268,1313,696],{"class":339},[268,1315,1316],{"class":311},"'format'",[268,1318,908],{"class":339},[268,1320,1321,1323,1326,1328,1330,1332,1335,1337,1340,1343,1346,1349],{"class":270,"line":615},[268,1322,889],{"class":335},[268,1324,1325],{"class":339}," accept ",[268,1327,747],{"class":335},[268,1329,1283],{"class":304},[268,1331,1286],{"class":339},[268,1333,1334],{"class":300},"getHeader",[268,1336,696],{"class":339},[268,1338,1339],{"class":311},"'Accept'",[268,1341,1342],{"class":339},") ",[268,1344,1345],{"class":335},"||",[268,1347,1348],{"class":311}," ''",[268,1350,732],{"class":339},[268,1352,1353],{"class":270,"line":620},[268,1354,1355],{"class":339},"            \n",[268,1357,1358],{"class":270,"line":626},[268,1359,1360],{"class":274},"            \u002F\u002F Auto-detect best format from Accept header\n",[268,1362,1363,1365,1368,1370,1372,1374,1376,1378,1381],{"class":270,"line":632},[268,1364,889],{"class":335},[268,1366,1367],{"class":339}," format ",[268,1369,747],{"class":335},[268,1371,1303],{"class":339},[268,1373,1345],{"class":335},[268,1375,1283],{"class":304},[268,1377,385],{"class":339},[268,1379,1380],{"class":300},"detectBestFormat",[268,1382,1383],{"class":339},"(accept);\n",[268,1385,1386],{"class":270,"line":638},[268,1387,1355],{"class":339},[268,1389,1390,1392,1395,1397,1399,1401,1404],{"class":270,"line":644},[268,1391,889],{"class":335},[268,1393,1394],{"class":339}," imageUrl ",[268,1396,747],{"class":335},[268,1398,1283],{"class":304},[268,1400,385],{"class":339},[268,1402,1403],{"class":300},"getImageUrl",[268,1405,1406],{"class":339},"(imageId, format);\n",[268,1408,1409],{"class":270,"line":650},[268,1410,1355],{"class":339},[268,1412,1413],{"class":270,"line":656},[268,1414,1415],{"class":274},"            \u002F\u002F Redirect to optimized image\n",[268,1417,1418,1421,1424,1427,1429,1432,1435,1438],{"class":270,"line":662},[268,1419,1420],{"class":304},"            this",[268,1422,1423],{"class":339},".response.",[268,1425,1426],{"class":300},"setHeader",[268,1428,696],{"class":339},[268,1430,1431],{"class":311},"'Cache-Control'",[268,1433,1434],{"class":339},", ",[268,1436,1437],{"class":311},"'public, max-age=31536000'",[268,1439,908],{"class":339},[268,1441,1442,1444,1446,1448,1450,1453,1455,1457],{"class":270,"line":668},[268,1443,1420],{"class":304},[268,1445,1423],{"class":339},[268,1447,1426],{"class":300},[268,1449,696],{"class":339},[268,1451,1452],{"class":311},"'Vary'",[268,1454,1434],{"class":339},[268,1456,1339],{"class":311},[268,1458,908],{"class":339},[268,1460,1461],{"class":270,"line":886},[268,1462,1355],{"class":339},[268,1464,1465,1467],{"class":270,"line":911},[268,1466,959],{"class":335},[268,1468,750],{"class":339},[268,1470,1471],{"class":270,"line":934},[268,1472,1473],{"class":339},"                url: imageUrl,\n",[268,1475,1476],{"class":270,"line":951},[268,1477,1478],{"class":339},"                format: format\n",[268,1480,1481],{"class":270,"line":956},[268,1482,1038],{"class":339},[268,1484,1485],{"class":270,"line":964},[268,1486,1044],{"class":339},[268,1488,1489],{"class":270,"line":970},[268,1490,1246],{"class":339},[268,1492,1493,1496,1498,1500,1502,1505],{"class":270,"line":982},[268,1494,1495],{"class":300},"        detectBestFormat",[268,1497,838],{"class":339},[268,1499,715],{"class":335},[268,1501,696],{"class":339},[268,1503,1504],{"class":720},"acceptHeader",[268,1506,724],{"class":339},[268,1508,1509,1511,1514,1517,1519,1522,1524,1527,1530,1533],{"class":270,"line":993},[268,1510,852],{"class":335},[268,1512,1513],{"class":339}," (acceptHeader.",[268,1515,1516],{"class":300},"indexOf",[268,1518,696],{"class":339},[268,1520,1521],{"class":311},"'image\u002Favif'",[268,1523,1342],{"class":339},[268,1525,1526],{"class":335},"!==",[268,1528,1529],{"class":335}," -",[268,1531,1532],{"class":304},"1",[268,1534,724],{"class":339},[268,1536,1537,1539,1542],{"class":270,"line":1015},[268,1538,866],{"class":335},[268,1540,1541],{"class":311}," 'avif'",[268,1543,732],{"class":339},[268,1545,1546],{"class":270,"line":1035},[268,1547,874],{"class":339},[268,1549,1550,1552,1554,1556,1558,1561,1563,1565,1567,1569],{"class":270,"line":1041},[268,1551,852],{"class":335},[268,1553,1513],{"class":339},[268,1555,1516],{"class":300},[268,1557,696],{"class":339},[268,1559,1560],{"class":311},"'image\u002Fwebp'",[268,1562,1342],{"class":339},[268,1564,1526],{"class":335},[268,1566,1529],{"class":335},[268,1568,1532],{"class":304},[268,1570,724],{"class":339},[268,1572,1573,1575,1578],{"class":270,"line":1047},[268,1574,866],{"class":335},[268,1576,1577],{"class":311}," 'webp'",[268,1579,732],{"class":339},[268,1581,1582],{"class":270,"line":1052},[268,1583,874],{"class":339},[268,1585,1586,1588,1591],{"class":270,"line":1057},[268,1587,959],{"class":335},[268,1589,1590],{"class":311}," 'jpeg'",[268,1592,732],{"class":339},[268,1594,1595],{"class":270,"line":1063},[268,1596,1044],{"class":339},[268,1598,1599],{"class":270,"line":1069},[268,1600,1246],{"class":339},[268,1602,1603,1606,1608,1610,1612,1615,1617,1620],{"class":270,"line":1074},[268,1604,1605],{"class":300},"        getImageUrl",[268,1607,838],{"class":339},[268,1609,715],{"class":335},[268,1611,696],{"class":339},[268,1613,1614],{"class":720},"imageId",[268,1616,1434],{"class":339},[268,1618,1619],{"class":720},"format",[268,1621,724],{"class":339},[268,1623,1624],{"class":270,"line":1091},[268,1625,1626],{"class":274},"            \u002F\u002F Implementation depends on your image storage\n",[268,1628,1629,1631,1634,1636,1638,1640,1643],{"class":270,"line":1097},[268,1630,889],{"class":335},[268,1632,1633],{"class":339}," baseUrl ",[268,1635,747],{"class":335},[268,1637,1283],{"class":304},[268,1639,385],{"class":339},[268,1641,1642],{"class":300},"getBaseImageUrl",[268,1644,1645],{"class":339},"(imageId);\n",[268,1647,1648],{"class":270,"line":1103},[268,1649,1355],{"class":339},[268,1651,1652,1655],{"class":270,"line":1113},[268,1653,1654],{"class":335},"            switch",[268,1656,1657],{"class":339}," (format) {\n",[268,1659,1660,1663,1665],{"class":270,"line":1118},[268,1661,1662],{"class":335},"                case",[268,1664,1541],{"class":311},[268,1666,1667],{"class":339},":\n",[268,1669,1670,1673,1675,1678,1680,1683,1687,1691,1694,1697,1699,1702,1705,1707,1710,1712,1715],{"class":270,"line":1123},[268,1671,1672],{"class":335},"                    return",[268,1674,897],{"class":339},[268,1676,1677],{"class":300},"replace",[268,1679,696],{"class":339},[268,1681,1682],{"class":311},"\u002F",[268,1684,1686],{"class":1685},"snhLl","\\.",[268,1688,1690],{"class":1689},"sA_wV","(jpg",[268,1692,1693],{"class":335},"|",[268,1695,1696],{"class":1689},"jpeg",[268,1698,1693],{"class":335},[268,1700,1701],{"class":1689},"png)",[268,1703,1704],{"class":335},"$",[268,1706,1682],{"class":311},[268,1708,1709],{"class":335},"i",[268,1711,1434],{"class":339},[268,1713,1714],{"class":311},"'.avif'",[268,1716,908],{"class":339},[268,1718,1719,1721,1723],{"class":270,"line":1139},[268,1720,1662],{"class":335},[268,1722,1577],{"class":311},[268,1724,1667],{"class":339},[268,1726,1727,1729,1731,1733,1735,1737,1739,1741,1743,1745,1747,1749,1751,1753,1755,1757,1759],{"class":270,"line":1145},[268,1728,1672],{"class":335},[268,1730,897],{"class":339},[268,1732,1677],{"class":300},[268,1734,696],{"class":339},[268,1736,1682],{"class":311},[268,1738,1686],{"class":1685},[268,1740,1690],{"class":1689},[268,1742,1693],{"class":335},[268,1744,1696],{"class":1689},[268,1746,1693],{"class":335},[268,1748,1701],{"class":1689},[268,1750,1704],{"class":335},[268,1752,1682],{"class":311},[268,1754,1709],{"class":335},[268,1756,1434],{"class":339},[268,1758,758],{"class":311},[268,1760,908],{"class":339},[268,1762,1763,1766],{"class":270,"line":1158},[268,1764,1765],{"class":335},"                default",[268,1767,1667],{"class":339},[268,1769,1770,1772],{"class":270,"line":1164},[268,1771,1672],{"class":335},[268,1773,1774],{"class":339}," baseUrl;\n",[268,1776,1777],{"class":270,"line":1169},[268,1778,874],{"class":339},[268,1780,1782],{"class":270,"line":1781},53,[268,1783,1161],{"class":339},[268,1785,1787],{"class":270,"line":1786},54,[268,1788,1789],{"class":339},"    });\n",[268,1791,1793],{"class":270,"line":1792},55,[268,1794,1172],{"class":339},[26,1796],{},[29,1798,55],{"id":1799},"implementing-lazy-loading-in-suitecommerce",[15,1801,1802],{},"Lazy loading defers image loading until images enter the viewport. This dramatically reduces initial page weight and speeds up First Contentful Paint.",[110,1804,1806],{"id":1805},"native-lazy-loading","Native Lazy Loading",[15,1808,1809],{},"The simplest implementation uses the browser's native lazy loading:",[258,1811,1813],{"className":542,"code":1812,"language":544,"meta":263,"style":263},"{{!-- product_thumbnail.tpl --}}\n\u003Cimg \n    src=\"{{imageUrl}}\"\n    alt=\"{{productName}}\"\n    loading=\"lazy\"\n    width=\"{{width}}\"\n    height=\"{{height}}\"\n    class=\"product-thumbnail\"\n\u002F>\n",[265,1814,1815,1820,1825,1830,1835,1840,1845,1850,1855],{"__ignoreMap":263},[268,1816,1817],{"class":270,"line":271},[268,1818,1819],{},"{{!-- product_thumbnail.tpl --}}\n",[268,1821,1822],{"class":270,"line":278},[268,1823,1824],{},"\u003Cimg \n",[268,1826,1827],{"class":270,"line":284},[268,1828,1829],{},"    src=\"{{imageUrl}}\"\n",[268,1831,1832],{"class":270,"line":291},[268,1833,1834],{},"    alt=\"{{productName}}\"\n",[268,1836,1837],{"class":270,"line":297},[268,1838,1839],{},"    loading=\"lazy\"\n",[268,1841,1842],{"class":270,"line":321},[268,1843,1844],{},"    width=\"{{width}}\"\n",[268,1846,1847],{"class":270,"line":326},[268,1848,1849],{},"    height=\"{{height}}\"\n",[268,1851,1852],{"class":270,"line":332},[268,1853,1854],{},"    class=\"product-thumbnail\"\n",[268,1856,1857],{"class":270,"line":355},[268,1858,1859],{},"\u002F>\n",[15,1861,1862,1865,1866,1869,1870,1873],{},[18,1863,1864],{},"Critical consideration:"," Always include ",[265,1867,1868],{},"width"," and ",[265,1871,1872],{},"height"," attributes. Without them, the browser can't reserve space before the image loads, causing Cumulative Layout Shift (CLS)—another Core Web Vital that hurts your Google ranking.",[110,1875,1877],{"id":1876},"advanced-lazy-loading-with-intersection-observer","Advanced Lazy Loading with Intersection Observer",[15,1879,1880],{},"For more control, implement custom lazy loading:",[258,1882,1884],{"className":679,"code":1883,"language":681,"meta":263,"style":263},"\u002F\u002F LazyImageLoader.js\ndefine('LazyImageLoader', [\n    'jQuery',\n    'underscore'\n], function($, _) {\n    'use strict';\n\n    var LazyImageLoader = function(options) {\n        this.options = _.extend({\n            rootMargin: '50px 0px',\n            threshold: 0.01,\n            selector: '[data-lazy-src]'\n        }, options);\n        \n        this.observer = null;\n        this.initialize();\n    };\n\n    _.extend(LazyImageLoader.prototype, {\n        \n        initialize: function() {\n            if ('IntersectionObserver' in window) {\n                this.observer = new IntersectionObserver(\n                    this.handleIntersection.bind(this),\n                    {\n                        rootMargin: this.options.rootMargin,\n                        threshold: this.options.threshold\n                    }\n                );\n                \n                this.observeImages();\n            } else {\n                \u002F\u002F Fallback for older browsers\n                this.loadAllImages();\n            }\n        },\n        \n        observeImages: function() {\n            var self = this;\n            var images = document.querySelectorAll(this.options.selector);\n            \n            images.forEach(function(img) {\n                self.observer.observe(img);\n            });\n        },\n        \n        handleIntersection: function(entries) {\n            var self = this;\n            \n            entries.forEach(function(entry) {\n                if (entry.isIntersecting) {\n                    self.loadImage(entry.target);\n                    self.observer.unobserve(entry.target);\n                }\n            });\n        },\n        \n        loadImage: function(img) {\n            var src = img.getAttribute('data-lazy-src');\n            var srcset = img.getAttribute('data-lazy-srcset');\n            \n            if (src) {\n                img.src = src;\n                img.removeAttribute('data-lazy-src');\n            }\n            \n            if (srcset) {\n                img.srcset = srcset;\n                img.removeAttribute('data-lazy-srcset');\n            }\n            \n            \u002F\u002F Add loaded class for CSS transitions\n            img.classList.add('lazy-loaded');\n        },\n        \n        loadAllImages: function() {\n            var self = this;\n            var images = document.querySelectorAll(this.options.selector);\n            \n            images.forEach(function(img) {\n                self.loadImage(img);\n            });\n        },\n        \n        \u002F\u002F Call when new images are added (e.g., infinite scroll)\n        refresh: function() {\n            this.observeImages();\n        },\n        \n        destroy: function() {\n            if (this.observer) {\n                this.observer.disconnect();\n            }\n        }\n    });\n\n    return LazyImageLoader;\n});\n",[265,1885,1886,1891,1902,1909,1913,1929,1935,1939,1959,1976,1986,1996,2004,2009,2013,2027,2039,2043,2047,2067,2071,2082,2097,2115,2133,2138,2148,2158,2163,2168,2173,2184,2194,2199,2210,2214,2218,2222,2233,2246,2268,2272,2291,2302,2307,2311,2315,2331,2343,2347,2365,2373,2384,2394,2399,2403,2408,2413,2429,2452,2473,2478,2486,2497,2512,2517,2522,2530,2541,2554,2559,2564,2570,2586,2591,2596,2608,2621,2640,2645,2662,2672,2677,2682,2687,2693,2705,2716,2721,2726,2738,2750,2763,2768,2773,2778,2783,2791],{"__ignoreMap":263},[268,1887,1888],{"class":270,"line":271},[268,1889,1890],{"class":274},"\u002F\u002F LazyImageLoader.js\n",[268,1892,1893,1895,1897,1900],{"class":270,"line":278},[268,1894,693],{"class":300},[268,1896,696],{"class":339},[268,1898,1899],{"class":311},"'LazyImageLoader'",[268,1901,702],{"class":339},[268,1903,1904,1907],{"class":270,"line":284},[268,1905,1906],{"class":311},"    'jQuery'",[268,1908,761],{"class":339},[268,1910,1911],{"class":270,"line":291},[268,1912,707],{"class":311},[268,1914,1915,1917,1919,1921,1923,1925,1927],{"class":270,"line":297},[268,1916,712],{"class":339},[268,1918,715],{"class":335},[268,1920,696],{"class":339},[268,1922,1704],{"class":720},[268,1924,1434],{"class":339},[268,1926,721],{"class":720},[268,1928,724],{"class":339},[268,1930,1931,1933],{"class":270,"line":321},[268,1932,729],{"class":311},[268,1934,732],{"class":339},[268,1936,1937],{"class":270,"line":326},[268,1938,288],{"emptyLinePlaceholder":287},[268,1940,1941,1943,1946,1949,1952,1954,1957],{"class":270,"line":332},[268,1942,741],{"class":335},[268,1944,1945],{"class":300}," LazyImageLoader",[268,1947,1948],{"class":335}," =",[268,1950,1951],{"class":335}," function",[268,1953,696],{"class":339},[268,1955,1956],{"class":720},"options",[268,1958,724],{"class":339},[268,1960,1961,1964,1967,1969,1972,1974],{"class":270,"line":355},[268,1962,1963],{"class":304},"        this",[268,1965,1966],{"class":339},".options ",[268,1968,747],{"class":335},[268,1970,1971],{"class":339}," _.",[268,1973,1238],{"class":300},[268,1975,1241],{"class":339},[268,1977,1978,1981,1984],{"class":270,"line":394},[268,1979,1980],{"class":339},"            rootMargin: ",[268,1982,1983],{"class":311},"'50px 0px'",[268,1985,761],{"class":339},[268,1987,1988,1991,1994],{"class":270,"line":598},[268,1989,1990],{"class":339},"            threshold: ",[268,1992,1993],{"class":304},"0.01",[268,1995,761],{"class":339},[268,1997,1998,2001],{"class":270,"line":604},[268,1999,2000],{"class":339},"            selector: ",[268,2002,2003],{"class":311},"'[data-lazy-src]'\n",[268,2005,2006],{"class":270,"line":610},[268,2007,2008],{"class":339},"        }, options);\n",[268,2010,2011],{"class":270,"line":615},[268,2012,1246],{"class":339},[268,2014,2015,2017,2020,2022,2025],{"class":270,"line":620},[268,2016,1963],{"class":304},[268,2018,2019],{"class":339},".observer ",[268,2021,747],{"class":335},[268,2023,2024],{"class":304}," null",[268,2026,732],{"class":339},[268,2028,2029,2031,2033,2036],{"class":270,"line":626},[268,2030,1963],{"class":304},[268,2032,385],{"class":339},[268,2034,2035],{"class":300},"initialize",[268,2037,2038],{"class":339},"();\n",[268,2040,2041],{"class":270,"line":632},[268,2042,774],{"class":339},[268,2044,2045],{"class":270,"line":638},[268,2046,288],{"emptyLinePlaceholder":287},[268,2048,2049,2052,2054,2056,2059,2061,2064],{"class":270,"line":644},[268,2050,2051],{"class":339},"    _.",[268,2053,1238],{"class":300},[268,2055,696],{"class":339},[268,2057,2058],{"class":304},"LazyImageLoader",[268,2060,385],{"class":339},[268,2062,2063],{"class":304},"prototype",[268,2065,2066],{"class":339},", {\n",[268,2068,2069],{"class":270,"line":650},[268,2070,1246],{"class":339},[268,2072,2073,2076,2078,2080],{"class":270,"line":656},[268,2074,2075],{"class":300},"        initialize",[268,2077,838],{"class":339},[268,2079,715],{"class":335},[268,2081,1271],{"class":339},[268,2083,2084,2086,2088,2091,2094],{"class":270,"line":662},[268,2085,852],{"class":335},[268,2087,855],{"class":339},[268,2089,2090],{"class":311},"'IntersectionObserver'",[268,2092,2093],{"class":335}," in",[268,2095,2096],{"class":339}," window) {\n",[268,2098,2099,2102,2104,2106,2109,2112],{"class":270,"line":668},[268,2100,2101],{"class":304},"                this",[268,2103,2019],{"class":339},[268,2105,747],{"class":335},[268,2107,2108],{"class":335}," new",[268,2110,2111],{"class":300}," IntersectionObserver",[268,2113,2114],{"class":339},"(\n",[268,2116,2117,2120,2123,2126,2128,2130],{"class":270,"line":886},[268,2118,2119],{"class":304},"                    this",[268,2121,2122],{"class":339},".handleIntersection.",[268,2124,2125],{"class":300},"bind",[268,2127,696],{"class":339},[268,2129,999],{"class":304},[268,2131,2132],{"class":339},"),\n",[268,2134,2135],{"class":270,"line":911},[268,2136,2137],{"class":339},"                    {\n",[268,2139,2140,2143,2145],{"class":270,"line":934},[268,2141,2142],{"class":339},"                        rootMargin: ",[268,2144,999],{"class":304},[268,2146,2147],{"class":339},".options.rootMargin,\n",[268,2149,2150,2153,2155],{"class":270,"line":951},[268,2151,2152],{"class":339},"                        threshold: ",[268,2154,999],{"class":304},[268,2156,2157],{"class":339},".options.threshold\n",[268,2159,2160],{"class":270,"line":956},[268,2161,2162],{"class":339},"                    }\n",[268,2164,2165],{"class":270,"line":964},[268,2166,2167],{"class":339},"                );\n",[268,2169,2170],{"class":270,"line":970},[268,2171,2172],{"class":339},"                \n",[268,2174,2175,2177,2179,2182],{"class":270,"line":982},[268,2176,2101],{"class":304},[268,2178,385],{"class":339},[268,2180,2181],{"class":300},"observeImages",[268,2183,2038],{"class":339},[268,2185,2186,2189,2192],{"class":270,"line":993},[268,2187,2188],{"class":339},"            } ",[268,2190,2191],{"class":335},"else",[268,2193,750],{"class":339},[268,2195,2196],{"class":270,"line":1015},[268,2197,2198],{"class":274},"                \u002F\u002F Fallback for older browsers\n",[268,2200,2201,2203,2205,2208],{"class":270,"line":1035},[268,2202,2101],{"class":304},[268,2204,385],{"class":339},[268,2206,2207],{"class":300},"loadAllImages",[268,2209,2038],{"class":339},[268,2211,2212],{"class":270,"line":1041},[268,2213,874],{"class":339},[268,2215,2216],{"class":270,"line":1047},[268,2217,1044],{"class":339},[268,2219,2220],{"class":270,"line":1052},[268,2221,1246],{"class":339},[268,2223,2224,2227,2229,2231],{"class":270,"line":1057},[268,2225,2226],{"class":300},"        observeImages",[268,2228,838],{"class":339},[268,2230,715],{"class":335},[268,2232,1271],{"class":339},[268,2234,2235,2237,2240,2242,2244],{"class":270,"line":1063},[268,2236,889],{"class":335},[268,2238,2239],{"class":339}," self ",[268,2241,747],{"class":335},[268,2243,1283],{"class":304},[268,2245,732],{"class":339},[268,2247,2248,2250,2253,2255,2258,2261,2263,2265],{"class":270,"line":1069},[268,2249,889],{"class":335},[268,2251,2252],{"class":339}," images ",[268,2254,747],{"class":335},[268,2256,2257],{"class":339}," document.",[268,2259,2260],{"class":300},"querySelectorAll",[268,2262,696],{"class":339},[268,2264,999],{"class":304},[268,2266,2267],{"class":339},".options.selector);\n",[268,2269,2270],{"class":270,"line":1074},[268,2271,1355],{"class":339},[268,2273,2274,2277,2280,2282,2284,2286,2289],{"class":270,"line":1091},[268,2275,2276],{"class":339},"            images.",[268,2278,2279],{"class":300},"forEach",[268,2281,696],{"class":339},[268,2283,715],{"class":335},[268,2285,696],{"class":339},[268,2287,2288],{"class":720},"img",[268,2290,724],{"class":339},[268,2292,2293,2296,2299],{"class":270,"line":1097},[268,2294,2295],{"class":339},"                self.observer.",[268,2297,2298],{"class":300},"observe",[268,2300,2301],{"class":339},"(img);\n",[268,2303,2304],{"class":270,"line":1103},[268,2305,2306],{"class":339},"            });\n",[268,2308,2309],{"class":270,"line":1113},[268,2310,1044],{"class":339},[268,2312,2313],{"class":270,"line":1118},[268,2314,1246],{"class":339},[268,2316,2317,2320,2322,2324,2326,2329],{"class":270,"line":1123},[268,2318,2319],{"class":300},"        handleIntersection",[268,2321,838],{"class":339},[268,2323,715],{"class":335},[268,2325,696],{"class":339},[268,2327,2328],{"class":720},"entries",[268,2330,724],{"class":339},[268,2332,2333,2335,2337,2339,2341],{"class":270,"line":1139},[268,2334,889],{"class":335},[268,2336,2239],{"class":339},[268,2338,747],{"class":335},[268,2340,1283],{"class":304},[268,2342,732],{"class":339},[268,2344,2345],{"class":270,"line":1145},[268,2346,1355],{"class":339},[268,2348,2349,2352,2354,2356,2358,2360,2363],{"class":270,"line":1158},[268,2350,2351],{"class":339},"            entries.",[268,2353,2279],{"class":300},[268,2355,696],{"class":339},[268,2357,715],{"class":335},[268,2359,696],{"class":339},[268,2361,2362],{"class":720},"entry",[268,2364,724],{"class":339},[268,2366,2367,2370],{"class":270,"line":1164},[268,2368,2369],{"class":335},"                if",[268,2371,2372],{"class":339}," (entry.isIntersecting) {\n",[268,2374,2375,2378,2381],{"class":270,"line":1169},[268,2376,2377],{"class":339},"                    self.",[268,2379,2380],{"class":300},"loadImage",[268,2382,2383],{"class":339},"(entry.target);\n",[268,2385,2386,2389,2392],{"class":270,"line":1781},[268,2387,2388],{"class":339},"                    self.observer.",[268,2390,2391],{"class":300},"unobserve",[268,2393,2383],{"class":339},[268,2395,2396],{"class":270,"line":1786},[268,2397,2398],{"class":339},"                }\n",[268,2400,2401],{"class":270,"line":1792},[268,2402,2306],{"class":339},[268,2404,2406],{"class":270,"line":2405},56,[268,2407,1044],{"class":339},[268,2409,2411],{"class":270,"line":2410},57,[268,2412,1246],{"class":339},[268,2414,2416,2419,2421,2423,2425,2427],{"class":270,"line":2415},58,[268,2417,2418],{"class":300},"        loadImage",[268,2420,838],{"class":339},[268,2422,715],{"class":335},[268,2424,696],{"class":339},[268,2426,2288],{"class":720},[268,2428,724],{"class":339},[268,2430,2432,2434,2437,2439,2442,2445,2447,2450],{"class":270,"line":2431},59,[268,2433,889],{"class":335},[268,2435,2436],{"class":339}," src ",[268,2438,747],{"class":335},[268,2440,2441],{"class":339}," img.",[268,2443,2444],{"class":300},"getAttribute",[268,2446,696],{"class":339},[268,2448,2449],{"class":311},"'data-lazy-src'",[268,2451,908],{"class":339},[268,2453,2455,2457,2460,2462,2464,2466,2468,2471],{"class":270,"line":2454},60,[268,2456,889],{"class":335},[268,2458,2459],{"class":339}," srcset ",[268,2461,747],{"class":335},[268,2463,2441],{"class":339},[268,2465,2444],{"class":300},[268,2467,696],{"class":339},[268,2469,2470],{"class":311},"'data-lazy-srcset'",[268,2472,908],{"class":339},[268,2474,2476],{"class":270,"line":2475},61,[268,2477,1355],{"class":339},[268,2479,2481,2483],{"class":270,"line":2480},62,[268,2482,852],{"class":335},[268,2484,2485],{"class":339}," (src) {\n",[268,2487,2489,2492,2494],{"class":270,"line":2488},63,[268,2490,2491],{"class":339},"                img.src ",[268,2493,747],{"class":335},[268,2495,2496],{"class":339}," src;\n",[268,2498,2500,2503,2506,2508,2510],{"class":270,"line":2499},64,[268,2501,2502],{"class":339},"                img.",[268,2504,2505],{"class":300},"removeAttribute",[268,2507,696],{"class":339},[268,2509,2449],{"class":311},[268,2511,908],{"class":339},[268,2513,2515],{"class":270,"line":2514},65,[268,2516,874],{"class":339},[268,2518,2520],{"class":270,"line":2519},66,[268,2521,1355],{"class":339},[268,2523,2525,2527],{"class":270,"line":2524},67,[268,2526,852],{"class":335},[268,2528,2529],{"class":339}," (srcset) {\n",[268,2531,2533,2536,2538],{"class":270,"line":2532},68,[268,2534,2535],{"class":339},"                img.srcset ",[268,2537,747],{"class":335},[268,2539,2540],{"class":339}," srcset;\n",[268,2542,2544,2546,2548,2550,2552],{"class":270,"line":2543},69,[268,2545,2502],{"class":339},[268,2547,2505],{"class":300},[268,2549,696],{"class":339},[268,2551,2470],{"class":311},[268,2553,908],{"class":339},[268,2555,2557],{"class":270,"line":2556},70,[268,2558,874],{"class":339},[268,2560,2562],{"class":270,"line":2561},71,[268,2563,1355],{"class":339},[268,2565,2567],{"class":270,"line":2566},72,[268,2568,2569],{"class":274},"            \u002F\u002F Add loaded class for CSS transitions\n",[268,2571,2573,2576,2579,2581,2584],{"class":270,"line":2572},73,[268,2574,2575],{"class":339},"            img.classList.",[268,2577,2578],{"class":300},"add",[268,2580,696],{"class":339},[268,2582,2583],{"class":311},"'lazy-loaded'",[268,2585,908],{"class":339},[268,2587,2589],{"class":270,"line":2588},74,[268,2590,1044],{"class":339},[268,2592,2594],{"class":270,"line":2593},75,[268,2595,1246],{"class":339},[268,2597,2599,2602,2604,2606],{"class":270,"line":2598},76,[268,2600,2601],{"class":300},"        loadAllImages",[268,2603,838],{"class":339},[268,2605,715],{"class":335},[268,2607,1271],{"class":339},[268,2609,2611,2613,2615,2617,2619],{"class":270,"line":2610},77,[268,2612,889],{"class":335},[268,2614,2239],{"class":339},[268,2616,747],{"class":335},[268,2618,1283],{"class":304},[268,2620,732],{"class":339},[268,2622,2624,2626,2628,2630,2632,2634,2636,2638],{"class":270,"line":2623},78,[268,2625,889],{"class":335},[268,2627,2252],{"class":339},[268,2629,747],{"class":335},[268,2631,2257],{"class":339},[268,2633,2260],{"class":300},[268,2635,696],{"class":339},[268,2637,999],{"class":304},[268,2639,2267],{"class":339},[268,2641,2643],{"class":270,"line":2642},79,[268,2644,1355],{"class":339},[268,2646,2648,2650,2652,2654,2656,2658,2660],{"class":270,"line":2647},80,[268,2649,2276],{"class":339},[268,2651,2279],{"class":300},[268,2653,696],{"class":339},[268,2655,715],{"class":335},[268,2657,696],{"class":339},[268,2659,2288],{"class":720},[268,2661,724],{"class":339},[268,2663,2665,2668,2670],{"class":270,"line":2664},81,[268,2666,2667],{"class":339},"                self.",[268,2669,2380],{"class":300},[268,2671,2301],{"class":339},[268,2673,2675],{"class":270,"line":2674},82,[268,2676,2306],{"class":339},[268,2678,2680],{"class":270,"line":2679},83,[268,2681,1044],{"class":339},[268,2683,2685],{"class":270,"line":2684},84,[268,2686,1246],{"class":339},[268,2688,2690],{"class":270,"line":2689},85,[268,2691,2692],{"class":274},"        \u002F\u002F Call when new images are added (e.g., infinite scroll)\n",[268,2694,2696,2699,2701,2703],{"class":270,"line":2695},86,[268,2697,2698],{"class":300},"        refresh",[268,2700,838],{"class":339},[268,2702,715],{"class":335},[268,2704,1271],{"class":339},[268,2706,2708,2710,2712,2714],{"class":270,"line":2707},87,[268,2709,1420],{"class":304},[268,2711,385],{"class":339},[268,2713,2181],{"class":300},[268,2715,2038],{"class":339},[268,2717,2719],{"class":270,"line":2718},88,[268,2720,1044],{"class":339},[268,2722,2724],{"class":270,"line":2723},89,[268,2725,1246],{"class":339},[268,2727,2729,2732,2734,2736],{"class":270,"line":2728},90,[268,2730,2731],{"class":300},"        destroy",[268,2733,838],{"class":339},[268,2735,715],{"class":335},[268,2737,1271],{"class":339},[268,2739,2741,2743,2745,2747],{"class":270,"line":2740},91,[268,2742,852],{"class":335},[268,2744,855],{"class":339},[268,2746,999],{"class":304},[268,2748,2749],{"class":339},".observer) {\n",[268,2751,2753,2755,2758,2761],{"class":270,"line":2752},92,[268,2754,2101],{"class":304},[268,2756,2757],{"class":339},".observer.",[268,2759,2760],{"class":300},"disconnect",[268,2762,2038],{"class":339},[268,2764,2766],{"class":270,"line":2765},93,[268,2767,874],{"class":339},[268,2769,2771],{"class":270,"line":2770},94,[268,2772,1161],{"class":339},[268,2774,2776],{"class":270,"line":2775},95,[268,2777,1789],{"class":339},[268,2779,2781],{"class":270,"line":2780},96,[268,2782,288],{"emptyLinePlaceholder":287},[268,2784,2786,2788],{"class":270,"line":2785},97,[268,2787,783],{"class":335},[268,2789,2790],{"class":339}," LazyImageLoader;\n",[268,2792,2794],{"class":270,"line":2793},98,[268,2795,1172],{"class":339},[15,2797,2798],{},[18,2799,2800],{},"Template modification for custom lazy loading:",[258,2802,2804],{"className":542,"code":2803,"language":544,"meta":263,"style":263},"{{!-- product_list_item.tpl --}}\n\u003Cdiv class=\"product-list-item\">\n    \u003Cimg \n        src=\"data:image\u002Fsvg+xml,%3Csvg xmlns='http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg' viewBox='0 0 400 400'%3E%3C\u002Fsvg%3E\"\n        data-lazy-src=\"{{imageUrl}}\"\n        data-lazy-srcset=\"{{imageSrcset}}\"\n        alt=\"{{productName}}\"\n        width=\"400\"\n        height=\"400\"\n        class=\"product-list-item-image lazy-image\"\n    \u002F>\n\u003C\u002Fdiv>\n",[265,2805,2806,2811,2816,2820,2825,2830,2835,2840,2845,2850,2855,2859],{"__ignoreMap":263},[268,2807,2808],{"class":270,"line":271},[268,2809,2810],{},"{{!-- product_list_item.tpl --}}\n",[268,2812,2813],{"class":270,"line":278},[268,2814,2815],{},"\u003Cdiv class=\"product-list-item\">\n",[268,2817,2818],{"class":270,"line":284},[268,2819,623],{},[268,2821,2822],{"class":270,"line":291},[268,2823,2824],{},"        src=\"data:image\u002Fsvg+xml,%3Csvg xmlns='http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg' viewBox='0 0 400 400'%3E%3C\u002Fsvg%3E\"\n",[268,2826,2827],{"class":270,"line":297},[268,2828,2829],{},"        data-lazy-src=\"{{imageUrl}}\"\n",[268,2831,2832],{"class":270,"line":321},[268,2833,2834],{},"        data-lazy-srcset=\"{{imageSrcset}}\"\n",[268,2836,2837],{"class":270,"line":326},[268,2838,2839],{},"        alt=\"{{productName}}\"\n",[268,2841,2842],{"class":270,"line":332},[268,2843,2844],{},"        width=\"400\"\n",[268,2846,2847],{"class":270,"line":355},[268,2848,2849],{},"        height=\"400\"\n",[268,2851,2852],{"class":270,"line":394},[268,2853,2854],{},"        class=\"product-list-item-image lazy-image\"\n",[268,2856,2857],{"class":270,"line":598},[268,2858,665],{},[268,2860,2861],{"class":270,"line":604},[268,2862,2863],{},"\u003C\u002Fdiv>\n",[15,2865,2866],{},[18,2867,2868],{},"CSS for smooth loading transitions:",[258,2870,2874],{"className":2871,"code":2872,"language":2873,"meta":263,"style":263},"language-scss shiki shiki-themes github-light github-dark","\u002F\u002F _lazy-images.scss\n.lazy-image {\n    opacity: 0;\n    transition: opacity 0.3s ease-in-out;\n    background-color: #f5f5f5;\n    \n    &.lazy-loaded {\n        opacity: 1;\n    }\n}\n\n\u002F\u002F Placeholder styling\n.lazy-image[src^=\"data:\"] {\n    background: linear-gradient(90deg, #f5f5f5 25%, #ececec 50%, #f5f5f5 75%);\n    background-size: 200% 100%;\n    animation: shimmer 1.5s infinite;\n}\n\n@keyframes shimmer {\n    0% {\n        background-position: -200% 0;\n    }\n    100% {\n        background-position: 200% 0;\n    }\n}\n","scss",[265,2875,2876,2881,2888,2899,2920,2932,2937,2948,2959,2964,2969,2973,2978,3001,3049,3068,3086,3090,3094,3104,3111,3128,3132,3139,3153,3157],{"__ignoreMap":263},[268,2877,2878],{"class":270,"line":271},[268,2879,2880],{"class":274},"\u002F\u002F _lazy-images.scss\n",[268,2882,2883,2886],{"class":270,"line":278},[268,2884,2885],{"class":300},".lazy-image",[268,2887,750],{"class":339},[268,2889,2890,2893,2895,2897],{"class":270,"line":284},[268,2891,2892],{"class":304},"    opacity",[268,2894,838],{"class":339},[268,2896,928],{"class":304},[268,2898,732],{"class":339},[268,2900,2901,2904,2906,2909,2912,2915,2918],{"class":270,"line":291},[268,2902,2903],{"class":304},"    transition",[268,2905,838],{"class":339},[268,2907,2908],{"class":304},"opacity",[268,2910,2911],{"class":304}," 0.3",[268,2913,2914],{"class":335},"s",[268,2916,2917],{"class":304}," ease-in-out",[268,2919,732],{"class":339},[268,2921,2922,2925,2927,2930],{"class":270,"line":297},[268,2923,2924],{"class":304},"    background-color",[268,2926,838],{"class":339},[268,2928,2929],{"class":304},"#f5f5f5",[268,2931,732],{"class":339},[268,2933,2934],{"class":270,"line":321},[268,2935,2936],{"class":339},"    \n",[268,2938,2939,2943,2946],{"class":270,"line":326},[268,2940,2942],{"class":2941},"s9eBZ","    &",[268,2944,2945],{"class":300},".lazy-loaded",[268,2947,750],{"class":339},[268,2949,2950,2953,2955,2957],{"class":270,"line":332},[268,2951,2952],{"class":304},"        opacity",[268,2954,838],{"class":339},[268,2956,1532],{"class":304},[268,2958,732],{"class":339},[268,2960,2961],{"class":270,"line":355},[268,2962,2963],{"class":339},"    }\n",[268,2965,2966],{"class":270,"line":394},[268,2967,2968],{"class":339},"}\n",[268,2970,2971],{"class":270,"line":598},[268,2972,288],{"emptyLinePlaceholder":287},[268,2974,2975],{"class":270,"line":604},[268,2976,2977],{"class":274},"\u002F\u002F Placeholder styling\n",[268,2979,2980,2982,2985,2988,2991,2993,2996,2998],{"class":270,"line":610},[268,2981,2885],{"class":300},[268,2983,2984],{"class":339},"[",[268,2986,2987],{"class":300},"src",[268,2989,2990],{"class":335},"^=",[268,2992,371],{"class":311},[268,2994,2995],{"class":339},"data:",[268,2997,371],{"class":311},[268,2999,3000],{"class":339},"] {\n",[268,3002,3003,3006,3008,3011,3013,3016,3019,3021,3023,3026,3028,3030,3033,3036,3038,3040,3042,3045,3047],{"class":270,"line":615},[268,3004,3005],{"class":304},"    background",[268,3007,838],{"class":339},[268,3009,3010],{"class":304},"linear-gradient",[268,3012,696],{"class":339},[268,3014,3015],{"class":304},"90",[268,3017,3018],{"class":335},"deg",[268,3020,1434],{"class":339},[268,3022,2929],{"class":304},[268,3024,3025],{"class":304}," 25",[268,3027,382],{"class":335},[268,3029,1434],{"class":339},[268,3031,3032],{"class":304},"#ececec",[268,3034,3035],{"class":304}," 50",[268,3037,382],{"class":335},[268,3039,1434],{"class":339},[268,3041,2929],{"class":304},[268,3043,3044],{"class":304}," 75",[268,3046,382],{"class":335},[268,3048,908],{"class":339},[268,3050,3051,3054,3056,3059,3061,3064,3066],{"class":270,"line":620},[268,3052,3053],{"class":304},"    background-size",[268,3055,838],{"class":339},[268,3057,3058],{"class":304},"200",[268,3060,382],{"class":335},[268,3062,3063],{"class":304}," 100",[268,3065,382],{"class":335},[268,3067,732],{"class":339},[268,3069,3070,3073,3076,3079,3081,3084],{"class":270,"line":626},[268,3071,3072],{"class":304},"    animation",[268,3074,3075],{"class":339},": shimmer ",[268,3077,3078],{"class":304},"1.5",[268,3080,2914],{"class":335},[268,3082,3083],{"class":304}," infinite",[268,3085,732],{"class":339},[268,3087,3088],{"class":270,"line":632},[268,3089,2968],{"class":339},[268,3091,3092],{"class":270,"line":638},[268,3093,288],{"emptyLinePlaceholder":287},[268,3095,3096,3099,3102],{"class":270,"line":644},[268,3097,3098],{"class":335},"@keyframes",[268,3100,3101],{"class":300}," shimmer",[268,3103,750],{"class":339},[268,3105,3106,3109],{"class":270,"line":650},[268,3107,3108],{"class":300},"    0%",[268,3110,750],{"class":339},[268,3112,3113,3116,3118,3121,3123,3126],{"class":270,"line":656},[268,3114,3115],{"class":304},"        background-position",[268,3117,838],{"class":339},[268,3119,3120],{"class":304},"-200",[268,3122,382],{"class":335},[268,3124,3125],{"class":304}," 0",[268,3127,732],{"class":339},[268,3129,3130],{"class":270,"line":662},[268,3131,2963],{"class":339},[268,3133,3134,3137],{"class":270,"line":668},[268,3135,3136],{"class":300},"    100%",[268,3138,750],{"class":339},[268,3140,3141,3143,3145,3147,3149,3151],{"class":270,"line":886},[268,3142,3115],{"class":304},[268,3144,838],{"class":339},[268,3146,3058],{"class":304},[268,3148,382],{"class":335},[268,3150,3125],{"class":304},[268,3152,732],{"class":339},[268,3154,3155],{"class":270,"line":911},[268,3156,2963],{"class":339},[268,3158,3159],{"class":270,"line":934},[268,3160,2968],{"class":339},[110,3162,3164],{"id":3163},"eager-loading-for-above-the-fold-images","Eager Loading for Above-the-Fold Images",[15,3166,3167,3168,3171],{},"Don't lazy load images that appear immediately on page load. Use ",[265,3169,3170],{},"loading=\"eager\""," or omit the attribute entirely:",[258,3173,3175],{"className":542,"code":3174,"language":544,"meta":263,"style":263},"{{!-- hero_image.tpl --}}\n\u003Cimg \n    src=\"{{heroImageUrl}}\"\n    alt=\"{{heroAltText}}\"\n    loading=\"eager\"\n    fetchpriority=\"high\"\n    class=\"hero-image\"\n\u002F>\n",[265,3176,3177,3182,3186,3191,3196,3201,3206,3211],{"__ignoreMap":263},[268,3178,3179],{"class":270,"line":271},[268,3180,3181],{},"{{!-- hero_image.tpl --}}\n",[268,3183,3184],{"class":270,"line":278},[268,3185,1824],{},[268,3187,3188],{"class":270,"line":284},[268,3189,3190],{},"    src=\"{{heroImageUrl}}\"\n",[268,3192,3193],{"class":270,"line":291},[268,3194,3195],{},"    alt=\"{{heroAltText}}\"\n",[268,3197,3198],{"class":270,"line":297},[268,3199,3200],{},"    loading=\"eager\"\n",[268,3202,3203],{"class":270,"line":321},[268,3204,3205],{},"    fetchpriority=\"high\"\n",[268,3207,3208],{"class":270,"line":326},[268,3209,3210],{},"    class=\"hero-image\"\n",[268,3212,3213],{"class":270,"line":332},[268,3214,1859],{},[15,3216,535,3217,3220],{},[265,3218,3219],{},"fetchpriority=\"high\""," attribute tells the browser to prioritize this image, improving LCP.",[15,3222,3223,3226],{},[18,3224,3225],{},"Rule of thumb:"," Eager load the first 1-3 images visible without scrolling. Lazy load everything else.",[26,3228],{},[29,3230,61],{"id":3231},"responsive-images-for-suitecommerce-themes",[15,3233,3234],{},"Serving appropriately-sized images prevents mobile users from downloading desktop-sized images.",[15,3236,3237],{},[2288,3238],{"alt":3239,"src":3240},"Responsive design across multiple devices","\u002Fimages\u002Fblog\u002Fimage-optimization-responsive.webp",[110,3242,3244],{"id":3243},"understanding-srcset-and-sizes","Understanding srcset and sizes",[15,3246,535,3247,3250,3251,3254],{},[265,3248,3249],{},"srcset"," attribute provides multiple image sizes. The ",[265,3252,3253],{},"sizes"," attribute tells the browser which size to choose:",[258,3256,3260],{"className":3257,"code":3258,"language":3259,"meta":263,"style":263},"language-html shiki shiki-themes github-light github-dark","\u003Cimg \n    srcset=\"\n        product-400w.webp 400w,\n        product-600w.webp 600w,\n        product-800w.webp 800w,\n        product-1200w.webp 1200w\n    \"\n    sizes=\"\n        (max-width: 480px) 100vw,\n        (max-width: 768px) 50vw,\n        (max-width: 1200px) 33vw,\n        400px\n    \"\n    src=\"product-800w.webp\"\n    alt=\"Product Name\"\n\u002F>\n","html",[265,3261,3262,3272,3282,3287,3292,3297,3302,3307,3316,3321,3326,3331,3336,3340,3350,3360],{"__ignoreMap":263},[268,3263,3264,3267,3269],{"class":270,"line":271},[268,3265,3266],{"class":339},"\u003C",[268,3268,2288],{"class":2941},[268,3270,3271],{"class":339}," \n",[268,3273,3274,3277,3279],{"class":270,"line":278},[268,3275,3276],{"class":300},"    srcset",[268,3278,747],{"class":339},[268,3280,3281],{"class":311},"\"\n",[268,3283,3284],{"class":270,"line":284},[268,3285,3286],{"class":311},"        product-400w.webp 400w,\n",[268,3288,3289],{"class":270,"line":291},[268,3290,3291],{"class":311},"        product-600w.webp 600w,\n",[268,3293,3294],{"class":270,"line":297},[268,3295,3296],{"class":311},"        product-800w.webp 800w,\n",[268,3298,3299],{"class":270,"line":321},[268,3300,3301],{"class":311},"        product-1200w.webp 1200w\n",[268,3303,3304],{"class":270,"line":326},[268,3305,3306],{"class":311},"    \"\n",[268,3308,3309,3312,3314],{"class":270,"line":332},[268,3310,3311],{"class":300},"    sizes",[268,3313,747],{"class":339},[268,3315,3281],{"class":311},[268,3317,3318],{"class":270,"line":355},[268,3319,3320],{"class":311},"        (max-width: 480px) 100vw,\n",[268,3322,3323],{"class":270,"line":394},[268,3324,3325],{"class":311},"        (max-width: 768px) 50vw,\n",[268,3327,3328],{"class":270,"line":598},[268,3329,3330],{"class":311},"        (max-width: 1200px) 33vw,\n",[268,3332,3333],{"class":270,"line":604},[268,3334,3335],{"class":311},"        400px\n",[268,3337,3338],{"class":270,"line":610},[268,3339,3306],{"class":311},[268,3341,3342,3345,3347],{"class":270,"line":615},[268,3343,3344],{"class":300},"    src",[268,3346,747],{"class":339},[268,3348,3349],{"class":311},"\"product-800w.webp\"\n",[268,3351,3352,3355,3357],{"class":270,"line":620},[268,3353,3354],{"class":300},"    alt",[268,3356,747],{"class":339},[268,3358,3359],{"class":311},"\"Product Name\"\n",[268,3361,3362],{"class":270,"line":626},[268,3363,1859],{"class":339},[15,3365,3366],{},"This tells the browser:",[217,3368,3369,3372,3375,3378],{},[37,3370,3371],{},"On phones (≤480px): The image fills the viewport width",[37,3373,3374],{},"On tablets (≤768px): The image is half the viewport width",[37,3376,3377],{},"On desktop (≤1200px): The image is one-third the viewport width",[37,3379,3380],{},"Larger screens: The image is 400px wide",[110,3382,3384],{"id":3383},"implementing-responsive-images-in-suitecommerce","Implementing Responsive Images in SuiteCommerce",[15,3386,3387],{},[18,3388,3389],{},"Create a responsive image helper:",[258,3391,3393],{"className":679,"code":3392,"language":681,"meta":263,"style":263},"\u002F\u002F ResponsiveImageHelper.js\ndefine('ResponsiveImageHelper', [\n    'underscore',\n    'SC.Configuration'\n], function(_, Configuration) {\n    'use strict';\n\n    var breakpoints = [400, 600, 800, 1200, 1600];\n    \n    var defaultSizes = {\n        'product-listing': '(max-width: 480px) 100vw, (max-width: 768px) 50vw, (max-width: 1200px) 33vw, 400px',\n        'product-detail': '(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 600px',\n        'thumbnail': '100px',\n        'hero': '100vw'\n    };\n\n    return {\n        \n        \u002F**\n         * Generate srcset from base image URL\n         * Assumes image resizing service is available\n         *\u002F\n        generateSrcset: function(baseUrl, maxWidth) {\n            if (!baseUrl) {\n                return '';\n            }\n            \n            var applicableBreakpoints = breakpoints.filter(function(bp) {\n                return !maxWidth || bp \u003C= maxWidth;\n            });\n            \n            return applicableBreakpoints.map(function(width) {\n                var resizedUrl = this.getResizedUrl(baseUrl, width);\n                return resizedUrl + ' ' + width + 'w';\n            }.bind(this)).join(', ');\n        },\n        \n        \u002F**\n         * Get the sizes attribute for a given context\n         *\u002F\n        getSizes: function(context) {\n            return defaultSizes[context] || defaultSizes['product-listing'];\n        },\n        \n        \u002F**\n         * Transform URL to point to resized version\n         * Implementation depends on your image service\n         *\u002F\n        getResizedUrl: function(originalUrl, width) {\n            \u002F\u002F Option 1: URL parameter (if using image processing service)\n            \u002F\u002F return originalUrl + '?w=' + width + '&format=webp';\n            \n            \u002F\u002F Option 2: URL path modification (pre-generated sizes)\n            var lastDot = originalUrl.lastIndexOf('.');\n            var basePath = originalUrl.substring(0, lastDot);\n            var ext = '.webp'; \u002F\u002F Always serve WebP in srcset\n            \n            return basePath + '-' + width + 'w' + ext;\n        },\n        \n        \u002F**\n         * Get complete responsive image attributes\n         *\u002F\n        getImageAttributes: function(imageUrl, context, options) {\n            options = options || {};\n            \n            return {\n                src: this.getResizedUrl(imageUrl, options.defaultWidth || 800),\n                srcset: this.generateSrcset(imageUrl, options.maxWidth),\n                sizes: this.getSizes(context),\n                width: options.width || '',\n                height: options.height || ''\n            };\n        }\n    };\n});\n",[265,3394,3395,3400,3411,3418,3423,3440,3446,3450,3488,3492,3503,3515,3527,3539,3549,3553,3557,3563,3567,3571,3576,3581,3585,3605,3615,3623,3627,3631,3657,3678,3682,3686,3706,3726,3750,3774,3778,3782,3786,3791,3795,3811,3828,3832,3836,3840,3845,3850,3854,3874,3879,3884,3888,3893,3912,3930,3947,3951,3975,3979,3983,3987,3992,3996,4020,4034,4038,4044,4065,4080,4095,4106,4116,4120,4124,4128],{"__ignoreMap":263},[268,3396,3397],{"class":270,"line":271},[268,3398,3399],{"class":274},"\u002F\u002F ResponsiveImageHelper.js\n",[268,3401,3402,3404,3406,3409],{"class":270,"line":278},[268,3403,693],{"class":300},[268,3405,696],{"class":339},[268,3407,3408],{"class":311},"'ResponsiveImageHelper'",[268,3410,702],{"class":339},[268,3412,3413,3416],{"class":270,"line":284},[268,3414,3415],{"class":311},"    'underscore'",[268,3417,761],{"class":339},[268,3419,3420],{"class":270,"line":291},[268,3421,3422],{"class":311},"    'SC.Configuration'\n",[268,3424,3425,3427,3429,3431,3433,3435,3438],{"class":270,"line":297},[268,3426,712],{"class":339},[268,3428,715],{"class":335},[268,3430,696],{"class":339},[268,3432,721],{"class":720},[268,3434,1434],{"class":339},[268,3436,3437],{"class":720},"Configuration",[268,3439,724],{"class":339},[268,3441,3442,3444],{"class":270,"line":321},[268,3443,729],{"class":311},[268,3445,732],{"class":339},[268,3447,3448],{"class":270,"line":326},[268,3449,288],{"emptyLinePlaceholder":287},[268,3451,3452,3454,3457,3459,3462,3465,3467,3470,3472,3475,3477,3480,3482,3485],{"class":270,"line":332},[268,3453,741],{"class":335},[268,3455,3456],{"class":339}," breakpoints ",[268,3458,747],{"class":335},[268,3460,3461],{"class":339}," [",[268,3463,3464],{"class":304},"400",[268,3466,1434],{"class":339},[268,3468,3469],{"class":304},"600",[268,3471,1434],{"class":339},[268,3473,3474],{"class":304},"800",[268,3476,1434],{"class":339},[268,3478,3479],{"class":304},"1200",[268,3481,1434],{"class":339},[268,3483,3484],{"class":304},"1600",[268,3486,3487],{"class":339},"];\n",[268,3489,3490],{"class":270,"line":355},[268,3491,2936],{"class":339},[268,3493,3494,3496,3499,3501],{"class":270,"line":394},[268,3495,741],{"class":335},[268,3497,3498],{"class":339}," defaultSizes ",[268,3500,747],{"class":335},[268,3502,750],{"class":339},[268,3504,3505,3508,3510,3513],{"class":270,"line":598},[268,3506,3507],{"class":311},"        'product-listing'",[268,3509,838],{"class":339},[268,3511,3512],{"class":311},"'(max-width: 480px) 100vw, (max-width: 768px) 50vw, (max-width: 1200px) 33vw, 400px'",[268,3514,761],{"class":339},[268,3516,3517,3520,3522,3525],{"class":270,"line":604},[268,3518,3519],{"class":311},"        'product-detail'",[268,3521,838],{"class":339},[268,3523,3524],{"class":311},"'(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 600px'",[268,3526,761],{"class":339},[268,3528,3529,3532,3534,3537],{"class":270,"line":610},[268,3530,3531],{"class":311},"        'thumbnail'",[268,3533,838],{"class":339},[268,3535,3536],{"class":311},"'100px'",[268,3538,761],{"class":339},[268,3540,3541,3544,3546],{"class":270,"line":615},[268,3542,3543],{"class":311},"        'hero'",[268,3545,838],{"class":339},[268,3547,3548],{"class":311},"'100vw'\n",[268,3550,3551],{"class":270,"line":620},[268,3552,774],{"class":339},[268,3554,3555],{"class":270,"line":626},[268,3556,288],{"emptyLinePlaceholder":287},[268,3558,3559,3561],{"class":270,"line":632},[268,3560,783],{"class":335},[268,3562,750],{"class":339},[268,3564,3565],{"class":270,"line":638},[268,3566,1246],{"class":339},[268,3568,3569],{"class":270,"line":644},[268,3570,790],{"class":274},[268,3572,3573],{"class":270,"line":650},[268,3574,3575],{"class":274},"         * Generate srcset from base image URL\n",[268,3577,3578],{"class":270,"line":656},[268,3579,3580],{"class":274},"         * Assumes image resizing service is available\n",[268,3582,3583],{"class":270,"line":662},[268,3584,830],{"class":274},[268,3586,3587,3590,3592,3594,3596,3598,3600,3603],{"class":270,"line":668},[268,3588,3589],{"class":300},"        generateSrcset",[268,3591,838],{"class":339},[268,3593,715],{"class":335},[268,3595,696],{"class":339},[268,3597,845],{"class":720},[268,3599,1434],{"class":339},[268,3601,3602],{"class":720},"maxWidth",[268,3604,724],{"class":339},[268,3606,3607,3609,3611,3613],{"class":270,"line":886},[268,3608,852],{"class":335},[268,3610,855],{"class":339},[268,3612,858],{"class":335},[268,3614,861],{"class":339},[268,3616,3617,3619,3621],{"class":270,"line":911},[268,3618,866],{"class":335},[268,3620,1348],{"class":311},[268,3622,732],{"class":339},[268,3624,3625],{"class":270,"line":934},[268,3626,874],{"class":339},[268,3628,3629],{"class":270,"line":951},[268,3630,1355],{"class":339},[268,3632,3633,3635,3638,3640,3643,3646,3648,3650,3652,3655],{"class":270,"line":956},[268,3634,889],{"class":335},[268,3636,3637],{"class":339}," applicableBreakpoints ",[268,3639,747],{"class":335},[268,3641,3642],{"class":339}," breakpoints.",[268,3644,3645],{"class":300},"filter",[268,3647,696],{"class":339},[268,3649,715],{"class":335},[268,3651,696],{"class":339},[268,3653,3654],{"class":720},"bp",[268,3656,724],{"class":339},[268,3658,3659,3661,3664,3667,3669,3672,3675],{"class":270,"line":964},[268,3660,866],{"class":335},[268,3662,3663],{"class":335}," !",[268,3665,3666],{"class":339},"maxWidth ",[268,3668,1345],{"class":335},[268,3670,3671],{"class":339}," bp ",[268,3673,3674],{"class":335},"\u003C=",[268,3676,3677],{"class":339}," maxWidth;\n",[268,3679,3680],{"class":270,"line":970},[268,3681,2306],{"class":339},[268,3683,3684],{"class":270,"line":982},[268,3685,1355],{"class":339},[268,3687,3688,3690,3693,3696,3698,3700,3702,3704],{"class":270,"line":993},[268,3689,959],{"class":335},[268,3691,3692],{"class":339}," applicableBreakpoints.",[268,3694,3695],{"class":300},"map",[268,3697,696],{"class":339},[268,3699,715],{"class":335},[268,3701,696],{"class":339},[268,3703,1868],{"class":720},[268,3705,724],{"class":339},[268,3707,3708,3711,3714,3716,3718,3720,3723],{"class":270,"line":1015},[268,3709,3710],{"class":335},"                var",[268,3712,3713],{"class":339}," resizedUrl ",[268,3715,747],{"class":335},[268,3717,1283],{"class":304},[268,3719,385],{"class":339},[268,3721,3722],{"class":300},"getResizedUrl",[268,3724,3725],{"class":339},"(baseUrl, width);\n",[268,3727,3728,3730,3732,3734,3737,3740,3743,3745,3748],{"class":270,"line":1035},[268,3729,866],{"class":335},[268,3731,3713],{"class":339},[268,3733,976],{"class":335},[268,3735,3736],{"class":311}," ' '",[268,3738,3739],{"class":335}," +",[268,3741,3742],{"class":339}," width ",[268,3744,976],{"class":335},[268,3746,3747],{"class":311}," 'w'",[268,3749,732],{"class":339},[268,3751,3752,3755,3757,3759,3761,3764,3767,3769,3772],{"class":270,"line":1041},[268,3753,3754],{"class":339},"            }.",[268,3756,2125],{"class":300},[268,3758,696],{"class":339},[268,3760,999],{"class":304},[268,3762,3763],{"class":339},")).",[268,3765,3766],{"class":300},"join",[268,3768,696],{"class":339},[268,3770,3771],{"class":311},"', '",[268,3773,908],{"class":339},[268,3775,3776],{"class":270,"line":1047},[268,3777,1044],{"class":339},[268,3779,3780],{"class":270,"line":1052},[268,3781,1246],{"class":339},[268,3783,3784],{"class":270,"line":1057},[268,3785,790],{"class":274},[268,3787,3788],{"class":270,"line":1063},[268,3789,3790],{"class":274},"         * Get the sizes attribute for a given context\n",[268,3792,3793],{"class":270,"line":1069},[268,3794,830],{"class":274},[268,3796,3797,3800,3802,3804,3806,3809],{"class":270,"line":1074},[268,3798,3799],{"class":300},"        getSizes",[268,3801,838],{"class":339},[268,3803,715],{"class":335},[268,3805,696],{"class":339},[268,3807,3808],{"class":720},"context",[268,3810,724],{"class":339},[268,3812,3813,3815,3818,3820,3823,3826],{"class":270,"line":1091},[268,3814,959],{"class":335},[268,3816,3817],{"class":339}," defaultSizes[context] ",[268,3819,1345],{"class":335},[268,3821,3822],{"class":339}," defaultSizes[",[268,3824,3825],{"class":311},"'product-listing'",[268,3827,3487],{"class":339},[268,3829,3830],{"class":270,"line":1097},[268,3831,1044],{"class":339},[268,3833,3834],{"class":270,"line":1103},[268,3835,1246],{"class":339},[268,3837,3838],{"class":270,"line":1113},[268,3839,790],{"class":274},[268,3841,3842],{"class":270,"line":1118},[268,3843,3844],{"class":274},"         * Transform URL to point to resized version\n",[268,3846,3847],{"class":270,"line":1123},[268,3848,3849],{"class":274},"         * Implementation depends on your image service\n",[268,3851,3852],{"class":270,"line":1139},[268,3853,830],{"class":274},[268,3855,3856,3859,3861,3863,3865,3868,3870,3872],{"class":270,"line":1145},[268,3857,3858],{"class":300},"        getResizedUrl",[268,3860,838],{"class":339},[268,3862,715],{"class":335},[268,3864,696],{"class":339},[268,3866,3867],{"class":720},"originalUrl",[268,3869,1434],{"class":339},[268,3871,1868],{"class":720},[268,3873,724],{"class":339},[268,3875,3876],{"class":270,"line":1158},[268,3877,3878],{"class":274},"            \u002F\u002F Option 1: URL parameter (if using image processing service)\n",[268,3880,3881],{"class":270,"line":1164},[268,3882,3883],{"class":274},"            \u002F\u002F return originalUrl + '?w=' + width + '&format=webp';\n",[268,3885,3886],{"class":270,"line":1169},[268,3887,1355],{"class":339},[268,3889,3890],{"class":270,"line":1781},[268,3891,3892],{"class":274},"            \u002F\u002F Option 2: URL path modification (pre-generated sizes)\n",[268,3894,3895,3897,3899,3901,3904,3906,3908,3910],{"class":270,"line":1786},[268,3896,889],{"class":335},[268,3898,892],{"class":339},[268,3900,747],{"class":335},[268,3902,3903],{"class":339}," originalUrl.",[268,3905,900],{"class":300},[268,3907,696],{"class":339},[268,3909,905],{"class":311},[268,3911,908],{"class":339},[268,3913,3914,3916,3918,3920,3922,3924,3926,3928],{"class":270,"line":1792},[268,3915,889],{"class":335},[268,3917,916],{"class":339},[268,3919,747],{"class":335},[268,3921,3903],{"class":339},[268,3923,923],{"class":300},[268,3925,696],{"class":339},[268,3927,928],{"class":304},[268,3929,931],{"class":339},[268,3931,3932,3934,3937,3939,3942,3944],{"class":270,"line":2405},[268,3933,889],{"class":335},[268,3935,3936],{"class":339}," ext ",[268,3938,747],{"class":335},[268,3940,3941],{"class":311}," '.webp'",[268,3943,349],{"class":339},[268,3945,3946],{"class":274},"\u002F\u002F Always serve WebP in srcset\n",[268,3948,3949],{"class":270,"line":2410},[268,3950,1355],{"class":339},[268,3952,3953,3955,3957,3959,3962,3964,3966,3968,3970,3972],{"class":270,"line":2415},[268,3954,959],{"class":335},[268,3956,916],{"class":339},[268,3958,976],{"class":335},[268,3960,3961],{"class":311}," '-'",[268,3963,3739],{"class":335},[268,3965,3742],{"class":339},[268,3967,976],{"class":335},[268,3969,3747],{"class":311},[268,3971,3739],{"class":335},[268,3973,3974],{"class":339}," ext;\n",[268,3976,3977],{"class":270,"line":2431},[268,3978,1044],{"class":339},[268,3980,3981],{"class":270,"line":2454},[268,3982,1246],{"class":339},[268,3984,3985],{"class":270,"line":2475},[268,3986,790],{"class":274},[268,3988,3989],{"class":270,"line":2480},[268,3990,3991],{"class":274},"         * Get complete responsive image attributes\n",[268,3993,3994],{"class":270,"line":2488},[268,3995,830],{"class":274},[268,3997,3998,4001,4003,4005,4007,4010,4012,4014,4016,4018],{"class":270,"line":2499},[268,3999,4000],{"class":300},"        getImageAttributes",[268,4002,838],{"class":339},[268,4004,715],{"class":335},[268,4006,696],{"class":339},[268,4008,4009],{"class":720},"imageUrl",[268,4011,1434],{"class":339},[268,4013,3808],{"class":720},[268,4015,1434],{"class":339},[268,4017,1956],{"class":720},[268,4019,724],{"class":339},[268,4021,4022,4025,4027,4030,4032],{"class":270,"line":2514},[268,4023,4024],{"class":339},"            options ",[268,4026,747],{"class":335},[268,4028,4029],{"class":339}," options ",[268,4031,1345],{"class":335},[268,4033,869],{"class":339},[268,4035,4036],{"class":270,"line":2519},[268,4037,1355],{"class":339},[268,4039,4040,4042],{"class":270,"line":2524},[268,4041,959],{"class":335},[268,4043,750],{"class":339},[268,4045,4046,4049,4051,4053,4055,4058,4060,4063],{"class":270,"line":2532},[268,4047,4048],{"class":339},"                src: ",[268,4050,999],{"class":304},[268,4052,385],{"class":339},[268,4054,3722],{"class":300},[268,4056,4057],{"class":339},"(imageUrl, options.defaultWidth ",[268,4059,1345],{"class":335},[268,4061,4062],{"class":304}," 800",[268,4064,2132],{"class":339},[268,4066,4067,4070,4072,4074,4077],{"class":270,"line":2543},[268,4068,4069],{"class":339},"                srcset: ",[268,4071,999],{"class":304},[268,4073,385],{"class":339},[268,4075,4076],{"class":300},"generateSrcset",[268,4078,4079],{"class":339},"(imageUrl, options.maxWidth),\n",[268,4081,4082,4085,4087,4089,4092],{"class":270,"line":2556},[268,4083,4084],{"class":339},"                sizes: ",[268,4086,999],{"class":304},[268,4088,385],{"class":339},[268,4090,4091],{"class":300},"getSizes",[268,4093,4094],{"class":339},"(context),\n",[268,4096,4097,4100,4102,4104],{"class":270,"line":2561},[268,4098,4099],{"class":339},"                width: options.width ",[268,4101,1345],{"class":335},[268,4103,1348],{"class":311},[268,4105,761],{"class":339},[268,4107,4108,4111,4113],{"class":270,"line":2566},[268,4109,4110],{"class":339},"                height: options.height ",[268,4112,1345],{"class":335},[268,4114,4115],{"class":311}," ''\n",[268,4117,4118],{"class":270,"line":2572},[268,4119,1038],{"class":339},[268,4121,4122],{"class":270,"line":2588},[268,4123,1161],{"class":339},[268,4125,4126],{"class":270,"line":2593},[268,4127,774],{"class":339},[268,4129,4130],{"class":270,"line":2598},[268,4131,1172],{"class":339},[15,4133,4134],{},[18,4135,4136],{},"Using the helper in a View:",[258,4138,4140],{"className":679,"code":4139,"language":681,"meta":263,"style":263},"\u002F\u002F ProductListItem.View.js\ndefine('ProductListItem.View', [\n    'Backbone',\n    'ResponsiveImageHelper',\n    'product_list_item.tpl'\n], function(Backbone, ResponsiveImageHelper, template) {\n    'use strict';\n\n    return Backbone.View.extend({\n        \n        template: template,\n        \n        getContext: function() {\n            var imageUrl = this.model.get('thumbnail');\n            var imageAttrs = ResponsiveImageHelper.getImageAttributes(\n                imageUrl, \n                'product-listing',\n                { \n                    defaultWidth: 400,\n                    maxWidth: 800,\n                    width: 400,\n                    height: 400\n                }\n            );\n            \n            return {\n                productName: this.model.get('displayname'),\n                productUrl: this.model.get('url'),\n                imageUrl: imageAttrs.src,\n                imageSrcset: imageAttrs.srcset,\n                imageSizes: imageAttrs.sizes,\n                imageWidth: imageAttrs.width,\n                imageHeight: imageAttrs.height\n            };\n        }\n    });\n});\n",[265,4141,4142,4147,4158,4165,4172,4177,4200,4206,4210,4221,4225,4230,4234,4245,4268,4285,4290,4297,4302,4311,4320,4329,4337,4341,4346,4350,4356,4374,4392,4397,4402,4407,4412,4417,4421,4425,4429],{"__ignoreMap":263},[268,4143,4144],{"class":270,"line":271},[268,4145,4146],{"class":274},"\u002F\u002F ProductListItem.View.js\n",[268,4148,4149,4151,4153,4156],{"class":270,"line":278},[268,4150,693],{"class":300},[268,4152,696],{"class":339},[268,4154,4155],{"class":311},"'ProductListItem.View'",[268,4157,702],{"class":339},[268,4159,4160,4163],{"class":270,"line":284},[268,4161,4162],{"class":311},"    'Backbone'",[268,4164,761],{"class":339},[268,4166,4167,4170],{"class":270,"line":291},[268,4168,4169],{"class":311},"    'ResponsiveImageHelper'",[268,4171,761],{"class":339},[268,4173,4174],{"class":270,"line":297},[268,4175,4176],{"class":311},"    'product_list_item.tpl'\n",[268,4178,4179,4181,4183,4185,4188,4190,4193,4195,4198],{"class":270,"line":321},[268,4180,712],{"class":339},[268,4182,715],{"class":335},[268,4184,696],{"class":339},[268,4186,4187],{"class":720},"Backbone",[268,4189,1434],{"class":339},[268,4191,4192],{"class":720},"ResponsiveImageHelper",[268,4194,1434],{"class":339},[268,4196,4197],{"class":720},"template",[268,4199,724],{"class":339},[268,4201,4202,4204],{"class":270,"line":326},[268,4203,729],{"class":311},[268,4205,732],{"class":339},[268,4207,4208],{"class":270,"line":332},[268,4209,288],{"emptyLinePlaceholder":287},[268,4211,4212,4214,4217,4219],{"class":270,"line":355},[268,4213,783],{"class":335},[268,4215,4216],{"class":339}," Backbone.View.",[268,4218,1238],{"class":300},[268,4220,1241],{"class":339},[268,4222,4223],{"class":270,"line":394},[268,4224,1246],{"class":339},[268,4226,4227],{"class":270,"line":598},[268,4228,4229],{"class":339},"        template: template,\n",[268,4231,4232],{"class":270,"line":604},[268,4233,1246],{"class":339},[268,4235,4236,4239,4241,4243],{"class":270,"line":610},[268,4237,4238],{"class":300},"        getContext",[268,4240,838],{"class":339},[268,4242,715],{"class":335},[268,4244,1271],{"class":339},[268,4246,4247,4249,4251,4253,4255,4258,4261,4263,4266],{"class":270,"line":615},[268,4248,889],{"class":335},[268,4250,1394],{"class":339},[268,4252,747],{"class":335},[268,4254,1283],{"class":304},[268,4256,4257],{"class":339},".model.",[268,4259,4260],{"class":300},"get",[268,4262,696],{"class":339},[268,4264,4265],{"class":311},"'thumbnail'",[268,4267,908],{"class":339},[268,4269,4270,4272,4275,4277,4280,4283],{"class":270,"line":620},[268,4271,889],{"class":335},[268,4273,4274],{"class":339}," imageAttrs ",[268,4276,747],{"class":335},[268,4278,4279],{"class":339}," ResponsiveImageHelper.",[268,4281,4282],{"class":300},"getImageAttributes",[268,4284,2114],{"class":339},[268,4286,4287],{"class":270,"line":626},[268,4288,4289],{"class":339},"                imageUrl, \n",[268,4291,4292,4295],{"class":270,"line":632},[268,4293,4294],{"class":311},"                'product-listing'",[268,4296,761],{"class":339},[268,4298,4299],{"class":270,"line":638},[268,4300,4301],{"class":339},"                { \n",[268,4303,4304,4307,4309],{"class":270,"line":644},[268,4305,4306],{"class":339},"                    defaultWidth: ",[268,4308,3464],{"class":304},[268,4310,761],{"class":339},[268,4312,4313,4316,4318],{"class":270,"line":650},[268,4314,4315],{"class":339},"                    maxWidth: ",[268,4317,3474],{"class":304},[268,4319,761],{"class":339},[268,4321,4322,4325,4327],{"class":270,"line":656},[268,4323,4324],{"class":339},"                    width: ",[268,4326,3464],{"class":304},[268,4328,761],{"class":339},[268,4330,4331,4334],{"class":270,"line":662},[268,4332,4333],{"class":339},"                    height: ",[268,4335,4336],{"class":304},"400\n",[268,4338,4339],{"class":270,"line":668},[268,4340,2398],{"class":339},[268,4342,4343],{"class":270,"line":886},[268,4344,4345],{"class":339},"            );\n",[268,4347,4348],{"class":270,"line":911},[268,4349,1355],{"class":339},[268,4351,4352,4354],{"class":270,"line":934},[268,4353,959],{"class":335},[268,4355,750],{"class":339},[268,4357,4358,4361,4363,4365,4367,4369,4372],{"class":270,"line":951},[268,4359,4360],{"class":339},"                productName: ",[268,4362,999],{"class":304},[268,4364,4257],{"class":339},[268,4366,4260],{"class":300},[268,4368,696],{"class":339},[268,4370,4371],{"class":311},"'displayname'",[268,4373,2132],{"class":339},[268,4375,4376,4379,4381,4383,4385,4387,4390],{"class":270,"line":956},[268,4377,4378],{"class":339},"                productUrl: ",[268,4380,999],{"class":304},[268,4382,4257],{"class":339},[268,4384,4260],{"class":300},[268,4386,696],{"class":339},[268,4388,4389],{"class":311},"'url'",[268,4391,2132],{"class":339},[268,4393,4394],{"class":270,"line":964},[268,4395,4396],{"class":339},"                imageUrl: imageAttrs.src,\n",[268,4398,4399],{"class":270,"line":970},[268,4400,4401],{"class":339},"                imageSrcset: imageAttrs.srcset,\n",[268,4403,4404],{"class":270,"line":982},[268,4405,4406],{"class":339},"                imageSizes: imageAttrs.sizes,\n",[268,4408,4409],{"class":270,"line":993},[268,4410,4411],{"class":339},"                imageWidth: imageAttrs.width,\n",[268,4413,4414],{"class":270,"line":1015},[268,4415,4416],{"class":339},"                imageHeight: imageAttrs.height\n",[268,4418,4419],{"class":270,"line":1035},[268,4420,1038],{"class":339},[268,4422,4423],{"class":270,"line":1041},[268,4424,1161],{"class":339},[268,4426,4427],{"class":270,"line":1047},[268,4428,1789],{"class":339},[268,4430,4431],{"class":270,"line":1052},[268,4432,1172],{"class":339},[15,4434,4435],{},[18,4436,4437],{},"Template using responsive image attributes:",[258,4439,4441],{"className":542,"code":4440,"language":544,"meta":263,"style":263},"{{!-- product_list_item.tpl --}}\n\u003Ca href=\"{{productUrl}}\" class=\"product-list-item-link\">\n    \u003Cimg \n        src=\"{{imageUrl}}\"\n        srcset=\"{{imageSrcset}}\"\n        sizes=\"{{imageSizes}}\"\n        alt=\"{{productName}}\"\n        width=\"{{imageWidth}}\"\n        height=\"{{imageHeight}}\"\n        loading=\"lazy\"\n        class=\"product-list-item-image\"\n    \u002F>\n    \u003Cspan class=\"product-list-item-name\">{{productName}}\u003C\u002Fspan>\n\u003C\u002Fa>\n",[265,4442,4443,4447,4452,4456,4461,4466,4471,4475,4480,4485,4489,4494,4498,4503],{"__ignoreMap":263},[268,4444,4445],{"class":270,"line":271},[268,4446,2810],{},[268,4448,4449],{"class":270,"line":278},[268,4450,4451],{},"\u003Ca href=\"{{productUrl}}\" class=\"product-list-item-link\">\n",[268,4453,4454],{"class":270,"line":284},[268,4455,623],{},[268,4457,4458],{"class":270,"line":291},[268,4459,4460],{},"        src=\"{{imageUrl}}\"\n",[268,4462,4463],{"class":270,"line":297},[268,4464,4465],{},"        srcset=\"{{imageSrcset}}\"\n",[268,4467,4468],{"class":270,"line":321},[268,4469,4470],{},"        sizes=\"{{imageSizes}}\"\n",[268,4472,4473],{"class":270,"line":326},[268,4474,2839],{},[268,4476,4477],{"class":270,"line":332},[268,4478,4479],{},"        width=\"{{imageWidth}}\"\n",[268,4481,4482],{"class":270,"line":355},[268,4483,4484],{},"        height=\"{{imageHeight}}\"\n",[268,4486,4487],{"class":270,"line":394},[268,4488,647],{},[268,4490,4491],{"class":270,"line":598},[268,4492,4493],{},"        class=\"product-list-item-image\"\n",[268,4495,4496],{"class":270,"line":604},[268,4497,665],{},[268,4499,4500],{"class":270,"line":610},[268,4501,4502],{},"    \u003Cspan class=\"product-list-item-name\">{{productName}}\u003C\u002Fspan>\n",[268,4504,4505],{"class":270,"line":615},[268,4506,4507],{},"\u003C\u002Fa>\n",[110,4509,4511],{"id":4510},"generating-multiple-image-sizes","Generating Multiple Image Sizes",[15,4513,4514],{},"For pre-generated responsive images, create a build script:",[258,4516,4518],{"className":679,"code":4517,"language":681,"meta":263,"style":263},"\u002F\u002F scripts\u002Fgenerate-responsive-images.js\nconst sharp = require('sharp');\nconst fs = require('fs');\nconst path = require('path');\n\nconst sizes = [400, 600, 800, 1200, 1600];\nconst inputDir = '.\u002Fimages\u002Foriginals';\nconst outputDir = '.\u002Fimages\u002Fresponsive';\n\nasync function processImage(inputPath) {\n    const filename = path.basename(inputPath, path.extname(inputPath));\n    \n    for (const width of sizes) {\n        const outputPath = path.join(outputDir, `${filename}-${width}w.webp`);\n        \n        await sharp(inputPath)\n            .resize(width, null, {\n                fit: 'inside',\n                withoutEnlargement: true\n            })\n            .webp({ quality: 80 })\n            .toFile(outputPath);\n        \n        console.log(`Generated: ${outputPath}`);\n    }\n}\n\nasync function processDirectory() {\n    const files = fs.readdirSync(inputDir);\n    \n    for (const file of files) {\n        if (\u002F\\.(jpg|jpeg|png)$\u002Fi.test(file)) {\n            await processImage(path.join(inputDir, file));\n        }\n    }\n}\n\nprocessDirectory().catch(console.error);\n",[265,4519,4520,4525,4545,4563,4581,4585,4616,4630,4644,4648,4665,4690,4694,4712,4745,4749,4759,4775,4785,4793,4798,4814,4824,4828,4849,4853,4857,4861,4872,4890,4894,4910,4945,4960,4964,4968,4972,4976],{"__ignoreMap":263},[268,4521,4522],{"class":270,"line":271},[268,4523,4524],{"class":274},"\u002F\u002F scripts\u002Fgenerate-responsive-images.js\n",[268,4526,4527,4530,4533,4535,4538,4540,4543],{"class":270,"line":278},[268,4528,4529],{"class":335},"const",[268,4531,4532],{"class":304}," sharp",[268,4534,1948],{"class":335},[268,4536,4537],{"class":300}," require",[268,4539,696],{"class":339},[268,4541,4542],{"class":311},"'sharp'",[268,4544,908],{"class":339},[268,4546,4547,4549,4552,4554,4556,4558,4561],{"class":270,"line":284},[268,4548,4529],{"class":335},[268,4550,4551],{"class":304}," fs",[268,4553,1948],{"class":335},[268,4555,4537],{"class":300},[268,4557,696],{"class":339},[268,4559,4560],{"class":311},"'fs'",[268,4562,908],{"class":339},[268,4564,4565,4567,4570,4572,4574,4576,4579],{"class":270,"line":291},[268,4566,4529],{"class":335},[268,4568,4569],{"class":304}," path",[268,4571,1948],{"class":335},[268,4573,4537],{"class":300},[268,4575,696],{"class":339},[268,4577,4578],{"class":311},"'path'",[268,4580,908],{"class":339},[268,4582,4583],{"class":270,"line":297},[268,4584,288],{"emptyLinePlaceholder":287},[268,4586,4587,4589,4592,4594,4596,4598,4600,4602,4604,4606,4608,4610,4612,4614],{"class":270,"line":321},[268,4588,4529],{"class":335},[268,4590,4591],{"class":304}," sizes",[268,4593,1948],{"class":335},[268,4595,3461],{"class":339},[268,4597,3464],{"class":304},[268,4599,1434],{"class":339},[268,4601,3469],{"class":304},[268,4603,1434],{"class":339},[268,4605,3474],{"class":304},[268,4607,1434],{"class":339},[268,4609,3479],{"class":304},[268,4611,1434],{"class":339},[268,4613,3484],{"class":304},[268,4615,3487],{"class":339},[268,4617,4618,4620,4623,4625,4628],{"class":270,"line":326},[268,4619,4529],{"class":335},[268,4621,4622],{"class":304}," inputDir",[268,4624,1948],{"class":335},[268,4626,4627],{"class":311}," '.\u002Fimages\u002Foriginals'",[268,4629,732],{"class":339},[268,4631,4632,4634,4637,4639,4642],{"class":270,"line":332},[268,4633,4529],{"class":335},[268,4635,4636],{"class":304}," outputDir",[268,4638,1948],{"class":335},[268,4640,4641],{"class":311}," '.\u002Fimages\u002Fresponsive'",[268,4643,732],{"class":339},[268,4645,4646],{"class":270,"line":355},[268,4647,288],{"emptyLinePlaceholder":287},[268,4649,4650,4653,4655,4658,4660,4663],{"class":270,"line":394},[268,4651,4652],{"class":335},"async",[268,4654,1951],{"class":335},[268,4656,4657],{"class":300}," processImage",[268,4659,696],{"class":339},[268,4661,4662],{"class":720},"inputPath",[268,4664,724],{"class":339},[268,4666,4667,4670,4673,4675,4678,4681,4684,4687],{"class":270,"line":598},[268,4668,4669],{"class":335},"    const",[268,4671,4672],{"class":304}," filename",[268,4674,1948],{"class":335},[268,4676,4677],{"class":339}," path.",[268,4679,4680],{"class":300},"basename",[268,4682,4683],{"class":339},"(inputPath, path.",[268,4685,4686],{"class":300},"extname",[268,4688,4689],{"class":339},"(inputPath));\n",[268,4691,4692],{"class":270,"line":604},[268,4693,2936],{"class":339},[268,4695,4696,4699,4701,4703,4706,4709],{"class":270,"line":610},[268,4697,4698],{"class":335},"    for",[268,4700,855],{"class":339},[268,4702,4529],{"class":335},[268,4704,4705],{"class":304}," width",[268,4707,4708],{"class":335}," of",[268,4710,4711],{"class":339}," sizes) {\n",[268,4713,4714,4717,4720,4722,4724,4726,4729,4732,4735,4738,4740,4743],{"class":270,"line":615},[268,4715,4716],{"class":335},"        const",[268,4718,4719],{"class":304}," outputPath",[268,4721,1948],{"class":335},[268,4723,4677],{"class":339},[268,4725,3766],{"class":300},[268,4727,4728],{"class":339},"(outputDir, ",[268,4730,4731],{"class":311},"`${",[268,4733,4734],{"class":339},"filename",[268,4736,4737],{"class":311},"}-${",[268,4739,1868],{"class":339},[268,4741,4742],{"class":311},"}w.webp`",[268,4744,908],{"class":339},[268,4746,4747],{"class":270,"line":620},[268,4748,1246],{"class":339},[268,4750,4751,4754,4756],{"class":270,"line":626},[268,4752,4753],{"class":335},"        await",[268,4755,4532],{"class":300},[268,4757,4758],{"class":339},"(inputPath)\n",[268,4760,4761,4764,4767,4770,4773],{"class":270,"line":632},[268,4762,4763],{"class":339},"            .",[268,4765,4766],{"class":300},"resize",[268,4768,4769],{"class":339},"(width, ",[268,4771,4772],{"class":304},"null",[268,4774,2066],{"class":339},[268,4776,4777,4780,4783],{"class":270,"line":638},[268,4778,4779],{"class":339},"                fit: ",[268,4781,4782],{"class":311},"'inside'",[268,4784,761],{"class":339},[268,4786,4787,4790],{"class":270,"line":644},[268,4788,4789],{"class":339},"                withoutEnlargement: ",[268,4791,4792],{"class":304},"true\n",[268,4794,4795],{"class":270,"line":650},[268,4796,4797],{"class":339},"            })\n",[268,4799,4800,4802,4805,4808,4811],{"class":270,"line":656},[268,4801,4763],{"class":339},[268,4803,4804],{"class":300},"webp",[268,4806,4807],{"class":339},"({ quality: ",[268,4809,4810],{"class":304},"80",[268,4812,4813],{"class":339}," })\n",[268,4815,4816,4818,4821],{"class":270,"line":662},[268,4817,4763],{"class":339},[268,4819,4820],{"class":300},"toFile",[268,4822,4823],{"class":339},"(outputPath);\n",[268,4825,4826],{"class":270,"line":668},[268,4827,1246],{"class":339},[268,4829,4830,4833,4836,4838,4841,4844,4847],{"class":270,"line":886},[268,4831,4832],{"class":339},"        console.",[268,4834,4835],{"class":300},"log",[268,4837,696],{"class":339},[268,4839,4840],{"class":311},"`Generated: ${",[268,4842,4843],{"class":339},"outputPath",[268,4845,4846],{"class":311},"}`",[268,4848,908],{"class":339},[268,4850,4851],{"class":270,"line":911},[268,4852,2963],{"class":339},[268,4854,4855],{"class":270,"line":934},[268,4856,2968],{"class":339},[268,4858,4859],{"class":270,"line":951},[268,4860,288],{"emptyLinePlaceholder":287},[268,4862,4863,4865,4867,4870],{"class":270,"line":956},[268,4864,4652],{"class":335},[268,4866,1951],{"class":335},[268,4868,4869],{"class":300}," processDirectory",[268,4871,1271],{"class":339},[268,4873,4874,4876,4879,4881,4884,4887],{"class":270,"line":964},[268,4875,4669],{"class":335},[268,4877,4878],{"class":304}," files",[268,4880,1948],{"class":335},[268,4882,4883],{"class":339}," fs.",[268,4885,4886],{"class":300},"readdirSync",[268,4888,4889],{"class":339},"(inputDir);\n",[268,4891,4892],{"class":270,"line":970},[268,4893,2936],{"class":339},[268,4895,4896,4898,4900,4902,4905,4907],{"class":270,"line":982},[268,4897,4698],{"class":335},[268,4899,855],{"class":339},[268,4901,4529],{"class":335},[268,4903,4904],{"class":304}," file",[268,4906,4708],{"class":335},[268,4908,4909],{"class":339}," files) {\n",[268,4911,4912,4915,4917,4919,4921,4923,4925,4927,4929,4931,4933,4935,4937,4939,4942],{"class":270,"line":993},[268,4913,4914],{"class":335},"        if",[268,4916,855],{"class":339},[268,4918,1682],{"class":311},[268,4920,1686],{"class":1685},[268,4922,1690],{"class":1689},[268,4924,1693],{"class":335},[268,4926,1696],{"class":1689},[268,4928,1693],{"class":335},[268,4930,1701],{"class":1689},[268,4932,1704],{"class":335},[268,4934,1682],{"class":311},[268,4936,1709],{"class":335},[268,4938,385],{"class":339},[268,4940,4941],{"class":300},"test",[268,4943,4944],{"class":339},"(file)) {\n",[268,4946,4947,4950,4952,4955,4957],{"class":270,"line":1015},[268,4948,4949],{"class":335},"            await",[268,4951,4657],{"class":300},[268,4953,4954],{"class":339},"(path.",[268,4956,3766],{"class":300},[268,4958,4959],{"class":339},"(inputDir, file));\n",[268,4961,4962],{"class":270,"line":1035},[268,4963,1161],{"class":339},[268,4965,4966],{"class":270,"line":1041},[268,4967,2963],{"class":339},[268,4969,4970],{"class":270,"line":1047},[268,4971,2968],{"class":339},[268,4973,4974],{"class":270,"line":1052},[268,4975,288],{"emptyLinePlaceholder":287},[268,4977,4978,4981,4984,4987],{"class":270,"line":1057},[268,4979,4980],{"class":300},"processDirectory",[268,4982,4983],{"class":339},"().",[268,4985,4986],{"class":300},"catch",[268,4988,4989],{"class":339},"(console.error);\n",[26,4991],{},[29,4993,67],{"id":4994},"cdn-configuration-for-images",[15,4996,4997],{},"A properly configured CDN reduces image delivery time by 50-80%.",[110,4999,5001],{"id":5000},"cdn-selection-for-suitecommerce","CDN Selection for SuiteCommerce",[15,5003,5004],{},"SuiteCommerce sites commonly use:",[217,5006,5007,5013,5019,5025],{},[37,5008,5009,5012],{},[18,5010,5011],{},"Akamai"," (NetSuite's default CDN partner)",[37,5014,5015,5018],{},[18,5016,5017],{},"Cloudflare"," (cost-effective, excellent performance)",[37,5020,5021,5024],{},[18,5022,5023],{},"AWS CloudFront"," (flexible, good for custom setups)",[37,5026,5027,5030],{},[18,5028,5029],{},"Fastly"," (premium performance, higher cost)",[15,5032,5033],{},"Each CDN supports image optimization features. Configure them to maximize benefit.",[110,5035,5037],{"id":5036},"cloudflare-image-optimization","Cloudflare Image Optimization",[15,5039,5040],{},"If using Cloudflare, enable these features:",[15,5042,5043],{},[18,5044,5045],{},"Polish (image compression):",[258,5047,5052],{"className":5048,"code":5050,"language":5051},[5049],"language-text","Dashboard → Speed → Optimization → Image Optimization → Polish: Lossless\n","text",[265,5053,5050],{"__ignoreMap":263},[15,5055,5056],{},[18,5057,5058],{},"WebP conversion:",[258,5060,5063],{"className":5061,"code":5062,"language":5051},[5049],"Dashboard → Speed → Optimization → Image Optimization → WebP: On\n",[265,5064,5062],{"__ignoreMap":263},[15,5066,5067],{},[18,5068,5069],{},"Mirage (lazy loading for mobile):",[258,5071,5074],{"className":5072,"code":5073,"language":5051},[5049],"Dashboard → Speed → Optimization → Image Optimization → Mirage: On\n",[265,5075,5073],{"__ignoreMap":263},[15,5077,5078],{},[18,5079,5080],{},"Cache rules for images:",[258,5082,5085],{"className":5083,"code":5084,"language":5051},[5049],"# Page Rule\nURL: *yourdomain.com\u002F*.jpg*\nSettings:\n  - Cache Level: Cache Everything\n  - Edge Cache TTL: 1 month\n  - Browser Cache TTL: 1 week\n",[265,5086,5084],{"__ignoreMap":263},[110,5088,5090],{"id":5089},"custom-cdn-headers","Custom CDN Headers",[15,5092,5093],{},"Set proper cache headers in your image service:",[258,5095,5097],{"className":679,"code":5096,"language":681,"meta":263,"style":263},"\u002F\u002F ImageService.ServiceController.js\nget: function() {\n    var imageUrl = this.request.getParameter('url');\n    \n    \u002F\u002F Set CDN-friendly cache headers\n    this.response.setHeader('Cache-Control', 'public, max-age=31536000, immutable');\n    this.response.setHeader('Vary', 'Accept'); \u002F\u002F Vary by Accept for format negotiation\n    \n    \u002F\u002F ETag for cache validation\n    var etag = this.generateETag(imageUrl);\n    this.response.setHeader('ETag', etag);\n    \n    return { url: imageUrl };\n}\n",[265,5098,5099,5103,5113,5133,5137,5142,5162,5184,5188,5193,5212,5228,5232,5239],{"__ignoreMap":263},[268,5100,5101],{"class":270,"line":271},[268,5102,1189],{"class":274},[268,5104,5105,5107,5109,5111],{"class":270,"line":278},[268,5106,4260],{"class":300},[268,5108,838],{"class":339},[268,5110,715],{"class":335},[268,5112,1271],{"class":339},[268,5114,5115,5117,5119,5121,5123,5125,5127,5129,5131],{"class":270,"line":284},[268,5116,741],{"class":335},[268,5118,1394],{"class":339},[268,5120,747],{"class":335},[268,5122,1283],{"class":304},[268,5124,1286],{"class":339},[268,5126,1289],{"class":300},[268,5128,696],{"class":339},[268,5130,4389],{"class":311},[268,5132,908],{"class":339},[268,5134,5135],{"class":270,"line":291},[268,5136,2936],{"class":339},[268,5138,5139],{"class":270,"line":297},[268,5140,5141],{"class":274},"    \u002F\u002F Set CDN-friendly cache headers\n",[268,5143,5144,5147,5149,5151,5153,5155,5157,5160],{"class":270,"line":321},[268,5145,5146],{"class":304},"    this",[268,5148,1423],{"class":339},[268,5150,1426],{"class":300},[268,5152,696],{"class":339},[268,5154,1431],{"class":311},[268,5156,1434],{"class":339},[268,5158,5159],{"class":311},"'public, max-age=31536000, immutable'",[268,5161,908],{"class":339},[268,5163,5164,5166,5168,5170,5172,5174,5176,5178,5181],{"class":270,"line":326},[268,5165,5146],{"class":304},[268,5167,1423],{"class":339},[268,5169,1426],{"class":300},[268,5171,696],{"class":339},[268,5173,1452],{"class":311},[268,5175,1434],{"class":339},[268,5177,1339],{"class":311},[268,5179,5180],{"class":339},"); ",[268,5182,5183],{"class":274},"\u002F\u002F Vary by Accept for format negotiation\n",[268,5185,5186],{"class":270,"line":332},[268,5187,2936],{"class":339},[268,5189,5190],{"class":270,"line":355},[268,5191,5192],{"class":274},"    \u002F\u002F ETag for cache validation\n",[268,5194,5195,5197,5200,5202,5204,5206,5209],{"class":270,"line":394},[268,5196,741],{"class":335},[268,5198,5199],{"class":339}," etag ",[268,5201,747],{"class":335},[268,5203,1283],{"class":304},[268,5205,385],{"class":339},[268,5207,5208],{"class":300},"generateETag",[268,5210,5211],{"class":339},"(imageUrl);\n",[268,5213,5214,5216,5218,5220,5222,5225],{"class":270,"line":598},[268,5215,5146],{"class":304},[268,5217,1423],{"class":339},[268,5219,1426],{"class":300},[268,5221,696],{"class":339},[268,5223,5224],{"class":311},"'ETag'",[268,5226,5227],{"class":339},", etag);\n",[268,5229,5230],{"class":270,"line":604},[268,5231,2936],{"class":339},[268,5233,5234,5236],{"class":270,"line":610},[268,5235,783],{"class":335},[268,5237,5238],{"class":339}," { url: imageUrl };\n",[268,5240,5241],{"class":270,"line":615},[268,5242,2968],{"class":339},[110,5244,5246],{"id":5245},"cdn-url-rewriting","CDN URL Rewriting",[15,5248,5249],{},"Rewrite image URLs to point to your CDN:",[258,5251,5253],{"className":679,"code":5252,"language":681,"meta":263,"style":263},"\u002F\u002F CDNImageUrl.js\ndefine('CDNImageUrl', [\n    'SC.Configuration'\n], function(Configuration) {\n    'use strict';\n\n    var cdnBase = Configuration.get('images.cdnBaseUrl', '');\n    var enabled = Configuration.get('images.useCDN', false);\n\n    return {\n        transform: function(originalUrl) {\n            if (!enabled || !cdnBase || !originalUrl) {\n                return originalUrl;\n            }\n            \n            \u002F\u002F Replace NetSuite file cabinet URL with CDN URL\n            if (originalUrl.indexOf('netsuite.com') !== -1 || \n                originalUrl.indexOf('\u002Fsite\u002F') !== -1) {\n                \n                var pathMatch = originalUrl.match(\u002F\\\u002Fsite\\\u002F(.+)$\u002F);\n                if (pathMatch) {\n                    return cdnBase + '\u002F' + pathMatch[1];\n                }\n            }\n            \n            return originalUrl;\n        }\n    };\n});\n",[265,5254,5255,5260,5271,5275,5287,5293,5297,5323,5348,5352,5358,5373,5398,5405,5409,5413,5418,5445,5467,5471,5512,5519,5539,5543,5547,5551,5557,5561,5565],{"__ignoreMap":263},[268,5256,5257],{"class":270,"line":271},[268,5258,5259],{"class":274},"\u002F\u002F CDNImageUrl.js\n",[268,5261,5262,5264,5266,5269],{"class":270,"line":278},[268,5263,693],{"class":300},[268,5265,696],{"class":339},[268,5267,5268],{"class":311},"'CDNImageUrl'",[268,5270,702],{"class":339},[268,5272,5273],{"class":270,"line":284},[268,5274,3422],{"class":311},[268,5276,5277,5279,5281,5283,5285],{"class":270,"line":291},[268,5278,712],{"class":339},[268,5280,715],{"class":335},[268,5282,696],{"class":339},[268,5284,3437],{"class":720},[268,5286,724],{"class":339},[268,5288,5289,5291],{"class":270,"line":297},[268,5290,729],{"class":311},[268,5292,732],{"class":339},[268,5294,5295],{"class":270,"line":321},[268,5296,288],{"emptyLinePlaceholder":287},[268,5298,5299,5301,5304,5306,5309,5311,5313,5316,5318,5321],{"class":270,"line":326},[268,5300,741],{"class":335},[268,5302,5303],{"class":339}," cdnBase ",[268,5305,747],{"class":335},[268,5307,5308],{"class":339}," Configuration.",[268,5310,4260],{"class":300},[268,5312,696],{"class":339},[268,5314,5315],{"class":311},"'images.cdnBaseUrl'",[268,5317,1434],{"class":339},[268,5319,5320],{"class":311},"''",[268,5322,908],{"class":339},[268,5324,5325,5327,5330,5332,5334,5336,5338,5341,5343,5346],{"class":270,"line":332},[268,5326,741],{"class":335},[268,5328,5329],{"class":339}," enabled ",[268,5331,747],{"class":335},[268,5333,5308],{"class":339},[268,5335,4260],{"class":300},[268,5337,696],{"class":339},[268,5339,5340],{"class":311},"'images.useCDN'",[268,5342,1434],{"class":339},[268,5344,5345],{"class":304},"false",[268,5347,908],{"class":339},[268,5349,5350],{"class":270,"line":355},[268,5351,288],{"emptyLinePlaceholder":287},[268,5353,5354,5356],{"class":270,"line":394},[268,5355,783],{"class":335},[268,5357,750],{"class":339},[268,5359,5360,5363,5365,5367,5369,5371],{"class":270,"line":598},[268,5361,5362],{"class":300},"        transform",[268,5364,838],{"class":339},[268,5366,715],{"class":335},[268,5368,696],{"class":339},[268,5370,3867],{"class":720},[268,5372,724],{"class":339},[268,5374,5375,5377,5379,5381,5384,5386,5388,5391,5393,5395],{"class":270,"line":604},[268,5376,852],{"class":335},[268,5378,855],{"class":339},[268,5380,858],{"class":335},[268,5382,5383],{"class":339},"enabled ",[268,5385,1345],{"class":335},[268,5387,3663],{"class":335},[268,5389,5390],{"class":339},"cdnBase ",[268,5392,1345],{"class":335},[268,5394,3663],{"class":335},[268,5396,5397],{"class":339},"originalUrl) {\n",[268,5399,5400,5402],{"class":270,"line":610},[268,5401,866],{"class":335},[268,5403,5404],{"class":339}," originalUrl;\n",[268,5406,5407],{"class":270,"line":615},[268,5408,874],{"class":339},[268,5410,5411],{"class":270,"line":620},[268,5412,1355],{"class":339},[268,5414,5415],{"class":270,"line":626},[268,5416,5417],{"class":274},"            \u002F\u002F Replace NetSuite file cabinet URL with CDN URL\n",[268,5419,5420,5422,5425,5427,5429,5432,5434,5436,5438,5440,5443],{"class":270,"line":632},[268,5421,852],{"class":335},[268,5423,5424],{"class":339}," (originalUrl.",[268,5426,1516],{"class":300},[268,5428,696],{"class":339},[268,5430,5431],{"class":311},"'netsuite.com'",[268,5433,1342],{"class":339},[268,5435,1526],{"class":335},[268,5437,1529],{"class":335},[268,5439,1532],{"class":304},[268,5441,5442],{"class":335}," ||",[268,5444,3271],{"class":339},[268,5446,5447,5450,5452,5454,5457,5459,5461,5463,5465],{"class":270,"line":638},[268,5448,5449],{"class":339},"                originalUrl.",[268,5451,1516],{"class":300},[268,5453,696],{"class":339},[268,5455,5456],{"class":311},"'\u002Fsite\u002F'",[268,5458,1342],{"class":339},[268,5460,1526],{"class":335},[268,5462,1529],{"class":335},[268,5464,1532],{"class":304},[268,5466,724],{"class":339},[268,5468,5469],{"class":270,"line":644},[268,5470,2172],{"class":339},[268,5472,5473,5475,5478,5480,5482,5485,5487,5489,5492,5495,5497,5499,5501,5503,5506,5508,5510],{"class":270,"line":650},[268,5474,3710],{"class":335},[268,5476,5477],{"class":339}," pathMatch ",[268,5479,747],{"class":335},[268,5481,3903],{"class":339},[268,5483,5484],{"class":300},"match",[268,5486,696],{"class":339},[268,5488,1682],{"class":311},[268,5490,5491],{"class":1685},"\\\u002F",[268,5493,5494],{"class":1689},"site",[268,5496,5491],{"class":1685},[268,5498,696],{"class":1689},[268,5500,385],{"class":304},[268,5502,976],{"class":335},[268,5504,5505],{"class":1689},")",[268,5507,1704],{"class":335},[268,5509,1682],{"class":311},[268,5511,908],{"class":339},[268,5513,5514,5516],{"class":270,"line":656},[268,5515,2369],{"class":335},[268,5517,5518],{"class":339}," (pathMatch) {\n",[268,5520,5521,5523,5525,5527,5530,5532,5535,5537],{"class":270,"line":662},[268,5522,1672],{"class":335},[268,5524,5303],{"class":339},[268,5526,976],{"class":335},[268,5528,5529],{"class":311}," '\u002F'",[268,5531,3739],{"class":335},[268,5533,5534],{"class":339}," pathMatch[",[268,5536,1532],{"class":304},[268,5538,3487],{"class":339},[268,5540,5541],{"class":270,"line":668},[268,5542,2398],{"class":339},[268,5544,5545],{"class":270,"line":886},[268,5546,874],{"class":339},[268,5548,5549],{"class":270,"line":911},[268,5550,1355],{"class":339},[268,5552,5553,5555],{"class":270,"line":934},[268,5554,959],{"class":335},[268,5556,5404],{"class":339},[268,5558,5559],{"class":270,"line":951},[268,5560,1161],{"class":339},[268,5562,5563],{"class":270,"line":956},[268,5564,774],{"class":339},[268,5566,5567],{"class":270,"line":964},[268,5568,1172],{"class":339},[26,5570],{},[29,5572,73],{"id":5573},"optimizing-product-images-at-upload",[15,5575,5576],{},"The best optimization happens before images enter your system.",[110,5578,5580],{"id":5579},"image-upload-guidelines","Image Upload Guidelines",[15,5582,5583],{},"Provide your team with clear specifications:",[115,5585,5586,5602],{},[118,5587,5588],{},[121,5589,5590,5593,5596,5599],{},[124,5591,5592],{},"Image Type",[124,5594,5595],{},"Max Dimensions",[124,5597,5598],{},"Max File Size",[124,5600,5601],{},"Format",[137,5603,5604,5618,5629,5642,5655],{},[121,5605,5606,5609,5612,5615],{},[142,5607,5608],{},"Product main",[142,5610,5611],{},"2000 x 2000px",[142,5613,5614],{},"500KB",[142,5616,5617],{},"JPEG (q85)",[121,5619,5620,5623,5625,5627],{},[142,5621,5622],{},"Product alt views",[142,5624,5611],{},[142,5626,5614],{},[142,5628,5617],{},[121,5630,5631,5634,5637,5640],{},[142,5632,5633],{},"Lifestyle\u002Fhero",[142,5635,5636],{},"2400 x 1200px",[142,5638,5639],{},"800KB",[142,5641,5617],{},[121,5643,5644,5646,5649,5652],{},[142,5645,419],{},[142,5647,5648],{},"400 x 400px",[142,5650,5651],{},"50KB",[142,5653,5654],{},"JPEG (q80)",[121,5656,5657,5660,5663,5666],{},[142,5658,5659],{},"Icons\u002Flogos",[142,5661,5662],{},"200 x 200px",[142,5664,5665],{},"20KB",[142,5667,5668],{},"PNG-8 or SVG",[110,5670,5672],{"id":5671},"automated-upload-processing","Automated Upload Processing",[15,5674,5675],{},"Create a SuiteScript that processes images on upload:",[258,5677,5679],{"className":679,"code":5678,"language":681,"meta":263,"style":263},"\u002F\u002F ImageUploadProcessor.js\n\u002F**\n * @NApiVersion 2.1\n * @NScriptType UserEventScript\n *\u002F\ndefine(['N\u002Ffile', 'N\u002Flog'], function(file, log) {\n    \n    function afterSubmit(context) {\n        if (context.type !== context.UserEventType.CREATE) {\n            return;\n        }\n        \n        var newRecord = context.newRecord;\n        var itemId = newRecord.id;\n        \n        \u002F\u002F Get the uploaded image\n        var imageId = newRecord.getValue({ fieldId: 'custitem_main_image' });\n        \n        if (!imageId) {\n            return;\n        }\n        \n        try {\n            var imageFile = file.load({ id: imageId });\n            var dimensions = getImageDimensions(imageFile);\n            \n            \u002F\u002F Check if optimization needed\n            if (dimensions.width > 2000 || dimensions.height > 2000) {\n                log.warning({\n                    title: 'Oversized Image',\n                    details: 'Item ' + itemId + ' has oversized image: ' + \n                             dimensions.width + 'x' + dimensions.height\n                });\n                \n                \u002F\u002F Option: Auto-resize or notify admin\n                notifyAdminOversizedImage(itemId, dimensions);\n            }\n            \n            \u002F\u002F Check file size\n            var sizeKB = imageFile.size \u002F 1024;\n            if (sizeKB > 500) {\n                log.warning({\n                    title: 'Large Image File',\n                    details: 'Item ' + itemId + ' image is ' + \n                             Math.round(sizeKB) + 'KB (limit: 500KB)'\n                });\n            }\n            \n        } catch (e) {\n            log.error({\n                title: 'Image Processing Error',\n                details: e.message\n            });\n        }\n    }\n    \n    function getImageDimensions(imageFile) {\n        \u002F\u002F Implementation depends on image library availability\n        \u002F\u002F NetSuite native doesn't include image dimension reading\n        \u002F\u002F You may need to parse JPEG\u002FPNG headers manually or use external service\n        return { width: 0, height: 0 };\n    }\n    \n    function notifyAdminOversizedImage(itemId, dimensions) {\n        \u002F\u002F Send email or create task for admin\n    }\n    \n    return {\n        afterSubmit: afterSubmit\n    };\n});\n",[265,5680,5681,5686,5691,5702,5712,5717,5746,5750,5764,5781,5787,5791,5795,5808,5820,5824,5829,5852,5856,5867,5873,5877,5881,5888,5906,5921,5925,5930,5954,5964,5974,5995,6010,6015,6019,6024,6032,6036,6040,6045,6064,6078,6086,6095,6114,6130,6134,6138,6142,6152,6162,6172,6177,6181,6185,6189,6193,6206,6211,6216,6221,6239,6243,6247,6266,6271,6275,6279,6285,6290,6294],{"__ignoreMap":263},[268,5682,5683],{"class":270,"line":271},[268,5684,5685],{"class":274},"\u002F\u002F ImageUploadProcessor.js\n",[268,5687,5688],{"class":270,"line":278},[268,5689,5690],{"class":274},"\u002F**\n",[268,5692,5693,5696,5699],{"class":270,"line":284},[268,5694,5695],{"class":274}," * ",[268,5697,5698],{"class":335},"@NApiVersion",[268,5700,5701],{"class":274}," 2.1\n",[268,5703,5704,5706,5709],{"class":270,"line":291},[268,5705,5695],{"class":274},[268,5707,5708],{"class":335},"@NScriptType",[268,5710,5711],{"class":274}," UserEventScript\n",[268,5713,5714],{"class":270,"line":297},[268,5715,5716],{"class":274}," *\u002F\n",[268,5718,5719,5721,5724,5727,5729,5732,5734,5736,5738,5740,5742,5744],{"class":270,"line":321},[268,5720,693],{"class":300},[268,5722,5723],{"class":339},"([",[268,5725,5726],{"class":311},"'N\u002Ffile'",[268,5728,1434],{"class":339},[268,5730,5731],{"class":311},"'N\u002Flog'",[268,5733,712],{"class":339},[268,5735,715],{"class":335},[268,5737,696],{"class":339},[268,5739,379],{"class":720},[268,5741,1434],{"class":339},[268,5743,4835],{"class":720},[268,5745,724],{"class":339},[268,5747,5748],{"class":270,"line":326},[268,5749,2936],{"class":339},[268,5751,5752,5755,5758,5760,5762],{"class":270,"line":332},[268,5753,5754],{"class":335},"    function",[268,5756,5757],{"class":300}," afterSubmit",[268,5759,696],{"class":339},[268,5761,3808],{"class":720},[268,5763,724],{"class":339},[268,5765,5766,5768,5771,5773,5776,5779],{"class":270,"line":355},[268,5767,4914],{"class":335},[268,5769,5770],{"class":339}," (context.type ",[268,5772,1526],{"class":335},[268,5774,5775],{"class":339}," context.UserEventType.",[268,5777,5778],{"class":304},"CREATE",[268,5780,724],{"class":339},[268,5782,5783,5785],{"class":270,"line":394},[268,5784,959],{"class":335},[268,5786,732],{"class":339},[268,5788,5789],{"class":270,"line":598},[268,5790,1161],{"class":339},[268,5792,5793],{"class":270,"line":604},[268,5794,1246],{"class":339},[268,5796,5797,5800,5803,5805],{"class":270,"line":610},[268,5798,5799],{"class":335},"        var",[268,5801,5802],{"class":339}," newRecord ",[268,5804,747],{"class":335},[268,5806,5807],{"class":339}," context.newRecord;\n",[268,5809,5810,5812,5815,5817],{"class":270,"line":615},[268,5811,5799],{"class":335},[268,5813,5814],{"class":339}," itemId ",[268,5816,747],{"class":335},[268,5818,5819],{"class":339}," newRecord.id;\n",[268,5821,5822],{"class":270,"line":620},[268,5823,1246],{"class":339},[268,5825,5826],{"class":270,"line":626},[268,5827,5828],{"class":274},"        \u002F\u002F Get the uploaded image\n",[268,5830,5831,5833,5835,5837,5840,5843,5846,5849],{"class":270,"line":632},[268,5832,5799],{"class":335},[268,5834,1278],{"class":339},[268,5836,747],{"class":335},[268,5838,5839],{"class":339}," newRecord.",[268,5841,5842],{"class":300},"getValue",[268,5844,5845],{"class":339},"({ fieldId: ",[268,5847,5848],{"class":311},"'custitem_main_image'",[268,5850,5851],{"class":339}," });\n",[268,5853,5854],{"class":270,"line":638},[268,5855,1246],{"class":339},[268,5857,5858,5860,5862,5864],{"class":270,"line":644},[268,5859,4914],{"class":335},[268,5861,855],{"class":339},[268,5863,858],{"class":335},[268,5865,5866],{"class":339},"imageId) {\n",[268,5868,5869,5871],{"class":270,"line":650},[268,5870,959],{"class":335},[268,5872,732],{"class":339},[268,5874,5875],{"class":270,"line":656},[268,5876,1161],{"class":339},[268,5878,5879],{"class":270,"line":662},[268,5880,1246],{"class":339},[268,5882,5883,5886],{"class":270,"line":668},[268,5884,5885],{"class":335},"        try",[268,5887,750],{"class":339},[268,5889,5890,5892,5895,5897,5900,5903],{"class":270,"line":886},[268,5891,889],{"class":335},[268,5893,5894],{"class":339}," imageFile ",[268,5896,747],{"class":335},[268,5898,5899],{"class":339}," file.",[268,5901,5902],{"class":300},"load",[268,5904,5905],{"class":339},"({ id: imageId });\n",[268,5907,5908,5910,5913,5915,5918],{"class":270,"line":911},[268,5909,889],{"class":335},[268,5911,5912],{"class":339}," dimensions ",[268,5914,747],{"class":335},[268,5916,5917],{"class":300}," getImageDimensions",[268,5919,5920],{"class":339},"(imageFile);\n",[268,5922,5923],{"class":270,"line":934},[268,5924,1355],{"class":339},[268,5926,5927],{"class":270,"line":951},[268,5928,5929],{"class":274},"            \u002F\u002F Check if optimization needed\n",[268,5931,5932,5934,5937,5940,5943,5945,5948,5950,5952],{"class":270,"line":956},[268,5933,852],{"class":335},[268,5935,5936],{"class":339}," (dimensions.width ",[268,5938,5939],{"class":335},">",[268,5941,5942],{"class":304}," 2000",[268,5944,5442],{"class":335},[268,5946,5947],{"class":339}," dimensions.height ",[268,5949,5939],{"class":335},[268,5951,5942],{"class":304},[268,5953,724],{"class":339},[268,5955,5956,5959,5962],{"class":270,"line":964},[268,5957,5958],{"class":339},"                log.",[268,5960,5961],{"class":300},"warning",[268,5963,1241],{"class":339},[268,5965,5966,5969,5972],{"class":270,"line":970},[268,5967,5968],{"class":339},"                    title: ",[268,5970,5971],{"class":311},"'Oversized Image'",[268,5973,761],{"class":339},[268,5975,5976,5979,5982,5984,5986,5988,5991,5993],{"class":270,"line":982},[268,5977,5978],{"class":339},"                    details: ",[268,5980,5981],{"class":311},"'Item '",[268,5983,3739],{"class":335},[268,5985,5814],{"class":339},[268,5987,976],{"class":335},[268,5989,5990],{"class":311}," ' has oversized image: '",[268,5992,3739],{"class":335},[268,5994,3271],{"class":339},[268,5996,5997,6000,6002,6005,6007],{"class":270,"line":993},[268,5998,5999],{"class":339},"                             dimensions.width ",[268,6001,976],{"class":335},[268,6003,6004],{"class":311}," 'x'",[268,6006,3739],{"class":335},[268,6008,6009],{"class":339}," dimensions.height\n",[268,6011,6012],{"class":270,"line":1015},[268,6013,6014],{"class":339},"                });\n",[268,6016,6017],{"class":270,"line":1035},[268,6018,2172],{"class":339},[268,6020,6021],{"class":270,"line":1041},[268,6022,6023],{"class":274},"                \u002F\u002F Option: Auto-resize or notify admin\n",[268,6025,6026,6029],{"class":270,"line":1047},[268,6027,6028],{"class":300},"                notifyAdminOversizedImage",[268,6030,6031],{"class":339},"(itemId, dimensions);\n",[268,6033,6034],{"class":270,"line":1052},[268,6035,874],{"class":339},[268,6037,6038],{"class":270,"line":1057},[268,6039,1355],{"class":339},[268,6041,6042],{"class":270,"line":1063},[268,6043,6044],{"class":274},"            \u002F\u002F Check file size\n",[268,6046,6047,6049,6052,6054,6057,6059,6062],{"class":270,"line":1069},[268,6048,889],{"class":335},[268,6050,6051],{"class":339}," sizeKB ",[268,6053,747],{"class":335},[268,6055,6056],{"class":339}," imageFile.size ",[268,6058,1682],{"class":335},[268,6060,6061],{"class":304}," 1024",[268,6063,732],{"class":339},[268,6065,6066,6068,6071,6073,6076],{"class":270,"line":1074},[268,6067,852],{"class":335},[268,6069,6070],{"class":339}," (sizeKB ",[268,6072,5939],{"class":335},[268,6074,6075],{"class":304}," 500",[268,6077,724],{"class":339},[268,6079,6080,6082,6084],{"class":270,"line":1091},[268,6081,5958],{"class":339},[268,6083,5961],{"class":300},[268,6085,1241],{"class":339},[268,6087,6088,6090,6093],{"class":270,"line":1097},[268,6089,5968],{"class":339},[268,6091,6092],{"class":311},"'Large Image File'",[268,6094,761],{"class":339},[268,6096,6097,6099,6101,6103,6105,6107,6110,6112],{"class":270,"line":1103},[268,6098,5978],{"class":339},[268,6100,5981],{"class":311},[268,6102,3739],{"class":335},[268,6104,5814],{"class":339},[268,6106,976],{"class":335},[268,6108,6109],{"class":311}," ' image is '",[268,6111,3739],{"class":335},[268,6113,3271],{"class":339},[268,6115,6116,6119,6122,6125,6127],{"class":270,"line":1113},[268,6117,6118],{"class":339},"                             Math.",[268,6120,6121],{"class":300},"round",[268,6123,6124],{"class":339},"(sizeKB) ",[268,6126,976],{"class":335},[268,6128,6129],{"class":311}," 'KB (limit: 500KB)'\n",[268,6131,6132],{"class":270,"line":1118},[268,6133,6014],{"class":339},[268,6135,6136],{"class":270,"line":1123},[268,6137,874],{"class":339},[268,6139,6140],{"class":270,"line":1139},[268,6141,1355],{"class":339},[268,6143,6144,6147,6149],{"class":270,"line":1145},[268,6145,6146],{"class":339},"        } ",[268,6148,4986],{"class":335},[268,6150,6151],{"class":339}," (e) {\n",[268,6153,6154,6157,6160],{"class":270,"line":1158},[268,6155,6156],{"class":339},"            log.",[268,6158,6159],{"class":300},"error",[268,6161,1241],{"class":339},[268,6163,6164,6167,6170],{"class":270,"line":1164},[268,6165,6166],{"class":339},"                title: ",[268,6168,6169],{"class":311},"'Image Processing Error'",[268,6171,761],{"class":339},[268,6173,6174],{"class":270,"line":1169},[268,6175,6176],{"class":339},"                details: e.message\n",[268,6178,6179],{"class":270,"line":1781},[268,6180,2306],{"class":339},[268,6182,6183],{"class":270,"line":1786},[268,6184,1161],{"class":339},[268,6186,6187],{"class":270,"line":1792},[268,6188,2963],{"class":339},[268,6190,6191],{"class":270,"line":2405},[268,6192,2936],{"class":339},[268,6194,6195,6197,6199,6201,6204],{"class":270,"line":2410},[268,6196,5754],{"class":335},[268,6198,5917],{"class":300},[268,6200,696],{"class":339},[268,6202,6203],{"class":720},"imageFile",[268,6205,724],{"class":339},[268,6207,6208],{"class":270,"line":2415},[268,6209,6210],{"class":274},"        \u002F\u002F Implementation depends on image library availability\n",[268,6212,6213],{"class":270,"line":2431},[268,6214,6215],{"class":274},"        \u002F\u002F NetSuite native doesn't include image dimension reading\n",[268,6217,6218],{"class":270,"line":2454},[268,6219,6220],{"class":274},"        \u002F\u002F You may need to parse JPEG\u002FPNG headers manually or use external service\n",[268,6222,6223,6226,6229,6231,6234,6236],{"class":270,"line":2475},[268,6224,6225],{"class":335},"        return",[268,6227,6228],{"class":339}," { width: ",[268,6230,928],{"class":304},[268,6232,6233],{"class":339},", height: ",[268,6235,928],{"class":304},[268,6237,6238],{"class":339}," };\n",[268,6240,6241],{"class":270,"line":2480},[268,6242,2963],{"class":339},[268,6244,6245],{"class":270,"line":2488},[268,6246,2936],{"class":339},[268,6248,6249,6251,6254,6256,6259,6261,6264],{"class":270,"line":2499},[268,6250,5754],{"class":335},[268,6252,6253],{"class":300}," notifyAdminOversizedImage",[268,6255,696],{"class":339},[268,6257,6258],{"class":720},"itemId",[268,6260,1434],{"class":339},[268,6262,6263],{"class":720},"dimensions",[268,6265,724],{"class":339},[268,6267,6268],{"class":270,"line":2514},[268,6269,6270],{"class":274},"        \u002F\u002F Send email or create task for admin\n",[268,6272,6273],{"class":270,"line":2519},[268,6274,2963],{"class":339},[268,6276,6277],{"class":270,"line":2524},[268,6278,2936],{"class":339},[268,6280,6281,6283],{"class":270,"line":2532},[268,6282,783],{"class":335},[268,6284,750],{"class":339},[268,6286,6287],{"class":270,"line":2543},[268,6288,6289],{"class":339},"        afterSubmit: afterSubmit\n",[268,6291,6292],{"class":270,"line":2556},[268,6293,774],{"class":339},[268,6295,6296],{"class":270,"line":2561},[268,6297,1172],{"class":339},[110,6299,6301],{"id":6300},"bulk-image-optimization-script","Bulk Image Optimization Script",[15,6303,6304],{},"For existing catalogs, create a scheduled script to optimize images:",[258,6306,6308],{"className":679,"code":6307,"language":681,"meta":263,"style":263},"\u002F\u002F BulkImageOptimizer.js\n\u002F**\n * @NApiVersion 2.1\n * @NScriptType ScheduledScript\n *\u002F\ndefine(['N\u002Fsearch', 'N\u002Frecord', 'N\u002Ffile', 'N\u002Flog', 'N\u002Fruntime'], \nfunction(search, record, file, log, runtime) {\n    \n    function execute(context) {\n        var itemSearch = search.create({\n            type: search.Type.INVENTORY_ITEM,\n            filters: [\n                ['isinactive', 'is', 'F'],\n                'AND',\n                ['custitem_images_optimized', 'is', 'F']\n            ],\n            columns: ['internalid', 'itemid', 'storedisplayimage']\n        });\n        \n        var results = itemSearch.run().getRange({ start: 0, end: 100 });\n        \n        results.forEach(function(result) {\n            var remainingUsage = runtime.getCurrentScript().getRemainingUsage();\n            \n            if (remainingUsage \u003C 100) {\n                log.audit({\n                    title: 'Governance Limit',\n                    details: 'Stopping to avoid governance limit'\n                });\n                return false;\n            }\n            \n            try {\n                processItemImages(result.id);\n                \n                \u002F\u002F Mark as processed\n                record.submitFields({\n                    type: record.Type.INVENTORY_ITEM,\n                    id: result.id,\n                    values: {\n                        custitem_images_optimized: true\n                    }\n                });\n                \n            } catch (e) {\n                log.error({\n                    title: 'Item Processing Error',\n                    details: 'Item ' + result.id + ': ' + e.message\n                });\n            }\n        });\n    }\n    \n    function processItemImages(itemId) {\n        \u002F\u002F Implementation: resize, compress, convert to WebP\n        \u002F\u002F This often requires external image processing service\n        log.audit({\n            title: 'Processing Item',\n            details: 'Item ID: ' + itemId\n        });\n    }\n    \n    return {\n        execute: execute\n    };\n});\n",[265,6309,6310,6315,6319,6327,6336,6340,6370,6399,6403,6416,6433,6443,6448,6469,6476,6494,6499,6519,6524,6528,6561,6565,6583,6605,6609,6622,6631,6640,6647,6651,6659,6663,6667,6674,6682,6686,6691,6701,6710,6715,6720,6727,6731,6735,6739,6747,6755,6764,6785,6789,6793,6797,6801,6805,6818,6823,6828,6837,6847,6860,6864,6868,6872,6878,6883,6887],{"__ignoreMap":263},[268,6311,6312],{"class":270,"line":271},[268,6313,6314],{"class":274},"\u002F\u002F BulkImageOptimizer.js\n",[268,6316,6317],{"class":270,"line":278},[268,6318,5690],{"class":274},[268,6320,6321,6323,6325],{"class":270,"line":284},[268,6322,5695],{"class":274},[268,6324,5698],{"class":335},[268,6326,5701],{"class":274},[268,6328,6329,6331,6333],{"class":270,"line":291},[268,6330,5695],{"class":274},[268,6332,5708],{"class":335},[268,6334,6335],{"class":274}," ScheduledScript\n",[268,6337,6338],{"class":270,"line":297},[268,6339,5716],{"class":274},[268,6341,6342,6344,6346,6349,6351,6354,6356,6358,6360,6362,6364,6367],{"class":270,"line":321},[268,6343,693],{"class":300},[268,6345,5723],{"class":339},[268,6347,6348],{"class":311},"'N\u002Fsearch'",[268,6350,1434],{"class":339},[268,6352,6353],{"class":311},"'N\u002Frecord'",[268,6355,1434],{"class":339},[268,6357,5726],{"class":311},[268,6359,1434],{"class":339},[268,6361,5731],{"class":311},[268,6363,1434],{"class":339},[268,6365,6366],{"class":311},"'N\u002Fruntime'",[268,6368,6369],{"class":339},"], \n",[268,6371,6372,6374,6376,6379,6381,6384,6386,6388,6390,6392,6394,6397],{"class":270,"line":326},[268,6373,715],{"class":335},[268,6375,696],{"class":339},[268,6377,6378],{"class":720},"search",[268,6380,1434],{"class":339},[268,6382,6383],{"class":720},"record",[268,6385,1434],{"class":339},[268,6387,379],{"class":720},[268,6389,1434],{"class":339},[268,6391,4835],{"class":720},[268,6393,1434],{"class":339},[268,6395,6396],{"class":720},"runtime",[268,6398,724],{"class":339},[268,6400,6401],{"class":270,"line":332},[268,6402,2936],{"class":339},[268,6404,6405,6407,6410,6412,6414],{"class":270,"line":355},[268,6406,5754],{"class":335},[268,6408,6409],{"class":300}," execute",[268,6411,696],{"class":339},[268,6413,3808],{"class":720},[268,6415,724],{"class":339},[268,6417,6418,6420,6423,6425,6428,6431],{"class":270,"line":394},[268,6419,5799],{"class":335},[268,6421,6422],{"class":339}," itemSearch ",[268,6424,747],{"class":335},[268,6426,6427],{"class":339}," search.",[268,6429,6430],{"class":300},"create",[268,6432,1241],{"class":339},[268,6434,6435,6438,6441],{"class":270,"line":598},[268,6436,6437],{"class":339},"            type: search.Type.",[268,6439,6440],{"class":304},"INVENTORY_ITEM",[268,6442,761],{"class":339},[268,6444,6445],{"class":270,"line":604},[268,6446,6447],{"class":339},"            filters: [\n",[268,6449,6450,6453,6456,6458,6461,6463,6466],{"class":270,"line":610},[268,6451,6452],{"class":339},"                [",[268,6454,6455],{"class":311},"'isinactive'",[268,6457,1434],{"class":339},[268,6459,6460],{"class":311},"'is'",[268,6462,1434],{"class":339},[268,6464,6465],{"class":311},"'F'",[268,6467,6468],{"class":339},"],\n",[268,6470,6471,6474],{"class":270,"line":615},[268,6472,6473],{"class":311},"                'AND'",[268,6475,761],{"class":339},[268,6477,6478,6480,6483,6485,6487,6489,6491],{"class":270,"line":620},[268,6479,6452],{"class":339},[268,6481,6482],{"class":311},"'custitem_images_optimized'",[268,6484,1434],{"class":339},[268,6486,6460],{"class":311},[268,6488,1434],{"class":339},[268,6490,6465],{"class":311},[268,6492,6493],{"class":339},"]\n",[268,6495,6496],{"class":270,"line":626},[268,6497,6498],{"class":339},"            ],\n",[268,6500,6501,6504,6507,6509,6512,6514,6517],{"class":270,"line":632},[268,6502,6503],{"class":339},"            columns: [",[268,6505,6506],{"class":311},"'internalid'",[268,6508,1434],{"class":339},[268,6510,6511],{"class":311},"'itemid'",[268,6513,1434],{"class":339},[268,6515,6516],{"class":311},"'storedisplayimage'",[268,6518,6493],{"class":339},[268,6520,6521],{"class":270,"line":638},[268,6522,6523],{"class":339},"        });\n",[268,6525,6526],{"class":270,"line":644},[268,6527,1246],{"class":339},[268,6529,6530,6532,6535,6537,6540,6543,6545,6548,6551,6553,6556,6559],{"class":270,"line":650},[268,6531,5799],{"class":335},[268,6533,6534],{"class":339}," results ",[268,6536,747],{"class":335},[268,6538,6539],{"class":339}," itemSearch.",[268,6541,6542],{"class":300},"run",[268,6544,4983],{"class":339},[268,6546,6547],{"class":300},"getRange",[268,6549,6550],{"class":339},"({ start: ",[268,6552,928],{"class":304},[268,6554,6555],{"class":339},", end: ",[268,6557,6558],{"class":304},"100",[268,6560,5851],{"class":339},[268,6562,6563],{"class":270,"line":656},[268,6564,1246],{"class":339},[268,6566,6567,6570,6572,6574,6576,6578,6581],{"class":270,"line":662},[268,6568,6569],{"class":339},"        results.",[268,6571,2279],{"class":300},[268,6573,696],{"class":339},[268,6575,715],{"class":335},[268,6577,696],{"class":339},[268,6579,6580],{"class":720},"result",[268,6582,724],{"class":339},[268,6584,6585,6587,6590,6592,6595,6598,6600,6603],{"class":270,"line":668},[268,6586,889],{"class":335},[268,6588,6589],{"class":339}," remainingUsage ",[268,6591,747],{"class":335},[268,6593,6594],{"class":339}," runtime.",[268,6596,6597],{"class":300},"getCurrentScript",[268,6599,4983],{"class":339},[268,6601,6602],{"class":300},"getRemainingUsage",[268,6604,2038],{"class":339},[268,6606,6607],{"class":270,"line":886},[268,6608,1355],{"class":339},[268,6610,6611,6613,6616,6618,6620],{"class":270,"line":911},[268,6612,852],{"class":335},[268,6614,6615],{"class":339}," (remainingUsage ",[268,6617,3266],{"class":335},[268,6619,3063],{"class":304},[268,6621,724],{"class":339},[268,6623,6624,6626,6629],{"class":270,"line":934},[268,6625,5958],{"class":339},[268,6627,6628],{"class":300},"audit",[268,6630,1241],{"class":339},[268,6632,6633,6635,6638],{"class":270,"line":951},[268,6634,5968],{"class":339},[268,6636,6637],{"class":311},"'Governance Limit'",[268,6639,761],{"class":339},[268,6641,6642,6644],{"class":270,"line":956},[268,6643,5978],{"class":339},[268,6645,6646],{"class":311},"'Stopping to avoid governance limit'\n",[268,6648,6649],{"class":270,"line":964},[268,6650,6014],{"class":339},[268,6652,6653,6655,6657],{"class":270,"line":970},[268,6654,866],{"class":335},[268,6656,1150],{"class":304},[268,6658,732],{"class":339},[268,6660,6661],{"class":270,"line":982},[268,6662,874],{"class":339},[268,6664,6665],{"class":270,"line":993},[268,6666,1355],{"class":339},[268,6668,6669,6672],{"class":270,"line":1015},[268,6670,6671],{"class":335},"            try",[268,6673,750],{"class":339},[268,6675,6676,6679],{"class":270,"line":1035},[268,6677,6678],{"class":300},"                processItemImages",[268,6680,6681],{"class":339},"(result.id);\n",[268,6683,6684],{"class":270,"line":1041},[268,6685,2172],{"class":339},[268,6687,6688],{"class":270,"line":1047},[268,6689,6690],{"class":274},"                \u002F\u002F Mark as processed\n",[268,6692,6693,6696,6699],{"class":270,"line":1052},[268,6694,6695],{"class":339},"                record.",[268,6697,6698],{"class":300},"submitFields",[268,6700,1241],{"class":339},[268,6702,6703,6706,6708],{"class":270,"line":1057},[268,6704,6705],{"class":339},"                    type: record.Type.",[268,6707,6440],{"class":304},[268,6709,761],{"class":339},[268,6711,6712],{"class":270,"line":1063},[268,6713,6714],{"class":339},"                    id: result.id,\n",[268,6716,6717],{"class":270,"line":1069},[268,6718,6719],{"class":339},"                    values: {\n",[268,6721,6722,6725],{"class":270,"line":1074},[268,6723,6724],{"class":339},"                        custitem_images_optimized: ",[268,6726,4792],{"class":304},[268,6728,6729],{"class":270,"line":1091},[268,6730,2162],{"class":339},[268,6732,6733],{"class":270,"line":1097},[268,6734,6014],{"class":339},[268,6736,6737],{"class":270,"line":1103},[268,6738,2172],{"class":339},[268,6740,6741,6743,6745],{"class":270,"line":1113},[268,6742,2188],{"class":339},[268,6744,4986],{"class":335},[268,6746,6151],{"class":339},[268,6748,6749,6751,6753],{"class":270,"line":1118},[268,6750,5958],{"class":339},[268,6752,6159],{"class":300},[268,6754,1241],{"class":339},[268,6756,6757,6759,6762],{"class":270,"line":1123},[268,6758,5968],{"class":339},[268,6760,6761],{"class":311},"'Item Processing Error'",[268,6763,761],{"class":339},[268,6765,6766,6768,6770,6772,6775,6777,6780,6782],{"class":270,"line":1139},[268,6767,5978],{"class":339},[268,6769,5981],{"class":311},[268,6771,3739],{"class":335},[268,6773,6774],{"class":339}," result.id ",[268,6776,976],{"class":335},[268,6778,6779],{"class":311}," ': '",[268,6781,3739],{"class":335},[268,6783,6784],{"class":339}," e.message\n",[268,6786,6787],{"class":270,"line":1145},[268,6788,6014],{"class":339},[268,6790,6791],{"class":270,"line":1158},[268,6792,874],{"class":339},[268,6794,6795],{"class":270,"line":1164},[268,6796,6523],{"class":339},[268,6798,6799],{"class":270,"line":1169},[268,6800,2963],{"class":339},[268,6802,6803],{"class":270,"line":1781},[268,6804,2936],{"class":339},[268,6806,6807,6809,6812,6814,6816],{"class":270,"line":1786},[268,6808,5754],{"class":335},[268,6810,6811],{"class":300}," processItemImages",[268,6813,696],{"class":339},[268,6815,6258],{"class":720},[268,6817,724],{"class":339},[268,6819,6820],{"class":270,"line":1792},[268,6821,6822],{"class":274},"        \u002F\u002F Implementation: resize, compress, convert to WebP\n",[268,6824,6825],{"class":270,"line":2405},[268,6826,6827],{"class":274},"        \u002F\u002F This often requires external image processing service\n",[268,6829,6830,6833,6835],{"class":270,"line":2410},[268,6831,6832],{"class":339},"        log.",[268,6834,6628],{"class":300},[268,6836,1241],{"class":339},[268,6838,6839,6842,6845],{"class":270,"line":2415},[268,6840,6841],{"class":339},"            title: ",[268,6843,6844],{"class":311},"'Processing Item'",[268,6846,761],{"class":339},[268,6848,6849,6852,6855,6857],{"class":270,"line":2431},[268,6850,6851],{"class":339},"            details: ",[268,6853,6854],{"class":311},"'Item ID: '",[268,6856,3739],{"class":335},[268,6858,6859],{"class":339}," itemId\n",[268,6861,6862],{"class":270,"line":2454},[268,6863,6523],{"class":339},[268,6865,6866],{"class":270,"line":2475},[268,6867,2963],{"class":339},[268,6869,6870],{"class":270,"line":2480},[268,6871,2936],{"class":339},[268,6873,6874,6876],{"class":270,"line":2488},[268,6875,783],{"class":335},[268,6877,750],{"class":339},[268,6879,6880],{"class":270,"line":2499},[268,6881,6882],{"class":339},"        execute: execute\n",[268,6884,6885],{"class":270,"line":2514},[268,6886,774],{"class":339},[268,6888,6889],{"class":270,"line":2519},[268,6890,1172],{"class":339},[26,6892],{},[29,6894,79],{"id":6895},"building-an-image-optimization-extension",[15,6897,6898],{},"Combine all techniques into a reusable extension.",[110,6900,6902],{"id":6901},"extension-structure","Extension Structure",[258,6904,6907],{"className":6905,"code":6906,"language":5051},[5049],"ImageOptimization\u002F\n├── Modules\u002F\n│   └── ImageOptimization\u002F\n│       ├── JavaScript\u002F\n│       │   ├── ImageOptimization.js\n│       │   ├── ImageOptimization.LazyLoader.js\n│       │   ├── ImageOptimization.ResponsiveHelper.js\n│       │   └── ImageOptimization.FormatHelper.js\n│       ├── Templates\u002F\n│       │   └── optimized_image.tpl\n│       ├── Sass\u002F\n│       │   └── _image-optimization.scss\n│       └── Configuration\u002F\n│           └── ImageOptimization.json\n├── ns.package.json\n└── manifest.json\n",[265,6908,6906],{"__ignoreMap":263},[110,6910,6912],{"id":6911},"main-module-entry-point","Main Module Entry Point",[258,6914,6916],{"className":679,"code":6915,"language":681,"meta":263,"style":263},"\u002F\u002F ImageOptimization.js\ndefine('ImageOptimization', [\n    'ImageOptimization.LazyLoader',\n    'ImageOptimization.ResponsiveHelper',\n    'ImageOptimization.FormatHelper',\n    'SC.Configuration'\n], function(\n    LazyLoader,\n    ResponsiveHelper,\n    FormatHelper,\n    Configuration\n) {\n    'use strict';\n\n    var config = Configuration.get('imageOptimization', {});\n\n    return {\n        \n        LazyLoader: LazyLoader,\n        ResponsiveHelper: ResponsiveHelper,\n        FormatHelper: FormatHelper,\n        \n        mountToApp: function(application) {\n            var self = this;\n            \n            \u002F\u002F Initialize lazy loading if enabled\n            if (config.lazyLoadingEnabled !== false) {\n                this.lazyLoader = new LazyLoader({\n                    rootMargin: config.lazyLoadingMargin || '100px 0px',\n                    selector: config.lazyLoadingSelector || '[data-lazy-src]'\n                });\n            }\n            \n            \u002F\u002F Extend image rendering in templates\n            Handlebars.registerHelper('optimizedImage', function(options) {\n                return self.renderOptimizedImage(options.hash);\n            });\n            \n            \u002F\u002F Listen for view renders to refresh lazy loading\n            application.getLayout().on('afterAppendView', function() {\n                if (self.lazyLoader) {\n                    self.lazyLoader.refresh();\n                }\n            });\n        },\n        \n        renderOptimizedImage: function(options) {\n            var url = options.url;\n            var context = options.context || 'product-listing';\n            var alt = options.alt || '';\n            var cssClass = options.class || '';\n            var lazy = options.lazy !== false;\n            \n            var formatUrls = this.FormatHelper.getFormatUrls(url);\n            var responsiveAttrs = this.ResponsiveHelper.getImageAttributes(url, context, {\n                width: options.width,\n                height: options.height\n            });\n            \n            var html = '\u003Cpicture class=\"optimized-image ' + cssClass + '\">';\n            \n            \u002F\u002F AVIF source (if available)\n            if (formatUrls.hasAvif) {\n                html += '\u003Csource srcset=\"' + formatUrls.avif + '\" type=\"image\u002Favif\" \u002F>';\n            }\n            \n            \u002F\u002F WebP source\n            if (formatUrls.hasWebp) {\n                html += '\u003Csource srcset=\"' + formatUrls.webp + '\" type=\"image\u002Fwebp\" \u002F>';\n            }\n            \n            \u002F\u002F Fallback img\n            html += '\u003Cimg ';\n            \n            if (lazy) {\n                html += 'src=\"data:image\u002Fsvg+xml,%3Csvg xmlns=\\'http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\\' viewBox=\\'0 0 ' + \n                        (options.width || 400) + ' ' + (options.height || 400) + '\\'%3E%3C\u002Fsvg%3E\" ';\n                html += 'data-lazy-src=\"' + responsiveAttrs.src + '\" ';\n                html += 'data-lazy-srcset=\"' + responsiveAttrs.srcset + '\" ';\n            } else {\n                html += 'src=\"' + responsiveAttrs.src + '\" ';\n                html += 'srcset=\"' + responsiveAttrs.srcset + '\" ';\n            }\n            \n            html += 'sizes=\"' + responsiveAttrs.sizes + '\" ';\n            html += 'alt=\"' + alt + '\" ';\n            html += 'width=\"' + (options.width || '') + '\" ';\n            html += 'height=\"' + (options.height || '') + '\" ';\n            html += 'class=\"optimized-image-img' + (lazy ? ' lazy-image' : '') + '\" ';\n            html += '\u002F>\u003C\u002Fpicture>';\n            \n            return new Handlebars.SafeString(html);\n        }\n    };\n});\n",[265,6917,6918,6923,6934,6941,6948,6955,6959,6967,6974,6981,6988,6993,6997,7003,7007,7028,7032,7038,7042,7047,7052,7057,7061,7077,7089,7093,7098,7111,7127,7139,7149,7153,7157,7161,7166,7189,7202,7206,7210,7215,7239,7246,7256,7260,7264,7268,7272,7287,7299,7318,7336,7354,7372,7376,7396,7415,7420,7425,7429,7433,7456,7460,7465,7472,7495,7499,7503,7508,7515,7535,7539,7543,7548,7560,7564,7571,7600,7639,7660,7680,7688,7707,7726,7730,7734,7754,7773,7799,7824,7857,7868,7872,7887,7891,7895],{"__ignoreMap":263},[268,6919,6920],{"class":270,"line":271},[268,6921,6922],{"class":274},"\u002F\u002F ImageOptimization.js\n",[268,6924,6925,6927,6929,6932],{"class":270,"line":278},[268,6926,693],{"class":300},[268,6928,696],{"class":339},[268,6930,6931],{"class":311},"'ImageOptimization'",[268,6933,702],{"class":339},[268,6935,6936,6939],{"class":270,"line":284},[268,6937,6938],{"class":311},"    'ImageOptimization.LazyLoader'",[268,6940,761],{"class":339},[268,6942,6943,6946],{"class":270,"line":291},[268,6944,6945],{"class":311},"    'ImageOptimization.ResponsiveHelper'",[268,6947,761],{"class":339},[268,6949,6950,6953],{"class":270,"line":297},[268,6951,6952],{"class":311},"    'ImageOptimization.FormatHelper'",[268,6954,761],{"class":339},[268,6956,6957],{"class":270,"line":321},[268,6958,3422],{"class":311},[268,6960,6961,6963,6965],{"class":270,"line":326},[268,6962,712],{"class":339},[268,6964,715],{"class":335},[268,6966,2114],{"class":339},[268,6968,6969,6972],{"class":270,"line":332},[268,6970,6971],{"class":720},"    LazyLoader",[268,6973,761],{"class":339},[268,6975,6976,6979],{"class":270,"line":355},[268,6977,6978],{"class":720},"    ResponsiveHelper",[268,6980,761],{"class":339},[268,6982,6983,6986],{"class":270,"line":394},[268,6984,6985],{"class":720},"    FormatHelper",[268,6987,761],{"class":339},[268,6989,6990],{"class":270,"line":598},[268,6991,6992],{"class":720},"    Configuration\n",[268,6994,6995],{"class":270,"line":604},[268,6996,724],{"class":339},[268,6998,6999,7001],{"class":270,"line":610},[268,7000,729],{"class":311},[268,7002,732],{"class":339},[268,7004,7005],{"class":270,"line":615},[268,7006,288],{"emptyLinePlaceholder":287},[268,7008,7009,7011,7014,7016,7018,7020,7022,7025],{"class":270,"line":620},[268,7010,741],{"class":335},[268,7012,7013],{"class":339}," config ",[268,7015,747],{"class":335},[268,7017,5308],{"class":339},[268,7019,4260],{"class":300},[268,7021,696],{"class":339},[268,7023,7024],{"class":311},"'imageOptimization'",[268,7026,7027],{"class":339},", {});\n",[268,7029,7030],{"class":270,"line":626},[268,7031,288],{"emptyLinePlaceholder":287},[268,7033,7034,7036],{"class":270,"line":632},[268,7035,783],{"class":335},[268,7037,750],{"class":339},[268,7039,7040],{"class":270,"line":638},[268,7041,1246],{"class":339},[268,7043,7044],{"class":270,"line":644},[268,7045,7046],{"class":339},"        LazyLoader: LazyLoader,\n",[268,7048,7049],{"class":270,"line":650},[268,7050,7051],{"class":339},"        ResponsiveHelper: ResponsiveHelper,\n",[268,7053,7054],{"class":270,"line":656},[268,7055,7056],{"class":339},"        FormatHelper: FormatHelper,\n",[268,7058,7059],{"class":270,"line":662},[268,7060,1246],{"class":339},[268,7062,7063,7066,7068,7070,7072,7075],{"class":270,"line":668},[268,7064,7065],{"class":300},"        mountToApp",[268,7067,838],{"class":339},[268,7069,715],{"class":335},[268,7071,696],{"class":339},[268,7073,7074],{"class":720},"application",[268,7076,724],{"class":339},[268,7078,7079,7081,7083,7085,7087],{"class":270,"line":886},[268,7080,889],{"class":335},[268,7082,2239],{"class":339},[268,7084,747],{"class":335},[268,7086,1283],{"class":304},[268,7088,732],{"class":339},[268,7090,7091],{"class":270,"line":911},[268,7092,1355],{"class":339},[268,7094,7095],{"class":270,"line":934},[268,7096,7097],{"class":274},"            \u002F\u002F Initialize lazy loading if enabled\n",[268,7099,7100,7102,7105,7107,7109],{"class":270,"line":951},[268,7101,852],{"class":335},[268,7103,7104],{"class":339}," (config.lazyLoadingEnabled ",[268,7106,1526],{"class":335},[268,7108,1150],{"class":304},[268,7110,724],{"class":339},[268,7112,7113,7115,7118,7120,7122,7125],{"class":270,"line":956},[268,7114,2101],{"class":304},[268,7116,7117],{"class":339},".lazyLoader ",[268,7119,747],{"class":335},[268,7121,2108],{"class":335},[268,7123,7124],{"class":300}," LazyLoader",[268,7126,1241],{"class":339},[268,7128,7129,7132,7134,7137],{"class":270,"line":964},[268,7130,7131],{"class":339},"                    rootMargin: config.lazyLoadingMargin ",[268,7133,1345],{"class":335},[268,7135,7136],{"class":311}," '100px 0px'",[268,7138,761],{"class":339},[268,7140,7141,7144,7146],{"class":270,"line":970},[268,7142,7143],{"class":339},"                    selector: config.lazyLoadingSelector ",[268,7145,1345],{"class":335},[268,7147,7148],{"class":311}," '[data-lazy-src]'\n",[268,7150,7151],{"class":270,"line":982},[268,7152,6014],{"class":339},[268,7154,7155],{"class":270,"line":993},[268,7156,874],{"class":339},[268,7158,7159],{"class":270,"line":1015},[268,7160,1355],{"class":339},[268,7162,7163],{"class":270,"line":1035},[268,7164,7165],{"class":274},"            \u002F\u002F Extend image rendering in templates\n",[268,7167,7168,7171,7174,7176,7179,7181,7183,7185,7187],{"class":270,"line":1041},[268,7169,7170],{"class":339},"            Handlebars.",[268,7172,7173],{"class":300},"registerHelper",[268,7175,696],{"class":339},[268,7177,7178],{"class":311},"'optimizedImage'",[268,7180,1434],{"class":339},[268,7182,715],{"class":335},[268,7184,696],{"class":339},[268,7186,1956],{"class":720},[268,7188,724],{"class":339},[268,7190,7191,7193,7196,7199],{"class":270,"line":1047},[268,7192,866],{"class":335},[268,7194,7195],{"class":339}," self.",[268,7197,7198],{"class":300},"renderOptimizedImage",[268,7200,7201],{"class":339},"(options.hash);\n",[268,7203,7204],{"class":270,"line":1052},[268,7205,2306],{"class":339},[268,7207,7208],{"class":270,"line":1057},[268,7209,1355],{"class":339},[268,7211,7212],{"class":270,"line":1063},[268,7213,7214],{"class":274},"            \u002F\u002F Listen for view renders to refresh lazy loading\n",[268,7216,7217,7220,7223,7225,7228,7230,7233,7235,7237],{"class":270,"line":1069},[268,7218,7219],{"class":339},"            application.",[268,7221,7222],{"class":300},"getLayout",[268,7224,4983],{"class":339},[268,7226,7227],{"class":300},"on",[268,7229,696],{"class":339},[268,7231,7232],{"class":311},"'afterAppendView'",[268,7234,1434],{"class":339},[268,7236,715],{"class":335},[268,7238,1271],{"class":339},[268,7240,7241,7243],{"class":270,"line":1074},[268,7242,2369],{"class":335},[268,7244,7245],{"class":339}," (self.lazyLoader) {\n",[268,7247,7248,7251,7254],{"class":270,"line":1091},[268,7249,7250],{"class":339},"                    self.lazyLoader.",[268,7252,7253],{"class":300},"refresh",[268,7255,2038],{"class":339},[268,7257,7258],{"class":270,"line":1097},[268,7259,2398],{"class":339},[268,7261,7262],{"class":270,"line":1103},[268,7263,2306],{"class":339},[268,7265,7266],{"class":270,"line":1113},[268,7267,1044],{"class":339},[268,7269,7270],{"class":270,"line":1118},[268,7271,1246],{"class":339},[268,7273,7274,7277,7279,7281,7283,7285],{"class":270,"line":1123},[268,7275,7276],{"class":300},"        renderOptimizedImage",[268,7278,838],{"class":339},[268,7280,715],{"class":335},[268,7282,696],{"class":339},[268,7284,1956],{"class":720},[268,7286,724],{"class":339},[268,7288,7289,7291,7294,7296],{"class":270,"line":1139},[268,7290,889],{"class":335},[268,7292,7293],{"class":339}," url ",[268,7295,747],{"class":335},[268,7297,7298],{"class":339}," options.url;\n",[268,7300,7301,7303,7306,7308,7311,7313,7316],{"class":270,"line":1145},[268,7302,889],{"class":335},[268,7304,7305],{"class":339}," context ",[268,7307,747],{"class":335},[268,7309,7310],{"class":339}," options.context ",[268,7312,1345],{"class":335},[268,7314,7315],{"class":311}," 'product-listing'",[268,7317,732],{"class":339},[268,7319,7320,7322,7325,7327,7330,7332,7334],{"class":270,"line":1158},[268,7321,889],{"class":335},[268,7323,7324],{"class":339}," alt ",[268,7326,747],{"class":335},[268,7328,7329],{"class":339}," options.alt ",[268,7331,1345],{"class":335},[268,7333,1348],{"class":311},[268,7335,732],{"class":339},[268,7337,7338,7340,7343,7345,7348,7350,7352],{"class":270,"line":1164},[268,7339,889],{"class":335},[268,7341,7342],{"class":339}," cssClass ",[268,7344,747],{"class":335},[268,7346,7347],{"class":339}," options.class ",[268,7349,1345],{"class":335},[268,7351,1348],{"class":311},[268,7353,732],{"class":339},[268,7355,7356,7358,7361,7363,7366,7368,7370],{"class":270,"line":1169},[268,7357,889],{"class":335},[268,7359,7360],{"class":339}," lazy ",[268,7362,747],{"class":335},[268,7364,7365],{"class":339}," options.lazy ",[268,7367,1526],{"class":335},[268,7369,1150],{"class":304},[268,7371,732],{"class":339},[268,7373,7374],{"class":270,"line":1781},[268,7375,1355],{"class":339},[268,7377,7378,7380,7383,7385,7387,7390,7393],{"class":270,"line":1786},[268,7379,889],{"class":335},[268,7381,7382],{"class":339}," formatUrls ",[268,7384,747],{"class":335},[268,7386,1283],{"class":304},[268,7388,7389],{"class":339},".FormatHelper.",[268,7391,7392],{"class":300},"getFormatUrls",[268,7394,7395],{"class":339},"(url);\n",[268,7397,7398,7400,7403,7405,7407,7410,7412],{"class":270,"line":1792},[268,7399,889],{"class":335},[268,7401,7402],{"class":339}," responsiveAttrs ",[268,7404,747],{"class":335},[268,7406,1283],{"class":304},[268,7408,7409],{"class":339},".ResponsiveHelper.",[268,7411,4282],{"class":300},[268,7413,7414],{"class":339},"(url, context, {\n",[268,7416,7417],{"class":270,"line":2405},[268,7418,7419],{"class":339},"                width: options.width,\n",[268,7421,7422],{"class":270,"line":2410},[268,7423,7424],{"class":339},"                height: options.height\n",[268,7426,7427],{"class":270,"line":2415},[268,7428,2306],{"class":339},[268,7430,7431],{"class":270,"line":2431},[268,7432,1355],{"class":339},[268,7434,7435,7437,7440,7442,7445,7447,7449,7451,7454],{"class":270,"line":2454},[268,7436,889],{"class":335},[268,7438,7439],{"class":339}," html ",[268,7441,747],{"class":335},[268,7443,7444],{"class":311}," '\u003Cpicture class=\"optimized-image '",[268,7446,3739],{"class":335},[268,7448,7342],{"class":339},[268,7450,976],{"class":335},[268,7452,7453],{"class":311}," '\">'",[268,7455,732],{"class":339},[268,7457,7458],{"class":270,"line":2475},[268,7459,1355],{"class":339},[268,7461,7462],{"class":270,"line":2480},[268,7463,7464],{"class":274},"            \u002F\u002F AVIF source (if available)\n",[268,7466,7467,7469],{"class":270,"line":2488},[268,7468,852],{"class":335},[268,7470,7471],{"class":339}," (formatUrls.hasAvif) {\n",[268,7473,7474,7477,7480,7483,7485,7488,7490,7493],{"class":270,"line":2499},[268,7475,7476],{"class":339},"                html ",[268,7478,7479],{"class":335},"+=",[268,7481,7482],{"class":311}," '\u003Csource srcset=\"'",[268,7484,3739],{"class":335},[268,7486,7487],{"class":339}," formatUrls.avif ",[268,7489,976],{"class":335},[268,7491,7492],{"class":311}," '\" type=\"image\u002Favif\" \u002F>'",[268,7494,732],{"class":339},[268,7496,7497],{"class":270,"line":2514},[268,7498,874],{"class":339},[268,7500,7501],{"class":270,"line":2519},[268,7502,1355],{"class":339},[268,7504,7505],{"class":270,"line":2524},[268,7506,7507],{"class":274},"            \u002F\u002F WebP source\n",[268,7509,7510,7512],{"class":270,"line":2532},[268,7511,852],{"class":335},[268,7513,7514],{"class":339}," (formatUrls.hasWebp) {\n",[268,7516,7517,7519,7521,7523,7525,7528,7530,7533],{"class":270,"line":2543},[268,7518,7476],{"class":339},[268,7520,7479],{"class":335},[268,7522,7482],{"class":311},[268,7524,3739],{"class":335},[268,7526,7527],{"class":339}," formatUrls.webp ",[268,7529,976],{"class":335},[268,7531,7532],{"class":311}," '\" type=\"image\u002Fwebp\" \u002F>'",[268,7534,732],{"class":339},[268,7536,7537],{"class":270,"line":2556},[268,7538,874],{"class":339},[268,7540,7541],{"class":270,"line":2561},[268,7542,1355],{"class":339},[268,7544,7545],{"class":270,"line":2566},[268,7546,7547],{"class":274},"            \u002F\u002F Fallback img\n",[268,7549,7550,7553,7555,7558],{"class":270,"line":2572},[268,7551,7552],{"class":339},"            html ",[268,7554,7479],{"class":335},[268,7556,7557],{"class":311}," '\u003Cimg '",[268,7559,732],{"class":339},[268,7561,7562],{"class":270,"line":2588},[268,7563,1355],{"class":339},[268,7565,7566,7568],{"class":270,"line":2593},[268,7567,852],{"class":335},[268,7569,7570],{"class":339}," (lazy) {\n",[268,7572,7573,7575,7577,7580,7583,7586,7588,7591,7593,7596,7598],{"class":270,"line":2598},[268,7574,7476],{"class":339},[268,7576,7479],{"class":335},[268,7578,7579],{"class":311}," 'src=\"data:image\u002Fsvg+xml,%3Csvg xmlns=",[268,7581,7582],{"class":304},"\\'",[268,7584,7585],{"class":311},"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg",[268,7587,7582],{"class":304},[268,7589,7590],{"class":311}," viewBox=",[268,7592,7582],{"class":304},[268,7594,7595],{"class":311},"0 0 '",[268,7597,3739],{"class":335},[268,7599,3271],{"class":339},[268,7601,7602,7605,7607,7610,7612,7614,7616,7618,7621,7623,7625,7627,7629,7632,7634,7637],{"class":270,"line":2610},[268,7603,7604],{"class":339},"                        (options.width ",[268,7606,1345],{"class":335},[268,7608,7609],{"class":304}," 400",[268,7611,1342],{"class":339},[268,7613,976],{"class":335},[268,7615,3736],{"class":311},[268,7617,3739],{"class":335},[268,7619,7620],{"class":339}," (options.height ",[268,7622,1345],{"class":335},[268,7624,7609],{"class":304},[268,7626,1342],{"class":339},[268,7628,976],{"class":335},[268,7630,7631],{"class":311}," '",[268,7633,7582],{"class":304},[268,7635,7636],{"class":311},"%3E%3C\u002Fsvg%3E\" '",[268,7638,732],{"class":339},[268,7640,7641,7643,7645,7648,7650,7653,7655,7658],{"class":270,"line":2623},[268,7642,7476],{"class":339},[268,7644,7479],{"class":335},[268,7646,7647],{"class":311}," 'data-lazy-src=\"'",[268,7649,3739],{"class":335},[268,7651,7652],{"class":339}," responsiveAttrs.src ",[268,7654,976],{"class":335},[268,7656,7657],{"class":311}," '\" '",[268,7659,732],{"class":339},[268,7661,7662,7664,7666,7669,7671,7674,7676,7678],{"class":270,"line":2642},[268,7663,7476],{"class":339},[268,7665,7479],{"class":335},[268,7667,7668],{"class":311}," 'data-lazy-srcset=\"'",[268,7670,3739],{"class":335},[268,7672,7673],{"class":339}," responsiveAttrs.srcset ",[268,7675,976],{"class":335},[268,7677,7657],{"class":311},[268,7679,732],{"class":339},[268,7681,7682,7684,7686],{"class":270,"line":2647},[268,7683,2188],{"class":339},[268,7685,2191],{"class":335},[268,7687,750],{"class":339},[268,7689,7690,7692,7694,7697,7699,7701,7703,7705],{"class":270,"line":2664},[268,7691,7476],{"class":339},[268,7693,7479],{"class":335},[268,7695,7696],{"class":311}," 'src=\"'",[268,7698,3739],{"class":335},[268,7700,7652],{"class":339},[268,7702,976],{"class":335},[268,7704,7657],{"class":311},[268,7706,732],{"class":339},[268,7708,7709,7711,7713,7716,7718,7720,7722,7724],{"class":270,"line":2674},[268,7710,7476],{"class":339},[268,7712,7479],{"class":335},[268,7714,7715],{"class":311}," 'srcset=\"'",[268,7717,3739],{"class":335},[268,7719,7673],{"class":339},[268,7721,976],{"class":335},[268,7723,7657],{"class":311},[268,7725,732],{"class":339},[268,7727,7728],{"class":270,"line":2679},[268,7729,874],{"class":339},[268,7731,7732],{"class":270,"line":2684},[268,7733,1355],{"class":339},[268,7735,7736,7738,7740,7743,7745,7748,7750,7752],{"class":270,"line":2689},[268,7737,7552],{"class":339},[268,7739,7479],{"class":335},[268,7741,7742],{"class":311}," 'sizes=\"'",[268,7744,3739],{"class":335},[268,7746,7747],{"class":339}," responsiveAttrs.sizes ",[268,7749,976],{"class":335},[268,7751,7657],{"class":311},[268,7753,732],{"class":339},[268,7755,7756,7758,7760,7763,7765,7767,7769,7771],{"class":270,"line":2695},[268,7757,7552],{"class":339},[268,7759,7479],{"class":335},[268,7761,7762],{"class":311}," 'alt=\"'",[268,7764,3739],{"class":335},[268,7766,7324],{"class":339},[268,7768,976],{"class":335},[268,7770,7657],{"class":311},[268,7772,732],{"class":339},[268,7774,7775,7777,7779,7782,7784,7787,7789,7791,7793,7795,7797],{"class":270,"line":2707},[268,7776,7552],{"class":339},[268,7778,7479],{"class":335},[268,7780,7781],{"class":311}," 'width=\"'",[268,7783,3739],{"class":335},[268,7785,7786],{"class":339}," (options.width ",[268,7788,1345],{"class":335},[268,7790,1348],{"class":311},[268,7792,1342],{"class":339},[268,7794,976],{"class":335},[268,7796,7657],{"class":311},[268,7798,732],{"class":339},[268,7800,7801,7803,7805,7808,7810,7812,7814,7816,7818,7820,7822],{"class":270,"line":2718},[268,7802,7552],{"class":339},[268,7804,7479],{"class":335},[268,7806,7807],{"class":311}," 'height=\"'",[268,7809,3739],{"class":335},[268,7811,7620],{"class":339},[268,7813,1345],{"class":335},[268,7815,1348],{"class":311},[268,7817,1342],{"class":339},[268,7819,976],{"class":335},[268,7821,7657],{"class":311},[268,7823,732],{"class":339},[268,7825,7826,7828,7830,7833,7835,7838,7841,7844,7847,7849,7851,7853,7855],{"class":270,"line":2723},[268,7827,7552],{"class":339},[268,7829,7479],{"class":335},[268,7831,7832],{"class":311}," 'class=\"optimized-image-img'",[268,7834,3739],{"class":335},[268,7836,7837],{"class":339}," (lazy ",[268,7839,7840],{"class":335},"?",[268,7842,7843],{"class":311}," ' lazy-image'",[268,7845,7846],{"class":335}," :",[268,7848,1348],{"class":311},[268,7850,1342],{"class":339},[268,7852,976],{"class":335},[268,7854,7657],{"class":311},[268,7856,732],{"class":339},[268,7858,7859,7861,7863,7866],{"class":270,"line":2728},[268,7860,7552],{"class":339},[268,7862,7479],{"class":335},[268,7864,7865],{"class":311}," '\u002F>\u003C\u002Fpicture>'",[268,7867,732],{"class":339},[268,7869,7870],{"class":270,"line":2740},[268,7871,1355],{"class":339},[268,7873,7874,7876,7878,7881,7884],{"class":270,"line":2752},[268,7875,959],{"class":335},[268,7877,2108],{"class":335},[268,7879,7880],{"class":339}," Handlebars.",[268,7882,7883],{"class":300},"SafeString",[268,7885,7886],{"class":339},"(html);\n",[268,7888,7889],{"class":270,"line":2765},[268,7890,1161],{"class":339},[268,7892,7893],{"class":270,"line":2770},[268,7894,774],{"class":339},[268,7896,7897],{"class":270,"line":2775},[268,7898,1172],{"class":339},[110,7900,7902],{"id":7901},"using-the-extension-in-templates","Using the Extension in Templates",[258,7904,7906],{"className":542,"code":7905,"language":544,"meta":263,"style":263},"{{!-- product_list_item.tpl --}}\n\u003Cdiv class=\"product-list-item\">\n    {{optimizedImage \n        url=imageUrl \n        alt=productName \n        context=\"product-listing\"\n        width=400 \n        height=400 \n        lazy=true\n        class=\"product-list-item-image\"\n    }}\n    \u003Ch3 class=\"product-list-item-name\">{{productName}}\u003C\u002Fh3>\n\u003C\u002Fdiv>\n",[265,7907,7908,7912,7916,7921,7926,7931,7936,7941,7946,7951,7955,7960,7965],{"__ignoreMap":263},[268,7909,7910],{"class":270,"line":271},[268,7911,2810],{},[268,7913,7914],{"class":270,"line":278},[268,7915,2815],{},[268,7917,7918],{"class":270,"line":284},[268,7919,7920],{},"    {{optimizedImage \n",[268,7922,7923],{"class":270,"line":291},[268,7924,7925],{},"        url=imageUrl \n",[268,7927,7928],{"class":270,"line":297},[268,7929,7930],{},"        alt=productName \n",[268,7932,7933],{"class":270,"line":321},[268,7934,7935],{},"        context=\"product-listing\"\n",[268,7937,7938],{"class":270,"line":326},[268,7939,7940],{},"        width=400 \n",[268,7942,7943],{"class":270,"line":332},[268,7944,7945],{},"        height=400 \n",[268,7947,7948],{"class":270,"line":355},[268,7949,7950],{},"        lazy=true\n",[268,7952,7953],{"class":270,"line":394},[268,7954,4493],{},[268,7956,7957],{"class":270,"line":598},[268,7958,7959],{},"    }}\n",[268,7961,7962],{"class":270,"line":604},[268,7963,7964],{},"    \u003Ch3 class=\"product-list-item-name\">{{productName}}\u003C\u002Fh3>\n",[268,7966,7967],{"class":270,"line":610},[268,7968,2863],{},[26,7970],{},[29,7972,85],{"id":7973},"measuring-image-performance-impact",[15,7975,7976],{},"You can't improve what you don't measure.",[15,7978,7979],{},[2288,7980],{"alt":7981,"src":7982},"Fast website loading and image delivery performance","\u002Fimages\u002Fblog\u002Fimage-optimization-performance.webp",[110,7984,7986],{"id":7985},"key-metrics-to-track","Key Metrics to Track",[115,7988,7989,8001],{},[118,7990,7991],{},[121,7992,7993,7995,7998],{},[124,7994,126],{},[124,7996,7997],{},"Target",[124,7999,8000],{},"Measurement Tool",[137,8002,8003,8014,8025,8036,8046],{},[121,8004,8005,8008,8011],{},[142,8006,8007],{},"LCP",[142,8009,8010],{},"\u003C 2.5s",[142,8012,8013],{},"PageSpeed Insights, CrUX",[121,8015,8016,8019,8022],{},[142,8017,8018],{},"Total image weight",[142,8020,8021],{},"\u003C 2MB\u002Fpage",[142,8023,8024],{},"Chrome DevTools Network",[121,8026,8027,8030,8033],{},[142,8028,8029],{},"Images above fold",[142,8031,8032],{},"\u003C 500KB",[142,8034,8035],{},"Manual inspection",[121,8037,8038,8040,8043],{},[142,8039,186],{},[142,8041,8042],{},"\u003C 20 initial",[142,8044,8045],{},"DevTools Network",[121,8047,8048,8051,8054],{},[142,8049,8050],{},"CLS from images",[142,8052,8053],{},"\u003C 0.1",[142,8055,8056],{},"PageSpeed Insights",[110,8058,8060],{"id":8059},"automated-performance-monitoring","Automated Performance Monitoring",[15,8062,8063],{},"Set up Lighthouse CI to track image metrics over time:",[258,8065,8069],{"className":8066,"code":8067,"language":8068,"meta":263,"style":263},"language-yaml shiki shiki-themes github-light github-dark","# lighthouserc.js\nmodule.exports = {\n  ci: {\n    collect: {\n      url: [\n        'https:\u002F\u002Fyoursite.com\u002F',\n        'https:\u002F\u002Fyoursite.com\u002Fcategory\u002Fproducts',\n        'https:\u002F\u002Fyoursite.com\u002Fproduct\u002Fsample-product'\n      ],\n      numberOfRuns: 3\n    },\n    assert: {\n      assertions: {\n        'largest-contentful-paint': ['warn', { maxNumericValue: 2500 }],\n        'cumulative-layout-shift': ['error', { maxNumericValue: 0.1 }],\n        'uses-webp-images': 'warn',\n        'uses-responsive-images': 'warn',\n        'offscreen-images': 'warn'\n      }\n    },\n    upload: {\n      target: 'temporary-public-storage'\n    }\n  }\n};\n","yaml",[265,8070,8071,8076,8081,8089,8096,8104,8111,8118,8123,8128,8138,8143,8150,8157,8182,8203,8214,8225,8235,8240,8244,8251,8261,8265,8270],{"__ignoreMap":263},[268,8072,8073],{"class":270,"line":271},[268,8074,8075],{"class":274},"# lighthouserc.js\n",[268,8077,8078],{"class":270,"line":278},[268,8079,8080],{"class":311},"module.exports = {\n",[268,8082,8083,8086],{"class":270,"line":284},[268,8084,8085],{"class":2941},"  ci",[268,8087,8088],{"class":339},": {\n",[268,8090,8091,8094],{"class":270,"line":291},[268,8092,8093],{"class":2941},"    collect",[268,8095,8088],{"class":339},[268,8097,8098,8101],{"class":270,"line":297},[268,8099,8100],{"class":2941},"      url",[268,8102,8103],{"class":339},": [\n",[268,8105,8106,8109],{"class":270,"line":321},[268,8107,8108],{"class":311},"        'https:\u002F\u002Fyoursite.com\u002F'",[268,8110,761],{"class":339},[268,8112,8113,8116],{"class":270,"line":326},[268,8114,8115],{"class":311},"        'https:\u002F\u002Fyoursite.com\u002Fcategory\u002Fproducts'",[268,8117,761],{"class":339},[268,8119,8120],{"class":270,"line":332},[268,8121,8122],{"class":311},"        'https:\u002F\u002Fyoursite.com\u002Fproduct\u002Fsample-product'\n",[268,8124,8125],{"class":270,"line":355},[268,8126,8127],{"class":339},"      ],\n",[268,8129,8130,8133,8135],{"class":270,"line":394},[268,8131,8132],{"class":2941},"      numberOfRuns",[268,8134,838],{"class":339},[268,8136,8137],{"class":304},"3\n",[268,8139,8140],{"class":270,"line":598},[268,8141,8142],{"class":339},"    },\n",[268,8144,8145,8148],{"class":270,"line":604},[268,8146,8147],{"class":2941},"    assert",[268,8149,8088],{"class":339},[268,8151,8152,8155],{"class":270,"line":610},[268,8153,8154],{"class":2941},"      assertions",[268,8156,8088],{"class":339},[268,8158,8159,8162,8165,8168,8171,8174,8176,8179],{"class":270,"line":615},[268,8160,8161],{"class":311},"        'largest-contentful-paint'",[268,8163,8164],{"class":339},": [",[268,8166,8167],{"class":311},"'warn'",[268,8169,8170],{"class":339},", { ",[268,8172,8173],{"class":2941},"maxNumericValue",[268,8175,838],{"class":339},[268,8177,8178],{"class":304},"2500",[268,8180,8181],{"class":339}," }],\n",[268,8183,8184,8187,8189,8192,8194,8196,8198,8201],{"class":270,"line":620},[268,8185,8186],{"class":311},"        'cumulative-layout-shift'",[268,8188,8164],{"class":339},[268,8190,8191],{"class":311},"'error'",[268,8193,8170],{"class":339},[268,8195,8173],{"class":2941},[268,8197,838],{"class":339},[268,8199,8200],{"class":304},"0.1",[268,8202,8181],{"class":339},[268,8204,8205,8208,8210,8212],{"class":270,"line":626},[268,8206,8207],{"class":311},"        'uses-webp-images'",[268,8209,838],{"class":339},[268,8211,8167],{"class":311},[268,8213,761],{"class":339},[268,8215,8216,8219,8221,8223],{"class":270,"line":632},[268,8217,8218],{"class":311},"        'uses-responsive-images'",[268,8220,838],{"class":339},[268,8222,8167],{"class":311},[268,8224,761],{"class":339},[268,8226,8227,8230,8232],{"class":270,"line":638},[268,8228,8229],{"class":311},"        'offscreen-images'",[268,8231,838],{"class":339},[268,8233,8234],{"class":311},"'warn'\n",[268,8236,8237],{"class":270,"line":644},[268,8238,8239],{"class":339},"      }\n",[268,8241,8242],{"class":270,"line":650},[268,8243,8142],{"class":339},[268,8245,8246,8249],{"class":270,"line":656},[268,8247,8248],{"class":2941},"    upload",[268,8250,8088],{"class":339},[268,8252,8253,8256,8258],{"class":270,"line":662},[268,8254,8255],{"class":2941},"      target",[268,8257,838],{"class":339},[268,8259,8260],{"class":311},"'temporary-public-storage'\n",[268,8262,8263],{"class":270,"line":668},[268,8264,2963],{"class":339},[268,8266,8267],{"class":270,"line":886},[268,8268,8269],{"class":339},"  }\n",[268,8271,8272,8275],{"class":270,"line":911},[268,8273,8274],{"class":339},"}",[268,8276,732],{"class":311},[110,8278,8280],{"id":8279},"beforeafter-comparison","Before\u002FAfter Comparison",[15,8282,8283],{},"Document your optimization results:",[258,8285,8289],{"className":8286,"code":8287,"language":8288,"meta":263,"style":263},"language-markdown shiki shiki-themes github-light github-dark","## Image Optimization Results - [Date]\n\n### Product Listing Page\n\n| Metric | Before | After | Improvement |\n|--------|--------|-------|-------------|\n| Page weight | 8.2MB | 2.1MB | 74% |\n| LCP | 4.8s | 1.9s | 60% |\n| Image count (initial) | 45 | 12 | 73% |\n| Time to Interactive | 6.2s | 3.1s | 50% |\n\n### Product Detail Page\n\n| Metric | Before | After | Improvement |\n|--------|--------|-------|-------------|\n| Page weight | 3.4MB | 1.2MB | 65% |\n| LCP | 3.2s | 1.5s | 53% |\n| CLS | 0.18 | 0.02 | 89% |\n","markdown",[265,8290,8291,8296,8300,8305,8309,8314,8319,8324,8329,8334,8339,8343,8348,8352,8356,8360,8365,8370],{"__ignoreMap":263},[268,8292,8293],{"class":270,"line":271},[268,8294,8295],{},"## Image Optimization Results - [Date]\n",[268,8297,8298],{"class":270,"line":278},[268,8299,288],{"emptyLinePlaceholder":287},[268,8301,8302],{"class":270,"line":284},[268,8303,8304],{},"### Product Listing Page\n",[268,8306,8307],{"class":270,"line":291},[268,8308,288],{"emptyLinePlaceholder":287},[268,8310,8311],{"class":270,"line":297},[268,8312,8313],{},"| Metric | Before | After | Improvement |\n",[268,8315,8316],{"class":270,"line":321},[268,8317,8318],{},"|--------|--------|-------|-------------|\n",[268,8320,8321],{"class":270,"line":326},[268,8322,8323],{},"| Page weight | 8.2MB | 2.1MB | 74% |\n",[268,8325,8326],{"class":270,"line":332},[268,8327,8328],{},"| LCP | 4.8s | 1.9s | 60% |\n",[268,8330,8331],{"class":270,"line":355},[268,8332,8333],{},"| Image count (initial) | 45 | 12 | 73% |\n",[268,8335,8336],{"class":270,"line":394},[268,8337,8338],{},"| Time to Interactive | 6.2s | 3.1s | 50% |\n",[268,8340,8341],{"class":270,"line":598},[268,8342,288],{"emptyLinePlaceholder":287},[268,8344,8345],{"class":270,"line":604},[268,8346,8347],{},"### Product Detail Page\n",[268,8349,8350],{"class":270,"line":610},[268,8351,288],{"emptyLinePlaceholder":287},[268,8353,8354],{"class":270,"line":615},[268,8355,8313],{},[268,8357,8358],{"class":270,"line":620},[268,8359,8318],{},[268,8361,8362],{"class":270,"line":626},[268,8363,8364],{},"| Page weight | 3.4MB | 1.2MB | 65% |\n",[268,8366,8367],{"class":270,"line":632},[268,8368,8369],{},"| LCP | 3.2s | 1.5s | 53% |\n",[268,8371,8372],{"class":270,"line":638},[268,8373,8374],{},"| CLS | 0.18 | 0.02 | 89% |\n",[26,8376],{},[29,8378,91],{"id":8379},"common-pitfalls-and-how-to-avoid-them",[110,8381,8383],{"id":8382},"pitfall-1-lazy-loading-above-the-fold-images","Pitfall 1: Lazy Loading Above-the-Fold Images",[15,8385,8386,8389],{},[18,8387,8388],{},"Problem:"," Lazy loading the hero image or first product row increases LCP.",[15,8391,8392,8395,8396,1869,8398,8400],{},[18,8393,8394],{},"Solution:"," Audit your templates. Use ",[265,8397,3170],{},[265,8399,3219],{}," for the first 1-3 visible images.",[110,8402,8404],{"id":8403},"pitfall-2-missing-widthheight-attributes","Pitfall 2: Missing Width\u002FHeight Attributes",[15,8406,8407,8409],{},[18,8408,8388],{}," Layout shifts when images load, hurting CLS score.",[15,8411,8412,8414,8415,1869,8417,8419,8420,8423],{},[18,8413,8394],{}," Always include explicit ",[265,8416,1868],{},[265,8418,1872],{}," attributes. If dimensions vary, use CSS ",[265,8421,8422],{},"aspect-ratio",":",[258,8425,8429],{"className":8426,"code":8427,"language":8428,"meta":263,"style":263},"language-css shiki shiki-themes github-light github-dark",".product-image {\n    aspect-ratio: 1 \u002F 1;\n    width: 100%;\n    height: auto;\n}\n","css",[265,8430,8431,8438,8454,8467,8479],{"__ignoreMap":263},[268,8432,8433,8436],{"class":270,"line":271},[268,8434,8435],{"class":300},".product-image",[268,8437,750],{"class":339},[268,8439,8440,8443,8445,8447,8450,8452],{"class":270,"line":278},[268,8441,8442],{"class":304},"    aspect-ratio",[268,8444,838],{"class":339},[268,8446,1532],{"class":304},[268,8448,8449],{"class":339}," \u002F ",[268,8451,1532],{"class":304},[268,8453,732],{"class":339},[268,8455,8456,8459,8461,8463,8465],{"class":270,"line":284},[268,8457,8458],{"class":304},"    width",[268,8460,838],{"class":339},[268,8462,6558],{"class":304},[268,8464,382],{"class":335},[268,8466,732],{"class":339},[268,8468,8469,8472,8474,8477],{"class":270,"line":291},[268,8470,8471],{"class":304},"    height",[268,8473,838],{"class":339},[268,8475,8476],{"class":304},"auto",[268,8478,732],{"class":339},[268,8480,8481],{"class":270,"line":297},[268,8482,2968],{"class":339},[110,8484,8486],{"id":8485},"pitfall-3-serving-desktop-images-to-mobile","Pitfall 3: Serving Desktop Images to Mobile",[15,8488,8489,8491],{},[18,8490,8388],{}," Mobile users download 1200px images for 400px containers.",[15,8493,8494,8496,8497,1869,8499,8501],{},[18,8495,8394],{}," Implement proper ",[265,8498,3249],{},[265,8500,3253],{}," attributes. Test on real devices, not just browser emulation.",[110,8503,8505],{"id":8504},"pitfall-4-not-compressing-original-uploads","Pitfall 4: Not Compressing Original Uploads",[15,8507,8508,8510],{},[18,8509,8388],{}," Optimization efforts wasted on 5MB source images.",[15,8512,8513,8515],{},[18,8514,8394],{}," Compress images before upload. Automate with upload validation scripts.",[110,8517,8519],{"id":8518},"pitfall-5-breaking-image-seo","Pitfall 5: Breaking Image SEO",[15,8521,8522,8524],{},[18,8523,8388],{}," Aggressive optimization removes alt text or breaks Google Image indexing.",[15,8526,8527,8529],{},[18,8528,8394],{}," Keep alt attributes meaningful. Don't block image URLs in robots.txt. Test Google Image search visibility.",[26,8531],{},[29,8533,97],{"id":8534},"faq",[110,8536,8538],{"id":8537},"whats-the-fastest-way-to-improve-lcp-on-my-suitecommerce-site","What's the fastest way to improve LCP on my SuiteCommerce site?",[15,8540,8541,8542,8544],{},"Start with the hero image and first row of product images. Convert to WebP, properly size them, use ",[265,8543,3219],{}," on the LCP image, and ensure proper cache headers. This alone typically improves LCP by 30-50%.",[110,8546,8548],{"id":8547},"should-i-use-a-third-party-image-optimization-service","Should I use a third-party image optimization service?",[15,8550,8551],{},"For sites with large catalogs (10,000+ products), third-party services like Cloudinary, imgix, or Cloudflare Images are worth the cost. They handle format conversion, resizing, and CDN delivery automatically. For smaller catalogs, the techniques in this guide are sufficient.",[110,8553,8555],{"id":8554},"how-do-i-optimize-images-in-netsuites-file-cabinet","How do I optimize images in NetSuite's File Cabinet?",[15,8557,8558],{},"NetSuite's File Cabinet doesn't support dynamic image transformations. Either: (1) pre-generate optimized versions and upload separately, (2) use a CDN with image transformation capabilities, or (3) build a SuiteScript service that proxies and transforms images.",[110,8560,8562],{"id":8561},"does-image-optimization-affect-seo-negatively","Does image optimization affect SEO negatively?",[15,8564,8565],{},"Done correctly, no. WebP and AVIF are fully supported by Google. Lazy loading with proper placeholders doesn't affect indexing. Using descriptive alt text and allowing images to be crawled maintains Google Image visibility.",[110,8567,8569],{"id":8568},"how-much-improvement-can-i-realistically-expect","How much improvement can I realistically expect?",[15,8571,8572],{},"On a typical unoptimized SuiteCommerce site: 40-60% reduction in page weight, 30-50% improvement in LCP, and noticeable improvement in mobile experience. The exact numbers depend on your current state and implementation thoroughness.",[26,8574],{},[29,8576,8578],{"id":8577},"start-optimizing","Start Optimizing",[15,8580,8581],{},"Image optimization is the highest-ROI performance improvement for most SuiteCommerce sites. The techniques in this guide can be implemented incrementally—start with the quick wins (WebP conversion, lazy loading below-fold images) and progress to the comprehensive extension approach.",[15,8583,8584,8585,8589],{},"If you need help diagnosing image performance issues or implementing these optimizations, ",[40,8586,8588],{"href":8587},"\u002Fsuitecommerce-services\u002Fperformance","our performance team"," has optimized dozens of SuiteCommerce sites. We're happy to run a free performance audit and identify your specific image bottlenecks.",[15,8591,8592],{},[18,8593,8594],{},"Every millisecond counts. Your images shouldn't be the reason customers leave.",[8596,8597,8598],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .snhLl, html code.shiki .snhLl{--shiki-default:#22863A;--shiki-default-font-weight:bold;--shiki-dark:#85E89D;--shiki-dark-font-weight:bold}html pre.shiki code .sA_wV, html code.shiki .sA_wV{--shiki-default:#032F62;--shiki-dark:#DBEDFF}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}",{"title":263,"searchDepth":278,"depth":278,"links":8600},[8601,8602,8607,8613,8618,8623,8629,8634,8639,8644,8651,8658],{"id":31,"depth":278,"text":32},{"id":102,"depth":278,"text":43,"children":8603},[8604,8605,8606],{"id":112,"depth":284,"text":113},{"id":201,"depth":284,"text":202},{"id":211,"depth":284,"text":212},{"id":238,"depth":278,"text":49,"children":8608},[8609,8610,8611,8612],{"id":244,"depth":284,"text":245},{"id":423,"depth":284,"text":424},{"id":531,"depth":284,"text":532},{"id":1175,"depth":284,"text":1176},{"id":1799,"depth":278,"text":55,"children":8614},[8615,8616,8617],{"id":1805,"depth":284,"text":1806},{"id":1876,"depth":284,"text":1877},{"id":3163,"depth":284,"text":3164},{"id":3231,"depth":278,"text":61,"children":8619},[8620,8621,8622],{"id":3243,"depth":284,"text":3244},{"id":3383,"depth":284,"text":3384},{"id":4510,"depth":284,"text":4511},{"id":4994,"depth":278,"text":67,"children":8624},[8625,8626,8627,8628],{"id":5000,"depth":284,"text":5001},{"id":5036,"depth":284,"text":5037},{"id":5089,"depth":284,"text":5090},{"id":5245,"depth":284,"text":5246},{"id":5573,"depth":278,"text":73,"children":8630},[8631,8632,8633],{"id":5579,"depth":284,"text":5580},{"id":5671,"depth":284,"text":5672},{"id":6300,"depth":284,"text":6301},{"id":6895,"depth":278,"text":79,"children":8635},[8636,8637,8638],{"id":6901,"depth":284,"text":6902},{"id":6911,"depth":284,"text":6912},{"id":7901,"depth":284,"text":7902},{"id":7973,"depth":278,"text":85,"children":8640},[8641,8642,8643],{"id":7985,"depth":284,"text":7986},{"id":8059,"depth":284,"text":8060},{"id":8279,"depth":284,"text":8280},{"id":8379,"depth":278,"text":91,"children":8645},[8646,8647,8648,8649,8650],{"id":8382,"depth":284,"text":8383},{"id":8403,"depth":284,"text":8404},{"id":8485,"depth":284,"text":8486},{"id":8504,"depth":284,"text":8505},{"id":8518,"depth":284,"text":8519},{"id":8534,"depth":278,"text":97,"children":8652},[8653,8654,8655,8656,8657],{"id":8537,"depth":284,"text":8538},{"id":8547,"depth":284,"text":8548},{"id":8554,"depth":284,"text":8555},{"id":8561,"depth":284,"text":8562},{"id":8568,"depth":284,"text":8569},{"id":8577,"depth":278,"text":8578},[8660,8661],"Performance","SuiteCommerce","2026-02-03","Complete guide to image optimization for SuiteCommerce stores. Covers WebP conversion, lazy loading, responsive images, CDN configuration, and custom optimization extensions.","md","\u002Fimages\u002Fblog\u002Fimage-optimization-hero.webp",{},"\u002Fblog\u002Fsuitecommerce-image-optimization-developer-guide",null,{"title":5,"description":8663},"blog\u002Fsuitecommerce-image-optimization-developer-guide",[8672,8673,8674,8675,8660,8661],"Image Optimization","WebP","Lazy Loading","CDN","s4GpWIN6iPV5Z0dgMgzpOfnHhlIiaV6YsDn7iP9HvKk",[8678,8690,8700,8712,8721,8731,8743,8752,8755,8764,8773,8783,8791,8801,8809,8820,8832,8841,8850,8859,8867],{"path":8679,"title":8680,"categories":8681,"tags":8683,"heroImage":8689},"\u002Fblog\u002Fbuilding-custom-suitecommerce-extensions-developer-guide","Building Custom SuiteCommerce Extensions: A Developer's Start-to-Finish Guide",[8661,8682],"Development",[8684,8685,8686,8687,8688],"SuiteCommerce Extensions","Custom Development","Backbone.js","SuiteScript","Frontend Development","\u002Fimages\u002Fblog\u002Fextensions-guide-hero.webp",{"path":8691,"title":8692,"categories":8693,"tags":8694,"heroImage":8699},"\u002Fblog\u002Fcore-web-vitals-suitecommerce-optimization-checklist","Core Web Vitals for SuiteCommerce: The Complete 2026 Optimization Checklist",[8660,8661],[8695,8007,8696,8697,8698,8661],"Core Web Vitals","INP","CLS","Performance Optimization","\u002Fimages\u002Fblog\u002Fcore-web-vitals-hero.webp",{"path":8701,"title":8702,"categories":8703,"tags":8705,"heroImage":8711},"\u002Fblog\u002Ffixing-duplicate-content-suitecommerce-faceted-navigation","Fixing Duplicate Content in SuiteCommerce Faceted Navigation",[8704,8661],"SEO",[8706,8707,8708,8709,8661,8710],"Duplicate Content","Faceted Navigation","Canonical Tags","Technical SEO","URL Parameters","\u002Fimages\u002Fblog\u002Fduplicate-content-seo-hero.webp",{"path":8713,"title":8714,"categories":8715,"tags":8716,"heroImage":8720},"\u002Fblog\u002Fheadless-suitecommerce-when-does-it-make-sense","Headless SuiteCommerce: When Does It Make Sense?",[8661,8682],[8661,8717,8718,8719,8660],"Headless Commerce","Architecture","Implementation","\u002Fimages\u002Fblog\u002Fheadless-suitecommerce-hero.webp",{"path":8722,"title":8723,"categories":8724,"tags":8726,"heroImage":8730},"\u002Fblog\u002Fnetsuite-ecommerce-integration-architecture-how-suitecommerce-works","NetSuite E-commerce Integration Architecture: How SuiteCommerce Actually Works",[8661,8682,8725],"Integration",[8718,8725,8687,8727,8728,8729],"API","Backend","Frontend","\u002Fimages\u002Fblog\u002Fnetsuite-ecommerce-integration-hero.webp",{"path":8732,"title":8733,"categories":8734,"tags":8736,"heroImage":8742},"\u002Fblog\u002Fnetsuite-integration-without-celigo-when-custom-beats-off-the-shelf","NetSuite Integration Without Celigo: When Custom Beats Off-the-Shelf",[8735,8725],"NetSuite",[8737,8738,8739,8740,8687,8741],"NetSuite Integration","Celigo","Custom Integration","RESTlet","API Development","\u002Fimages\u002Fblog\u002Fnetsuite-integration-hero.webp",{"path":8744,"title":8745,"categories":8746,"tags":8747,"heroImage":8751},"\u002Fblog\u002Fsuitecommerce-checkout-optimization-fixing-abandonment","SuiteCommerce Checkout Optimization: Fixing Abandonment at the Technical Level",[8661,8660],[8661,8748,8749,8750,8660],"Checkout Optimization","Cart Abandonment","Conversions","\u002Fimages\u002Fblog\u002Fsuitecommerce-checkout-hero.webp",{"path":8667,"title":5,"categories":8753,"tags":8754,"heroImage":8665},[8660,8661],[8672,8673,8674,8675,8660,8661],{"path":8756,"title":8757,"categories":8758,"tags":8759,"heroImage":8763},"\u002Fblog\u002Fsuitecommerce-implementation-cost-guide-2026","SuiteCommerce Implementation Cost Guide: What to Expect in 2026",[8661,8719],[8760,8719,8735,8761,8762],"SuiteCommerce Cost","Budget Planning","E-commerce","\u002Fimages\u002Fblog\u002Fimplementation-cost-hero.webp",{"path":8765,"title":8766,"categories":8767,"tags":8768,"heroImage":8772},"\u002Fblog\u002Fsuitecommerce-migration-checklist-upgrading-without-downtime","The SuiteCommerce Migration Checklist: Upgrading Without Downtime",[8661,8682],[8661,8769,8770,8771,8719],"Migration","Upgrade","Zero Downtime","\u002Fimages\u002Fblog\u002Fmigration-checklist-hero.webp",{"path":8774,"title":8775,"categories":8776,"tags":8777,"heroImage":8782},"\u002Fblog\u002Fsuitecommerce-myaccount-customization-b2b-features","SuiteCommerce MyAccount Customization: 10 Features B2B Customers Need",[8661,8682],[8661,8778,8779,8780,8781],"MyAccount","B2B","Customization","Portal","\u002Fimages\u002Fblog\u002Fsuitecommerce-myaccount-hero.webp",{"path":8784,"title":8785,"categories":8786,"tags":8788,"heroImage":8790},"\u002Fblog\u002Fsuitecommerce-performance-audit-286-stores","We Audited 286 Live SuiteCommerce Stores. Here's What We Found",[8660,8787,8661],"Research",[8660,8661,8695,8787,8789],"Benchmarks","\u002Fimages\u002Fblog\u002Fsuitecommerce-audit-hero.webp",{"path":8792,"title":8793,"categories":8794,"tags":8795,"heroImage":8800},"\u002Fblog\u002Fsuitecommerce-product-page-optimization-conversions-seo","How to Optimize SuiteCommerce Product Pages for Conversions and SEO",[8704,8660,8661],[8796,8797,8798,8709,8799],"Product Pages","Conversion Optimization","Schema Markup","CRO","\u002Fimages\u002Fblog\u002Fsuitecommerce-product-page-hero.webp",{"path":8802,"title":8803,"categories":8804,"tags":8805,"heroImage":8808},"\u002Fblog\u002Fsuitecommerce-seo-schema-markup-technical-guide","SuiteCommerce SEO: Schema Markup, Technical SEO, and What Actually Works",[8704,8661],[8798,8709,8806,8807,8661,8735],"JSON-LD","Structured Data","\u002Fimages\u002Fblog\u002Fseo-schema-markup-hero.webp",{"path":8810,"title":8811,"categories":8812,"tags":8814,"heroImage":8819},"\u002Fblog\u002Fsuitecommerce-theme-development-design-to-deployment","SuiteCommerce Theme Development: From Design to Deployment",[8682,8661,8813],"Themes",[8815,8816,8817,8818,8688,8780],"Theme Development","SASS","CSS","Templates","\u002Fimages\u002Fblog\u002Fsuitecommerce-theme-hero.webp",{"path":8821,"title":8822,"categories":8823,"tags":8826,"heroImage":8831},"\u002Fblog\u002Fsuitecommerce-version-upgrade-guide-2024","SuiteCommerce Version Upgrade Guide: 2023.x to 2024.x",[8661,8824,8825],"Maintenance","Upgrades",[8827,8769,8828,8829,8830],"Version Upgrade","2024 Release","SCA","Deployment","\u002Fimages\u002Fblog\u002Fsuitecommerce-upgrade-hero.webp",{"path":8833,"title":8834,"categories":8835,"tags":8836,"heroImage":8840},"\u002Fblog\u002Fsuitecommerce-vs-bigcommerce-netsuite-users","SuiteCommerce vs. BigCommerce for NetSuite Users: Which Platform Wins?",[8661,8762],[8837,8661,8735,8838,8839,8725],"BigCommerce","Platform Comparison","E-commerce Platform","\u002Fimages\u002Fblog\u002Fsuitecommerce-vs-bigcommerce-hero.webp",{"path":8842,"title":8843,"categories":8844,"tags":8845,"heroImage":8849},"\u002Fblog\u002Fsuitescript-performance-optimization-writing-efficient-scripts","SuiteScript Performance Optimization: Writing Efficient Scripts",[8735,8687],[8687,8698,8846,8847,8848,8727],"Governance","Map\u002FReduce","NetSuite Development","\u002Fimages\u002Fblog\u002Fsuitescript-performance-hero.webp",{"path":8851,"title":8852,"categories":8853,"tags":8854,"heroImage":8858},"\u002Fblog\u002Ftroubleshooting-suitecommerce-15-common-errors-how-to-fix","Troubleshooting SuiteCommerce: 15 Common Errors and How to Fix Them",[8661,8682],[8661,8855,8856,8857,8682],"Troubleshooting","Errors","Debugging","\u002Fimages\u002Fblog\u002Ftroubleshooting-errors-hero.webp",{"path":8860,"title":8861,"categories":8862,"tags":8863,"heroImage":8866},"\u002Fblog\u002Ftrue-cost-suitecommerce-maintenance-annual-budget-guide","The True Cost of SuiteCommerce Maintenance: Annual Budget Planning Guide",[8661,8660],[8661,8824,8761,8864,8865],"TCO","E-commerce Operations","\u002Fimages\u002Fblog\u002Fsuitecommerce-maintenance-cost-hero.webp",{"path":8868,"title":8869,"categories":8870,"tags":8871,"heroImage":8873},"\u002Fblog\u002Fwhy-suitecommerce-site-slow-how-to-fix","Why Your SuiteCommerce Site is Slow (And How to Fix It)",[8660,8661],[8660,8661,8872,8855],"Speed Optimization","\u002Fimages\u002Fblog\u002Fslow-site-fix-hero.webp",1773773964272]