قياسات ضغط الصور: عشرة نماذج داخل المتصفح

عشرة نماذج، خمس قياسات لكل منها، ومتصفح واحد. هذه قياسات المرمّزات من مسار العمل نفسه الذي ينشره الموقع، بما في ذلك الحالات التي لا تكون فيها النتيجة في صالحنا.

نشرها tinyimg. أدوات القياس ومولّد النماذج وملفات النتائج موجودة في المستودع، فيمكن التحقق من الطريقة والأرقام.

ما الذي قيس، وكيف؟

عشرة حالات من سبعة ملفات، بخمس قياسات لكل حالة: يقيس الاختبار زمن الضغط وحجم الناتج. الصورة الفوتوغرافية بدقة 12 ميغابكسل تُرمّز إلى JPEG وWebP وAVIF، ولقطة الشاشة بدقة 2 ميغابكسل تُرمّز إلى PNG وWebP.

تعمل أدوات القياس على المسار الذي يُنشر فعليًا. تستورد src/lib/pool.js وsrc/lib/worker.js — نفس تجمّع العمال ونفس العامل الذي يستخدمه التطبيق لـ JPEG وPNG وWebP وAVIF وJXL. ولـ MotionPhoto تستورد src/lib/motion-photo/pipeline.js، وهو المسار الذي يسلكه التطبيق لهذه الصيغة؛ فـ MotionPhoto لا يمر عبر تجمّع العمال في الإنتاج أيضًا. لا يوجد مرمّز خاص بالاختبار، ولا تنفيذ ثانٍ يمكن أن ينحرف عن الأول.

تُشغَّل كل حالة مرة واحدة كتهيئة، ثم خمس مرات مقيسة. تُشغَّل الحالات بالتتابع، فلا تتنافس على تجمّع العمال المؤلف من أربعة. الزمن المذكور هو الوسيط للعينات الخمس. ويُحسب p95 بالرتبة الأقرب، أي أنه عند خمس عينات يساوي أبطأ تشغيل — بلا استيفاء، وبلا ادعاء أن خمس عينات تصف الذيل.

المتصفح هو Chrome 155 بلا واجهة، مع ملف تعريف مؤقت جديد في كل تشغيل؛ الإضافات والشبكة الخلفية معطّلتان. تُقدَّم الصفحة من localhost، ويبدأ التوقيت بعد جاهزية تجمّع العمال ووحدات WASM. لا يُفعَّل العزل عبر المصادر عمدًا: فهو يجعل wasm-feature-detect يبلّغ عن دعم الخيوط ويحوّل oxipng إلى بنائه متعدد الخيوط، وهو ليس المسار الذي يستخدمه الإنتاج.

الجهاز هو Apple M4 بعشرة أنوية و16 غيغابايت من الذاكرة، يعمل بـ macOS على arm64. يبلّغ المتصفح عن 10 خيوط عتادية؛ ويحدّ التطبيق تجمّعه بأربعة عمال.

ما الملفات التي اختُبرت؟

سبعة ملفات، من JPEG بدقة 0.5 ميغابكسل إلى صورة فوتوغرافية بدقة 24 ميغابكسل، بالإضافة إلى MotionPhoto بدقة 12 ميغابكسل.

الملفالبكسلاتالمدخلماذا يمثّل
photo-12mp.jpg4000×30004.92 MBصورة فوتوغرافية غنية بالتفاصيل
shot-2mp.png1920×10801.36 MBلقطة شاشة لواجهة بحواف حادة وأشرطة تشبه النص
flat-1mp.png1000×1000118.1 KBرسم مسطّح قليل التفاصيل
alpha-4mp.png2000×20008.26 MBصورة RGBA بقناة شفافية حقيقية
large-24mp.jpg6000×40009.66 MBصورة فوتوغرافية بدقة 24 ميغابكسل
tiny-0.5mp.jpg800×600219.6 KBصورة صغيرة؛ تظهر هنا كلفة النداء الواحد
motion-12mp.jpgإطار ثابت 4000×3000 + فيديو 1280×720 مدته 6 ثوانٍ9.98 MBMotionPhoto مركّب بأداة الكتابة في المستودع

كل النماذج مولّدة بـ ffmpeg من مصادر مدمجة. تُسجَّل بصمة SHA-256 لكل ملف في bench/fixtures/manifest.json وتُتحقَّق قبل أن يحمّلها المتصفح، فتغيير أي نموذج يؤدي إلى فشل صريح بدل أن يتحرك خط الأساس بصمت.

ما النتائج؟

عشر حالات بنسب من 1.5% إلى 69.3% ووسائط من 42.0 ms إلى 1,983.2 ms. النسبة هي الناتج ÷ المدخل؛ الأقل أصغر. الوسيط وp95 هما الزمن الفعلي للحالة كاملة، بما في ذلك رحلة العامل. ويقسم ms/MP الوسيط على عدد الميغابكسل.

الجدول والرسمان يقرآن الملف نفسه، bench/published.json (معرّف التشغيل، التاريخ، البيئة)؛ وعند الاختلاف فالمرجع هو الملف.

نسبة الضغط حسب الحالةرسم أعمدة أفقي. النسبة هي حجم الناتج مقسوماً على حجم الإدخال؛ الأقل أفضل. تتراوح من 1.5% في shot-2mp-webp إلى 69.3% في motion-12mp.نسبة الضغط حسب الحالة0255075photo-12mp-jpgphoto-12mp-webpphoto-12mp-avifshot-2mp-pngshot-2mp-webpflat-1mp-pngalpha-4mp-aviflarge-24mp-jpgtiny-0.5mp-webpmotion-12mp8.8%6.5%2.4%43.2%1.5%51.7%4.4%8.6%9.3%69.3%الناتج ÷ الإدخال (%)الأقل أفضل
الأصغر: shot-2mp-webp بنسبة 1.5% من الأصل. الأكبر: motion-12mp بنسبة 69.3%.
زمن الترميز لكل ميغابكسلرسم أعمدة أفقي لوسيط زمن الترميز لكل ميغابكسل، بترتيب الحالات نفسه في رسم نسبة الضغط. من 51.2 مللي ثانية/ميغابكسل في large-24mp-jpg إلى 516.2 في flat-1mp-png.زمن الترميز لكل ميغابكسل0200400600photo-12mp-jpgphoto-12mp-webpphoto-12mp-avifshot-2mp-pngshot-2mp-webpflat-1mp-pngalpha-4mp-aviflarge-24mp-jpgtiny-0.5mp-webpmotion-12mp56.483.1165.3296.273.1516.2387.951.287.5111.2مللي ثانية/ميغابكسل (وسيط 5 تشغيلات)ترتيب الحالات مطابق لرسم نسبة الضغط
الأسرع لكل ميغابكسل: large-24mp-jpg عند 51.2 مللي ثانية/ميغابكسل. الأبطأ: flat-1mp-png عند 516.2.
الحالةالصيغةMPالمدخلالناتجالنسبةالوسيطp95ms/MP
photo-12mp-jpgJPEG → JPEG124.92 MB444.4 KB8.8%677.0733.456.4
photo-12mp-webpJPEG → WebP124.92 MB325.2 KB6.5%997.51021.783.1
photo-12mp-avifJPEG → AVIF124.92 MB121.8 KB2.4%1983.22026.8165.3
shot-2mp-pngPNG → PNG2.071.36 MB600.6 KB43.2%613.1618.1296.2
shot-2mp-webpPNG → WebP2.071.36 MB21.0 KB1.5%151.3156.173.1
flat-1mp-pngPNG → PNG1118.1 KB61.0 KB51.7%516.2562.9516.2
alpha-4mp-avifPNG → AVIF48.26 MB370.1 KB4.4%1551.71626.3387.9
large-24mp-jpgJPEG → JPEG249.66 MB846.1 KB8.6%1228.11231.051.2
tiny-0.5mp-webpJPEG → WebP0.48219.6 KB20.4 KB9.3%42.043.487.5
motion-12mpMotionPhoto129.98 MB6.92 MB69.3%1334.01377.3111.2

ماذا تقول الأرقام؟

على صورة 12 ميغابكسل، AVIF أصغر من JPEG بـ 3.65 مرة وأبطأ بـ 2.93 مرة؛ WebP بينهما، وPNG هو الاستثناء بلا فقدان عند 296.2 ms/MP.

بكم يكون AVIF أصغر من JPEG؟

نحو ثلث حجم JPEG: 2.4% مقابل 8.8% على الصورة بدقة 12 ميغابكسل، أي 121.8 KB مقابل 444.4 KB. وأنتج WebP حجم 325.2 KB. أي أن AVIF أصغر من JPEG بـ 3.65 مرة وأصغر من WebP بـ 2.67 مرة. وهو أيضًا الأبطأ: وسيط 1,983.2 ms، أي 2.93 ضعف زمن JPEG و1.99 ضعف زمن WebP. وبحسب الميغابكسل: 165.3 ms مقابل 56.4 لـ JPEG و83.1 لـ WebP.

هذه هي المقايضة في سطر واحد: ربع بايتات JPEG تقريبًا مقابل ثلاثة أضعاف زمن الترميز. في دفعة من مئات الصور، هذا الوقت حقيقي؛ وفي صورة رئيسية واحدة قد لا يهم.

بكم يكون WebP أصغر وأبطأ من JPEG؟

أصغر بنسبة 26.8% وأبطأ بـ 1.47 مرة: على المصدر نفسه بدقة 12 ميغابكسل 325.2 KB مقابل 444.4 KB، و997.5 ms مقابل 677.0 ms. ومقارنة بـ AVIF فهو أكبر بـ 2.67 مرة وأسرع بـ 1.99 مرة. ليس الأفضل في أي طرف؛ إنه الوسط في الاتجاهين.

ما مدى سرعة JPEG؟

677.0 ms للصورة بدقة 12 ميغابكسل (56.4 ms/MP) و1,228.1 ms للصورة بدقة 24 ميغابكسل (51.2 ms/MP)، وهو الأسرع بين المرمّزات الثلاثة هنا. الكلفة لكل ميغابكسل شبه ثابتة، وهذا ما يبدو عليه مرمّز كتلي سريع. ناتجه أكبر من الصيغتين الحديثتين، لكنه الصيغة التي يجب التغلّب عليها في الزمن، وعلى هذا الجهاز لم يتغلّب عليها أحد.

لماذا يكون PNG الأبطأ لكل ميغابكسل؟

296.2 ms/MP على لقطة الشاشة بدقة 2.07 ميغابكسل، أي 4.05 مرة أكثر من 73.1 ms/MP لـ WebP، لأن التحسين بلا فقدان يجب أن يبحث عن مرشحات واستراتيجيات DEFLATE لكل بكسل. استغرقت اللقطة 613.1 ms بصيغة PNG، وترميزها إلى WebP استغرق 151.3 ms. وكان PNG المسطّح بدقة 1 ميغابكسل أسوأ لكل بكسل: 516.2 ms، لأن الكلفة الثابتة للمحسّن موزّعة على ميغابكسل واحد فقط.

PNG بلا فقدان. يُحفظ كل بكسل، ويقضي oxipng وقته في البحث عن مرشحات واستراتيجيات DEFLATE لتيار أصغر؛ البحث هو الغاية وهو الكلفة في الوقت نفسه. يمكن للمرمّز بفقدان أن يتوقف عند بلوغ هدف الجودة. أما المحسّن بلا فقدان فيجب أن يثبت أنه لم يبق شيء يمكن إزالته، وعدد التركيبات ينمو مع الصورة.

فرق الحجم صريح بالمثل: اللقطة كانت 600.6 KB بصيغة PNG و21.0 KB بصيغة WebP. هذان الناتجان ليسا متكافئين — أحدهما بلا فقدان والآخر بفقدان — لكنهما يفسّران لماذا تكون PNG الخيار الصحيح لمخطط ستعدّله، والخيار الخاطئ لصورة فوتوغرافية ستنشرها.

هل يجعل مستوى oxipng الأعلى ملف PNG أصغر دائمًا؟

لا: كان المستوى 3 أصغر بنسبة 9.6–13.6% على نماذج لقطات الشاشة الثلاثة، لكنه وفّر أربعة بايتات فقط على PNG الفوتوغرافي بدقة 8.29 ميغابكسل، بزمن 8.2 ضعف. قيس مستوى PNG بشكل منفصل باستخدام bench/png-levels.mjs، على النماذج نفسها، بتهيئة واحدة وخمس تشغيلات لكل مستوى. على نماذج لقطات الشاشة الثلاثة (2.07 و8.29 و15.73 ميغابكسل)، استغرق المستوى 3 ما بين 7.8 و8.5 ضعف زمن المستوى 1، وأنتج ملفات أصغر بنسبة 9.6–13.6%. وعلى PNG الفوتوغرافي بدقة 8.29 ميغابكسل أنتج أربعة بايتات أقل من المستوى 1 — 15,474,918 مقابل 15,474,922 — واستغرق 8.2 ضعف الزمن. وعلى صورة RGBA وفّر 2.0% واستغرق 7.1 ضعف الزمن. البحث الإضافي لا يشتري شيئًا تقريبًا عندما تكون الصورة فوتوغرافية أصلًا.

لهذا يستخدم العامل المنشور المستوى 2 افتراضيًا، ويهبط إلى المستوى 1 فوق 4 ميغابكسل. عند 16 ميغابكسل كان المستوى 2 أكبر بنسبة 1.0% من المستوى 1 وأبطأ بنحو الضعف، لذا فالمستوى الأعلى ليس تلقائيًا ملفًا أصغر. تظهر كلفة التغيير على صور PNG المسطّحة قليلة التفاصيل: نموذج 1 ميغابكسل المسطّح يبلغ 62,501 B عند المستوى 2 مقابل 48,138 B عند المستوى 3 — أكبر بنسبة 29.8% — لكنه يُرمّز في 437.9 ms بدل 2,028.3 ms، أي أسرع بـ 4.6 مرة. لقطات الشاشة تدفع أقل: عند 2.07 ميغابكسل يكون ملف المستوى 2 أكبر بنسبة 7.2% من المستوى 3 وأسرع بـ 4.1 مرة. اختار الموقع الافتراضي الأسرع وقبل البايتات الإضافية.

هل يضغط MotionPhoto الفيديو أيضًا؟

لا: يُعاد ترميز الإطار الثابت فقط، ويُنسخ الفيديو بايتًا ببايت، لذا انخفض الملف المركّب بدقة 12 ميغابكسل بنسبة 30.7% بينما لم يُلمس نصفه. MotionPhoto هو ملف واحد: صورة JPEG ثابتة مع فيديو مضاف، وعلى بعض الهواتف خريطة كسب (gain map). يفكّ المسار المنشور ترميز الإطار الثابت ويعيد ترميزه، ثم يعيد بناء الحاوية حوله. لا يُفكّ ترميزه ولا يُعاد ترميزه ولا يُعرض كهدف. وخريطة الكسب، عند وجودها، تُنسخ أيضًا ويُعاد توجيه إزاحتها المطلقة في MPF كي يبقى عرض HDR سليمًا.

هذا يعني أن نسبة الملف كله يحكمها حجم الفيديو من الملف. في نموذج 12 ميغابكسل المركّب، يشغل الإطار الثابت 5,156,418 B من أصل 10,463,084 B (49.3%) ويشغل الفيديو 5,306,666 B (50.7%)؛ ولا توجد خريطة كسب. خرج الإطار الثابت بحجم 1,944,569 B، أي أصغر بنسبة 62.3%، وانتقل الملف كله من 9.98 MB إلى 6.92 MB — أصغر بنسبة 30.7%. ما يوفّره الإطار الثابت كبير؛ وما يوفّره الملف محدود بالنصف الذي لم يُلمس أصلًا.

يستخدم فحص العينة الحقيقية ملف MotionPhoto من OnePlus 13: الإطار الثابت 7,140,978 B (44.7%)، الفيديو 7,968,544 B (49.9%)، خريطة الكسب 848,042 B (5.3%)، الإجمالي 15,957,564 B. بعد مسار الإطار الثابت فقط: الإطار 1,862,140 B (أصغر بنسبة 73.9%)، والفيديو وخريطة الكسب متطابقان بايتًا ببايت، والإجمالي 10,712,466 B — من 15.96 MB إلى 10.71 MB، أصغر بنسبة 32.9%. وقد جرى التعرّف على الملف المعاد بناؤه كـ MotionPhoto وشُغّل على الهاتف. هذا هو مسار خريطة الكسب موثّقًا على عتاد حقيقي، لا مستنتجًا من النموذج المركّب.

ما الحدود؟

ستة تحفظات، تبدأ بالنماذج المركّبة وجهاز واحد.

كيف يمكن إعادة إنتاج هذه الأرقام؟

خمسة أوامر، من npm ci إلى npm run bench.

npm ci
npm run build
npm run bench:fixtures
npm run bench:build
npm run bench

يكتب التشغيل ملف JSON في bench/results/ ويطبع الجدول أعلاه إلى stdout. ومقارنة مستوى PNG هي npm run bench:png-levels. تُتحقَّق النماذج مقابل bench/fixtures/manifest.json قبل تحميل المتصفح لها؛ تغيير أي ملف فشل صريح، وليس خط أساس جديدًا بصمت.

الأسئلة الشائعة

أي صيغة تضغط أكثر؟

AVIF: على الصورة بدقة 12 ميغابكسل أنتج 121.8 KB، أي 2.4% من المدخل، مقابل 6.5% لـ WebP و8.8% لـ JPEG.

أي صيغة ترمّز أسرع؟

JPEG: 677.0 ms للصورة بدقة 12 ميغابكسل، مقابل 997.5 ms لـ WebP و1,983.2 ms لـ AVIF.

لماذا يكون PNG أبطأ لكل ميغابكسل؟

لأنه بلا فقدان: يبحث oxipng عن مرشحات واستراتيجيات DEFLATE لكل بكسل. استغرقت لقطة 2.07 ميغابكسل 296.2 ms/MP بصيغة PNG و73.1 ms/MP بصيغة WebP، أي أقل بـ 4.05 مرة.

هل يضغط MotionPhoto الفيديو؟

لا. يُنسخ الفيديو بايتًا ببايت ويُعاد ترميز الإطار الثابت فقط؛ في النموذج المركّب بدقة 12 ميغابكسل صغر الإطار بنسبة 62.3% والملف كله بنسبة 30.7%، من 9.98 MB إلى 6.92 MB.

ماذا يفعل المستوى 2 مقابل المستوى 3 بحجم ناتج PNG؟

المستوى 3 أصغر لكنه أبطأ بكثير. ملف PNG المسطّح بدقة 1 ميغابكسل هو 62,501 B عند المستوى 2 مقابل 48,138 B عند المستوى 3، أي أكبر بنسبة 29.8%، لكنه يُرمّز في 437.9 ms بدل 2,028.3 ms.

كم مرة يُقاس كل حالة؟

تهيئة واحدة وخمس تشغيلات مقيسة؛ يعرض الجدول وسيط هذه الخمس، وp95 هو أبطأ عينة.

عن هذا المقال

نشرها tinyimg. أدوات القياس ومولّد النماذج وملفات النتائج موجودة في المستودع، والـ JSON الخام لهذا التشغيل يُكتب في bench/results/. التوقيع للمشروع لا لشخص: الادعاء هنا ليس السلطة، بل أن الطريقة مكتوبة والأرقام قابلة لإعادة الإنتاج.

← العودة إلى tinyimg

en · zh-CN · ja · ko · es · fr · ru · ar