پرش به محتوا
تصاویر و رسانه

جلوگیری از فشرده‌سازی تصاویر وردپرس با کیفیت ۸۲ درصد

وردپرس هر JPEG ای که می‌سازد را با کیفیت ۸۲ از مقیاس ۰ تا ۱۰۰ دوباره کدگذاری می‌کند. این مقدار پیش‌فرض در WP_Image_Editor::get_default_quality() قرار دارد و اعمال می‌شود

منتشرشده

وردپرس هر JPEG ای که تولید می‌کند را با کیفیت ۸۲ از مقیاس ۰ تا ۱۰۰ دوباره کدگذاری می‌کند. این مقدار پیش‌فرض در WP_Image_Editor::get_default_quality() قرار دارد و روی هر نسخه‌ای که وردپرس از فایل آپلودی شما می‌سازد اعمال می‌شود — thumbnail، medium، medium_large، large و هر سایز اضافه‌ای که قالب شما ثبت می‌کند. برای عکس‌ها، ۸۲ یک تعادل منطقی بین حجم فایل و افت کیفیت است. اما برای اسکرین‌شات‌ها، تصاویر رابط کاربری، نمودارها، لوگوها و هر چیزی که متن تیز یا رنگ یکدست دارد، ۸۲ به‌وضوح مخرب است: نویز mosquito دور تک‌تک حروف می‌چرخد و روی گرادیان‌های نرم نوارنوار (banding) دیده می‌شود.

برای تغییر آن، یک فیلتر اضافه کنید و تصاویر بندانگشتی‌تان را دوباره بسازید. اما برای رفع مشکل اسکرین‌شات‌ها به‌طور خاص، پاسخ بهتر معمولاً این است که اصلاً از همان ابتدا یک JPEG تحویل وردپرس ندهید.

عدد ۸۲ واقعاً از کجا می‌آید

وردپرس مقدار پیش‌فرض JPEG خود را در نسخه ۴.۵ (سال ۲۰۱۶) از ۹۰ به ۸۲ کاهش داد تا وزن صفحه را بهینه کند. این مقدار توسط get_default_quality() در wp-includes/class-wp-image-editor.php برگردانده می‌شود و هر بار که ویرایشگر فعال — یعنی WP_Image_Editor_Imagick اگر هاست شما Imagick داشته باشد، وگرنه WP_Image_Editor_GD — یک فایل تغییر اندازه‌یافته می‌نویسد، خوانده می‌شود.

نکته مهم این است: ۸۲ به‌ازای هر سایز نسخه اعمال می‌شود، نه فقط یک بار. یک تصویر آپلود کنید و وردپرس آن را چندین بار از انکودر عبور می‌دهد و هر بار با کیفیت ۸۲ دوباره کوانتیزه می‌کند. خودِ فایل اصلی آپلودشده دست‌نخورده باقی می‌ماند اگر زیر آستانه تصویر بزرگ (۲۵۶۰ پیکسل در لبه بلند) باشد. اگر از این آستانه فراتر رود، وردپرس یک فایل -scaled.jpg دوباره‌کدگذاری‌شده با کیفیت ۸۲ می‌سازد و همان را به‌عنوان سایز «full» ارائه می‌دهد. پس این جمله که «تصویر با وضوح کامل من خوب است اما نسخه‌ای که در صفحه است لکه‌دار به نظر می‌رسد» تقریباً همیشه به این معنی است که srcset دارد یک زیرسایز با کیفیت ۸۲ یا فایل -scaled را انتخاب می‌کند.

چطور کیفیت را تغییر دهیم

فقط یک فیلتر برای هوک کردن وجود دارد. wp_editor_set_quality گزینه مدرن و استاندارد است — هم برای JPEG و هم WebP اجرا می‌شود و نوع MIME را دریافت می‌کند تا بتوانید شرط‌بندی کنید:

add_filter( 'wp_editor_set_quality', function ( $quality, $mime_type ) {
    if ( 'image/jpeg' === $mime_type ) {
        return 92; // up from 82
    }
    return $quality;
}, 10, 2 );

این را در یک mu-plugin کوچک (wp-content/mu-plugins/) یا یک افزونه مخصوص سایت قرار دهید. functions.php هم کار می‌کند، اما به‌محض اینکه قالب را عوض کنید این تنظیم را از دست می‌دهید.

فیلتر قدیمی‌تر jpeg_quality را هم به‌عنوان پیشنهاد خواهید دید. این فیلتر هنوز اجرا می‌شود (وردپرس آن را بلافاصله بعد از wp_editor_set_quality اعمال می‌کند، فقط برای JPEG)، اما هیچ دلیلی برای هوک کردن هر دو وجود ندارد — wp_editor_set_quality هر کاری که فیلتر قدیمی می‌کرد و بیشتر را پوشش می‌دهد.

یک چیزی که همه فراموش می‌کنند: این فیلتر فقط روی تصاویری که پس از فعال شدن آن کدگذاری می‌شوند اثر دارد. هر تصویر بندانگشتی که همین حالا در wp-content/uploads نشسته با کیفیت ۸۲ نوشته شده و با همان ۸۲ باقی می‌ماند. آن‌ها را دوباره بسازید:

wp media regenerate --yes

اگر از WP-CLI استفاده نمی‌کنید، افزونه Regenerate Thumbnails همین کار را از طریق پیشخوان انجام می‌دهد.

قبل از اینکه روی یک عدد تصمیم بگیرید، بهتر است به‌جای حدس زدن، ببینید یک کیفیت مشخص واقعاً چه بلایی سر تصویر خودتان می‌آورد. ابزار کیفیت JPEG وردپرس ما یک نمونه را در مرورگر با هر سطح کیفیت دوباره کدگذاری می‌کند تا بتوانید ظاهر شدن افت کیفیت را ببینید — تفاوت بین ۸۲، ۹۰ و ۱۰۰ را روی یک اسکرین‌شات به شکلی روشن می‌کند که یک عدد در فایل تنظیمات هرگز نمی‌تواند.

راه‌حل بهتر برای اسکرین‌شات‌ها و گرافیک‌های یکدست

بالا بردن عدد JPEG فقط علامت بیماری را درمان می‌کند. مشکل واقعی اسکرین‌شات‌ها این است که JPEG کدک اشتباهی برای آن‌هاست. فشرده‌سازی DCT در JPEG برای گرادیان‌های عکاسی تنظیم شده؛ روی لبه‌های تیز مشکی‌روی‌سفیدِ متن و اجزای رابط کاربری از هم می‌پاشد، و دقیقاً به همین دلیل است که کیفیت ۸۲ روی یک اسکرین‌شات خیلی بدتر از یک عکس ساحل به نظر می‌رسد.

به‌جای آن یک PNG آپلود کنید. وردپرس زیرسایزهای PNG را به‌صورت PNG نگه می‌دارد و PNG بدون اتلاف است — فیلتر کیفیت به آن دست نمی‌زند، پس در هیچ سایزی افت کیفیت وجود ندارد، فقط بازنمونه‌برداری تمیز. برای یک اسکرین‌شات، یک PNG خوب بهینه‌شده اغلب کوچک‌تر از یک JPEG با کیفیت بالا از همان تصویر است، چون رنگ یکدست در PNG خوب فشرده می‌شود و در JPEG افتضاح.

اگر فایل‌های کوچک‌تر یک فرمت با اتلاف را می‌خواهید بدون آسیب JPEG به لبه‌ها، WebP حد وسط است — اما همچنان کیفیت آن را از طریق همان فیلتر wp_editor_set_quality که بالا نشان داده شد کنترل می‌کنید، با شرط‌بندی روی image/webp.

چه کارهایی نکنید

کیفیت را به‌صورت سراسری روی ۱۰۰ نگذارید. این پرطرفدارترین پاسخ در نیمی از تاپیک‌های انجمن‌هاست و اشتباه است. JPEG با کیفیت ۱۰۰ بدون اتلاف نیست — همچنان کوانتیزه می‌کند — اما حجم هر عکس سایت شما را به میزان زیادی بدون هیچ سود دیداری‌ای باد می‌کند و LCP و Core Web Vitals را پایین می‌کشد. عدد را برای فرمتی که به آن نیاز دارد بالا ببرید، یا فرمت گرافیک‌ها را تغییر دهید؛ فشرده‌سازی را در کل سایت نابود نکنید.

فایل class-wp-image-editor.php را ویرایش نکنید. تغییر مقدار بازگشتی get_default_quality() در هسته تا زمانی که wp core update بعدی بی‌سروصدا آن را بازنویسی کند کار می‌کند. از فیلتر استفاده کنید.

سایزهای تصویر را برای «اجتناب از فشرده‌سازی» غیرفعال نکنید. خاموش کردن تولید تصویر بندانگشتی جلوی دوباره‌کدگذاری را نمی‌گیرد — بلکه srcset واکنش‌گرا را خراب می‌کند، در نتیجه مرورگرها روی موبایل تصویر تمام‌سایز شما را دانلود می‌کنند. مشکلی متفاوت، با نتیجه‌ای بدتر.

فرض نکنید آپلود دوباره تصاویر موجود را درست می‌کند. اگر فیلتر را تنظیم کنید اما مرحله regenerate را رد کنید، هر نسخه قدیمی همچنان کیفیت ۸۲ دارد. فیلتر فقط رو به جلو عمل می‌کند.

اگر تصاویرتان زیر ۲۵۶۰ پیکسل هستند فایل -scaled را مقصر ندانید — آن مسیر اصلاً برای آن‌ها اجرا نمی‌شود. اگر واقعاً به آن برخورد می‌کنید و می‌خواهید فایل اصلی دست‌نخورده ارائه شود، آن یک تنظیم جداگانه است؛ به غیرفعال کردن تصاویر scaled مراجعه کنید.

هنوز گیر کرده‌اید؟

اگر یک سایز مشخص بعد از regenerate هنوز خراب به نظر می‌رسد، مطمئن شوید که صفحه واقعاً کدام فایل را ارائه می‌دهد — تصویر را در یک تب جدید باز کنید و بررسی کنید که آیا نام فایل به یک پسوند ابعاد (-1024x768.jpg) یا -scaled.jpg ختم می‌شود. بازرس سایزهای تصویر هر نسخه‌ای که وردپرس از یک آپلود می‌سازد را نشان می‌دهد، تا دقیقاً ببینید srcset شما کدام سایز را به مرورگر تحویل می‌دهد و دیگر فایل اشتباهی را دیباگ نکنید.