# πŸ“ Π€ΠΎΡ€ΠΌΠ°Ρ‚ URL для рСсайзСра ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ ## ΠžΠ±Π·ΠΎΡ€ Quoter ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ автоматичСскоС ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ Ρ‡Π΅Ρ€Π΅Π· URL ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹. БистСма автоматичСски Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΌΠΈΠ½ΠΈΠ°Ρ‚ΡŽΡ€Ρ‹ Π² ΠΏΡ€Π΅Π΄ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Ρ… Ρ€Π°Π·ΠΌΠ΅Ρ€Π°Ρ… ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ блиТайший подходящий Ρ€Π°Π·ΠΌΠ΅Ρ€. ## 🎯 ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Π΅ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ ### ΠŸΡ€Π΅Π΄ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Π΅ ΡˆΠΈΡ€ΠΈΠ½Ρ‹ ```rust [10, 40, 110, 300, 600, 800, 1400] // пиксСлСй ΠΏΠΎ ΡˆΠΈΡ€ΠΈΠ½Π΅ ``` - **10px** - ΠΌΠΈΠΊΡ€ΠΎ-ΠΏΡ€Π΅Π²ΡŒΡŽ - **40px** - Π°Π²Π°Ρ‚Π°Ρ€Ρ‹, ΠΈΠΊΠΎΠ½ΠΊΠΈ - **110px** - малСнькиС ΠΏΡ€Π΅Π²ΡŒΡŽ - **300px** - срСдниС ΠΏΡ€Π΅Π²ΡŒΡŽ - **600px** - стандартныС изобраТСния - **800px** - большиС изобраТСния - **1400px** - ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ ## πŸ“ Бинтаксис URL ### 1. Π‘ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ (рСкомСндуСтся) ``` GET /{filename}_{width}.{extension} ``` **ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹:** ```bash # Запрос изобраТСния ΡˆΠΈΡ€ΠΈΠ½ΠΎΠΉ 300px GET /439efaa0-816f-11ef-b201-439da98539bc_300.jpg # Запрос изобраТСния ΡˆΠΈΡ€ΠΈΠ½ΠΎΠΉ 600px GET /5627e002-0c53-11ee-9565-0242ac110006_600.png # Запрос ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° (Π±Π΅Π· рСсайза) GET /439efaa0-816f-11ef-b201-439da98539bc.jpg ``` ### 2. Legacy Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ (поддСрТиваСтся) ``` GET /unsafe/{width}x/production/image/{filename}.{extension} ``` **ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹:** ```bash # Legacy Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ с ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ΠΌ ΡˆΠΈΡ€ΠΈΠ½Ρ‹ GET /unsafe/1440x/production/image/439efaa0-816f-11ef-b201-439da98539bc.jpg # Legacy Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ Π±Π΅Π· рСсайза GET /unsafe/production/image/5627e002-0c53-11ee-9565-0242ac110006.png ``` ### 3. ΠšΠΎΠ½Π²Π΅Ρ€ΡΠΈΡ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° ``` GET /{filename}.{extension}/webp ``` **ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹:** ```bash # ΠšΠΎΠ½Π²Π΅Ρ€ΡΠΈΡ Π² WebP GET /439efaa0-816f-11ef-b201-439da98539bc.jpg/webp # ΠšΠΎΠ½Π²Π΅Ρ€ΡΠΈΡ с рСсайзом GET /439efaa0-816f-11ef-b201-439da98539bc_600.jpg/webp ``` ## πŸ”§ Π›ΠΎΠ³ΠΈΠΊΠ° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ### Алгоритм Π²Ρ‹Π±ΠΎΡ€Π° Ρ€Π°Π·ΠΌΠ΅Ρ€Π° 1. **Π’ΠΎΡ‡Π½ΠΎΠ΅ совпадСниС**: Если Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½Π½Π°Ρ ΡˆΠΈΡ€ΠΈΠ½Π° Π΅ΡΡ‚ΡŒ Π² ΠΏΡ€Π΅Π΄ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Ρ… Ρ€Π°Π·ΠΌΠ΅Ρ€Π°Ρ… 2. **Π‘Π»ΠΈΠΆΠ°ΠΉΡˆΠΈΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€**: ВыбираСтся Ρ€Π°Π·ΠΌΠ΅Ρ€ с минимальной Ρ€Π°Π·Π½ΠΎΡΡ‚ΡŒΡŽ 3. **ΠœΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Π»ΠΈΠΌΠΈΡ‚**: Если Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½Π½Π°Ρ ΡˆΠΈΡ€ΠΈΠ½Π° > 1400px, возвращаСтся 1400px 4. **ΠžΡ€ΠΈΠ³ΠΈΠ½Π°Π»**: Если ΡˆΠΈΡ€ΠΈΠ½Π° Π½Π΅ ΡƒΠΊΠ°Π·Π°Π½Π° (0), возвращаСтся ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½ΠΎΠ΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ### ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ Π²Ρ‹Π±ΠΎΡ€Π° Ρ€Π°Π·ΠΌΠ΅Ρ€Π° ```bash # Запрос 150px β†’ Π²Π΅Ρ€Π½Π΅Ρ‚ 110px (блиТайший мСньший) # Запрос 250px β†’ Π²Π΅Ρ€Π½Π΅Ρ‚ 300px (блиТайший больший) # Запрос 2000px β†’ Π²Π΅Ρ€Π½Π΅Ρ‚ 1400px (ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ) # Запрос 299px β†’ Π²Π΅Ρ€Π½Π΅Ρ‚ 300px (блиТайший) # Запрос 301px β†’ Π²Π΅Ρ€Π½Π΅Ρ‚ 300px (блиТайший) ``` ### ГСнСрация ΠΌΠΈΠ½ΠΈΠ°Ρ‚ΡŽΡ€ - **Lazy generation**: ΠœΠΈΠ½ΠΈΠ°Ρ‚ΡŽΡ€Ρ‹ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ ΠΏΠΎ ΠΏΠ΅Ρ€Π²ΠΎΠΌΡƒ запросу - **Асинхронная ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°**: ГСнСрация происходит Π² Ρ„ΠΎΠ½Π΅ - **ΠšΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅**: Π‘ΠΎΠ·Π΄Π°Π½Π½Ρ‹Π΅ ΠΌΠΈΠ½ΠΈΠ°Ρ‚ΡŽΡ€Ρ‹ ΡΠΎΡ…Ρ€Π°Π½ΡΡŽΡ‚ΡΡ Π² S3 - **Fallback**: ΠŸΡ€ΠΈ отсутствии ΠΌΠΈΠ½ΠΈΠ°Ρ‚ΡŽΡ€Ρ‹ возвращаСтся ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π» ## 🎨 ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Π΅ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹ ### Π’Ρ…ΠΎΠ΄Π½Ρ‹Π΅ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹ - **JPEG** (`.jpg`, `.jpeg`) - **PNG** (`.png`) - **GIF** (`.gif`) - **WebP** (`.webp`) - **HEIC** (`.heic`, `.heif`) - конвСртируСтся Π² JPEG - **TIFF** (`.tiff`, `.tif`) - конвСртируСтся Π² JPEG ### Π’Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Π΅ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹ - **БохраняСтся исходный Ρ„ΠΎΡ€ΠΌΠ°Ρ‚** (ΠΊΡ€ΠΎΠΌΠ΅ HEIC/TIFF β†’ JPEG) - **WebP конвСрсия** Ρ‡Π΅Ρ€Π΅Π· `/webp` суффикс - **АвтоматичСская оптимизация** для web ## πŸš€ HTTP Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ ### ΠšΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ```http ETag: "filename.ext" Cache-Control: public, max-age=31536000, immutable Access-Control-Allow-Origin: * ``` ### УсловныС запросы ```http # ΠšΠ»ΠΈΠ΅Π½Ρ‚ отправляСт If-None-Match: "filename.ext" # Π‘Π΅Ρ€Π²Π΅Ρ€ ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ (Ссли Π½Π΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΎ) HTTP/1.1 304 Not Modified ``` ## πŸ’‘ ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ### ΠšΠ»ΠΈΠ΅Π½Ρ‚ΡΠΊΠ°Ρ оптимизация ```html ОписаниС ОписаниС ``` ### API использованиС ```javascript // Ѐункция для получСния ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ URL function getImageUrl(filename, maxWidth) { const sizes = [10, 40, 110, 300, 600, 800, 1400]; const optimalSize = sizes.find(size => size >= maxWidth) || 1400; const [name, ext] = filename.split('.'); return `https://files.dscrs.site/${name}_${optimalSize}.${ext}`; } // ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ использования const thumbUrl = getImageUrl('image.jpg', 300); // image_300.jpg const fullUrl = getImageUrl('image.jpg', 1200); // image_1400.jpg ``` ## πŸ” ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ ΠΈ ΠΎΡ‚Π»Π°Π΄ΠΊΠ° ### Π›ΠΎΠ³ΠΈ сСрвСра ```log # УспСшная ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° INFO GET image_300.jpg [START] INFO Parsed request - base: image, width: 300, ext: jpg INFO Cache hit for image.jpg, returning 304 # ГСнСрация ΠΌΠΈΠ½ΠΈΠ°Ρ‚ΡŽΡ€Ρ‹ WARN Thumbnail not found, generating: image_300.jpg WARN generate new thumb files: image.jpg INFO Generated thumbnail: image_300.jpg ``` ### ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Ρ‡Π΅Ρ€Π΅Π· API ```bash # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° сущСствования Ρ„Π°ΠΉΠ»Π° curl -I https://files.dscrs.site/image_300.jpg # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° с условным запросом curl -H "If-None-Match: \"image.jpg\"" https://files.dscrs.site/image_300.jpg ``` ## ⚠️ ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΡ ΠΈ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ ### Π›ΠΈΠΌΠΈΡ‚Ρ‹ - **Максимальная ΡˆΠΈΡ€ΠΈΠ½Π°**: 1400px - **ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Π΅ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹**: см. список Π²Ρ‹ΡˆΠ΅ - **Π Π°Π·ΠΌΠ΅Ρ€ Ρ„Π°ΠΉΠ»Π°**: Π΄ΠΎ 500MB для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ### Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ 1. **Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ WebP** для Π»ΡƒΡ‡ΡˆΠ΅Π³ΠΎ сТатия 2. **ΠšΡΡˆΠΈΡ€ΡƒΠΉΡ‚Π΅ Π½Π° CDN** для Π»ΡƒΡ‡ΡˆΠ΅ΠΉ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ 3. **Π£ΠΊΠ°Π·Ρ‹Π²Π°ΠΉΡ‚Π΅ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ Π·Π°Ρ€Π°Π½Π΅Π΅** для избСТания layout shift 4. **Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ lazy loading** для ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ Π²Π½Π΅ viewport ### Troubleshooting ```bash # Если ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π½Π΅ отобраТаСтся 1. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ Ρ„Π°ΠΉΠ»Π° (поддСрТиваСтся Π»ΠΈ) 2. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Ρ€Π°Π·ΠΌΠ΅Ρ€ запроса (Π½Π΅ ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ°Π΅Ρ‚ Π»ΠΈ Π»ΠΈΠΌΠΈΡ‚Ρ‹) 3. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Π»ΠΎΠ³ΠΈ сСрвСра Π½Π° ошибки Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ 4. Π£Π±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ Π² коррСктности URL Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° ```