مواجهة أداء تأثيرات صورة الويب
نشرت: 2022-03-10نظرًا لأن المتصفحات تعمل باستمرار على تحسين قدراتها في العرض الرسومي ، فإن القدرة على التصميم حقًا داخلها أصبحت حقيقة واقعة. يمكن أن يكون لبضعة أسطر من التعليمات البرمجية الآن تأثير مرئي سريع ورائع ، وتسمح بالاتساق دون بذل الكثير من الجهد . وكما هو الحال مع معظم الأشياء في تطوير الويب ، غالبًا ما توجد طرق عديدة لتحقيق نفس التأثير.
في هذا المنشور ، سنلقي نظرة على أحد أكثر تأثيرات الصور شيوعًا ، التدرج الرمادي ، ونقيم سهولة التنفيذ وتأثيرات الأداء في لوحة HTML ، ومرشحات SVG ، و CSS ، وأوضاع مزج CSS. أي واحد سيفوز؟
مزيد من القراءة على SmashingMag:
- مواجهة أداء تأثيرات صورة الويب
- HTML5: الحقائق والأساطير
- تغيير حجم الصورة بكفاءة باستخدام ImageMagick
- تقنيات تحسين JPEG الذكية
تعمل المرشحات على الويب مثل العدسة الموضوعة فوق صورة. يتم تطبيقها على الصورة بعد أن يعرض المتصفح التخطيط والطلاء الأولي. في المتصفحات الداعمة ، يمكن تطبيق المرشحات بشكل فردي أو طبقات فوق بعضها البعض. نظرًا لأنه يمكن تطبيقها كتعديلات على الصورة بعد العرض الأولي ، ومن المحتمل أن تكون تحسينًا ، فإن المرشحات تتدهور بأمان بمجرد عدم رؤيتها في المتصفحات التي لا تدعمها.
مرشحات CSS
لنبدأ بالطريقة الأكثر مباشرة لإنتاج تأثير التدرج الرمادي: مرشح CSS المتواضع والقوي.

لتحقيق هذا التأثير ، نضيف سطرًا واحدًا من CSS: filter: grayscale(1)
. يعمل هذا المرشح على إزالة تشبع الصورة ويمكن استخدامه مع أي قيمة رقمية أو قائمة على النسبة المئوية بين 0 و 1 (أو 0٪ إلى 100٪). ملاحظة: في الوقت الحالي ، يجب أن تبدأ عوامل تصفية المتصفحات القائمة على WebKit بـ -webkit-
. ومع ذلك ، فإن حلًا مثل Autoprefixer من شأنه أن يلغي الحاجة إلى إضافتها يدويًا.
عرض حي - مرشح CSS
.cssfilter-gray { -webkit-filter: grayscale(1); background: url('img/bird.jpg'); filter: grayscale(1); }
وضع مزج الخلفية
توفر أوضاع المزج CSS مجموعة متنوعة لا حصر لها من الخيارات لمجموعات تأثيرات الصورة. هناك طريقتان لاستخدام أوضاع المزج: خاصية mix-blend-mode
وخاصية وضع background-blend-mode
.
-
mix-blend-mode
هي الخاصية التي تصف كيفية مزج العنصر مع المحتوى الموجود خلفه. - يُستخدم
background-blend-mode
للعناصر ذات الخلفيات المتعددة ، ويصف العلاقة بين هذه الخلفيات.
سنستخدم background-blend-mode: luminosity
لسحب قنوات اللمعان على خلفية رمادية في مثالنا ، مما ينتج عنه صورة ذات تدرج رمادي. شيء واحد يجب ملاحظته هو أن ترتيب الخلفية ثابت: يجب دائمًا ترتيب صور الخلفية قبل الألوان الصلبة أو الخلفيات المتدرجة حتى يتم عرض التأثيرات بشكل صحيح . يجب أن يكون اللون هو آخر طبقة خلفية. هذا أيضًا حماية ضد المتصفحات القديمة التي لا تدعم background-blend-mode
- ستستمر الصورة بدون التأثير.
الاختلاف الوحيد بين أوضاع المزج وفلتر CSS هو أننا نمتلك الآن خلفيات متعددة ، ونستخدم background-blend-mode: luminosity
، الذي يستحوذ على قيم اللمعان من الصورة العلوية (جهاز اختبار الطيور) ويضع قيم السطوع هذه فوق الخلفية الرمادية الثانية.
عرض حي - وضع مزيج الخلفية
.cssfilter-gray { background: url('img/bird.jpg'), gray; background-blend-mode: luminosity; }
في الوقت الحالي ، يعد هذا هو الخيار الأحدث وبالتالي الأقل دعمًا ، على الرغم من أنه لا يزال يعمل بشكل جيد في Chrome و Firefox ، ولديه دعم Safari الجزئي. ملاحظة: يدعم Safari جميع أوضاع المزج باستثناء أوضاع المزج المستندة إلى HSL: تدرج اللون والتشبع واللون والسطوع.
قماش HTML5
يتيح HTML5 <canvas>
قدرًا كبيرًا من المرونة عندما يتعلق الأمر بمعالجة الصور ، لأن لدينا إمكانية الوصول إلى بيانات كل بكسل فردي (على وجه التحديد من خلال canvasContext.getImageData
) ويمكننا معالجة كل واحدة من خلال JavaScript. ومع ذلك ، فإن هذه الطريقة هي الأكثر تعقيدًا وتأتي مع أكثر من غيرها. كما أن لديها بعض الفروق الدقيقة في القضايا متعددة المصادر بسبب مخاوف أمنية.
لإصلاح خطأ المصدر المشترك في Chrome ، ستحتاج صورتك إلى الاستضافة على موقع سهل الاستخدام لمشاركة المصادر متعددة المصادر (CORS) مثل GitHub Pages أو Dropbox ، وتحديد crossOrigin="Anonymous"
. انظر المثال الحي لمظاهرة.

تتمثل طريقة تحقيق تأثير التدرج الرمادي باستخدام <canvas>
في تجريد المكونات الحمراء والخضراء والزرقاء من أي قيمة نائية في قيمة البكسل مع الحفاظ على مستوى لمعانها (السطوع). تتمثل إحدى طرق القيام بذلك في حساب متوسط قيم RGB مثل: grayscale = (red + green + blue) / 3;
.
في المثال أدناه ، نستخدم قيم RGBa بالتنسيق (R,G,B,a)
في بيانات الصورة ؛ القناة الحمراء عبارة data[0]
والقناة الخضراء data[1]
وهكذا. نحصل بعد ذلك على مستوى اللمعان لكل من هذه القنوات (السطوع) ومتوسطها لتحويل الصورة إلى التدرج الرمادي.
عرض حي - HTML5 Canvas
مرشح SVG
تتمتع مرشحات SVG بأوسع دعم (حتى في Internet Explorer و Edge!) وهي أيضًا (تقريبًا) سهلة الاستخدام مثل عوامل تصفية CSS مباشرة. يمكنك استخدامها مع نفس خاصية filter
. في الواقع ، انبثقت مرشحات CSS من مرشحات SVG. كما هو الحال مع لوحة الرسم ، تتيح لك مرشحات SVG تجاوز المستوى المسطح للتأثيرات ثنائية الأبعاد ، حيث يمكنك الاستفادة من تظليل WebGL لإنشاء نتائج أكثر تعقيدًا.
هناك عدة طرق لتطبيق مرشح SVG ، ولكن في هذه الحالة سنستمر في استخدام خاصية filter
في صورة الخلفية ، تمامًا مثل مثال مرشح CSS من أجل التناسق. يتمثل الاختلاف الأكبر مع مرشحات SVG في أننا بحاجة إلى توخي الحذر لتضمين هذا المرشح وربطه بالمسار الصحيح. هذا يعني أننا بحاجة إلى استيراد SVG على الصفحة أعلى العنصر الذي نستخدمه فيه (والذي يمكن جعله أسهل باستخدام محرك القوالب وتضمين العبارات).
عرض حي - مرشح SVG
<svg> <filter> <feColorMatrix type="saturate" values="0"/> </filter> </svg>
.svgfilter-gray { background: url('img/bird.jpg'); -webkit-filter: url(#grayscale-filter); filter: url(#grayscale-filter); }
أداء المرشح
إذن كيف تتراكم هذه عندما يتعلق الأمر بأداء التصيير الأولي؟ لقد أنشأت صفحة اختبار لكل منها واستخدمت ميزة مقارنة WebPagetest في Chrome 47. مع الأخذ في الاعتبار أن كل اختبار أعطى نتائج مختلفة قليلاً ، يمكن تلخيص الاتجاه العام على النحو التالي:
تم تحميل طرق وضع مزيج CSS و مرشح SVG و مرشح CSS في إطارات زمنية متشابهة نسبيًا. في بعض الأحيان ، كان مرشح SVG أسرع من وضع المزج CSS (ولكن بالكاد دائمًا) والعكس صحيح. كان مرشح CSS عمومًا من بين الأسرع في التحميل ، وكان <canvas>
دائمًا الأبطأ. هذه هي أهم فكرة تم الحصول عليها. كان <canvas>
متخلفًا بشكل منتظم عن الطرق الأخرى في عرض الصورة.
من أجل الإنصاف ، أردت أيضًا مقارنة وقت تحميل صور متعددة. لقد أنشأت عشرة عمليات نقل لكل منها (بدلاً من واحدة فقط) وقمت بإجراء الاختبارات مرة أخرى:
كانت النتائج متشابهة (ضع في اعتبارك أن هناك اختلافات طفيفة في كل اختبار). كان مرشح CSS أبطأ بمقدار 0.1 مللي ثانية في هذه الحالة ، مما يوضح أنه بين مرشحات CSS وأوضاع المزج ومرشحات SVG ، فإن النتائج غير حاسمة بالنسبة لأسرع طريقة. ومع ذلك ، تأخر HTML5 <canvas>
بشكل ملحوظ بالمقارنة.
بإلقاء نظرة أعمق على وقت تحميل الصفحة عبر عرض JavaScript ووقت عرض الطلاء ، يمكنك رؤية استمرار هذا الاتجاه.

نوع فلتر | حان وقت التقديم | حان وقت الرسم |
---|---|---|
مرشح CSS | 12.94 مللي ثانية | 4.28 مللي ثانية |
وضع المزج CSS | 12.10 مللي ثانية | 4.45 مللي ثانية |
مرشح SVG | 14.77 مللي ثانية | 5.80 مللي ثانية |
مرشح قماش | 15.23 مللي ثانية | 10.73 مللي ثانية |
مرة أخرى ، استغرق <canvas>
وقتًا أطول للعرض وأطول وقت للطلاء ، بينما كان خياري CSS هما الأسرع ، وجاء SVG في المنتصف.
هذه النتائج منطقية ، لأن <canvas>
يأخذ كل بكسل فرديًا ويقوم بإجراء عملية عليه قبل أن نتمكن من رؤية أي صورة على الإطلاق. يتطلب هذا قدرًا كبيرًا من قوة المعالجة في وقت العرض. بينما تُستخدم صور SVG عادةً للرسومات المتجهة ، ما زلت أوصي بها بشدة فوق <canvas>
عند التعامل مع تأثيرات الصور النقطية. لا يعتبر SVG أسرع فحسب ، بل إنه أسهل بكثير في التعامل معه وأكثر مرونة داخل DOM. بشكل عام ، تكون عوامل تصفية CSS أكثر تحسينًا من مرشحات SVG ، حيث إنها تاريخياً اختصارات ناشئة عن مرشحات SVG ، وبالتالي فهي محسّنة في المتصفحات.
# فلتر
ماذا عن عدم استخدام مرشح؟ لقد قارنت أسرع طريقة عامة لدينا (إضافة عامل تصفية CSS) لتحرير صورتك في برنامج تحرير الصور قبل تحميلها (لقد استخدمت Preview على نظام التشغيل Mac OS X لإزالة التشبع). عند تحرير الصورة ، وجدت تحسنًا ثابتًا في أداء 0.1 مللي ثانية في اختباراتي:
خاتمة
تعد مرشحات الصور طريقة ممتعة وفعالة لتوفير وحدة بصرية وجاذبية جمالية على الويب. ضع في اعتبارك أنها تأتي مع أداء طفيف ، ولكن أيضًا مع مزايا التصميم السريع في المتصفح وفرصة تصميم التفاعلات معها.
لتأثيرات الصور البسيطة ، استخدم مرشحات CSS ، لأنها تتمتع بأوسع دعم وأبسط استخدام. للحصول على تأثيرات صور أكثر تعقيدًا ، تحقق من مرشحات SVG أو أوضاع مزج CSS. تعد تأثيرات مرشح SVG رائعة بشكل خاص بسبب إمكانيات معالجة القنوات و feColorMatrix
. توفر أوضاع المزج CSS أيضًا بعض التأثيرات المرئية الرائعة مع العناصر المتداخلة على الصفحة. يمكنك استخدام أوضاع مزج مماثلة داخل SVG (مثل feBlend
) ، على الرغم من أنها تشبه background-blend-mode
في CSS بمعنى أن التفاعل يتعلق بـ SVG نفسه وليس مع العناصر المحيطة ، مثل يسمح mix-blend-mode
. فقط لا تستخدم <canvas>
للفلاتر.