برمجة اختيار الموارد باستخدام تعديلات العميل

إيليا غريغوريك

يمنحك إنشاء التطبيقات للويب وصولاً لا مثيل له. سيكون تطبيق الويب الخاص بك على بعد نقرة واحدة، ويتوفر على جميع الهواتف الذكية والأجهزة اللوحية وأجهزة الكمبيوتر المحمولة وسطح المكتب والتلفزيون تقريبًا، بغض النظر عن العلامة التجارية أو النظام الأساسي. لتقديم أفضل تجربة، صمّمت موقعًا إلكترونيًا متجاوبًا يعمل على تعديل العرض التقديمي والوظائف بما يتناسب مع كل شكل من أشكال الأجهزة، والآن يتم إغلاق قائمة التحقّق من الأداء لضمان تحميل التطبيق بأسرع وقت ممكن: لقد حسّنت مسار العرض الحرج، وقمت بضغط مواردك النصية وتخزينها مؤقتًا، وأصبحت الآن تطّلع على موارد الصور التي نقلت معظم وحدات البايت التي تم نقلها إلى حسابك في أغلب الأحيان. المشكلة هي أنّ تحسين الصور صعب:

  • حدد التنسيق المناسب (المتجه مقابل النقطة النقطية)
  • تحديد تنسيقات الترميز المثلى (jpeg وwebp وما إلى ذلك).
  • تحديد إعدادات الضغط الصحيحة (الضغط مع فقدان البيانات مقابل فقدان البيانات)
  • تحديد البيانات الوصفية التي يجب الاحتفاظ بها أو إزالتها
  • إنشاء متغيرات متعددة من كل شاشة + دقة الدقّة الرقمية (DPR)
  • ...
  • مراعاة نوع الشبكة والسرعة والإعدادات المفضّلة للمستخدم

بشكل فردي، تشكّل هذه المشاكل مشاكل واضحة. ومعًا، يتم إنشاء مساحة تحسين كبيرة نغفلها نحن (المطورون) غالبًا أو نتجاهلها. يقوم البشر بعمل ضعيف في استكشاف مساحة البحث نفسها بشكل متكرر، خاصةً عندما يتعلق الأمر بالعديد من الخطوات. من ناحية أخرى، تتفوق أجهزة الكمبيوتر في هذه الأنواع من المهام.

الإجابة عن استراتيجية تحسين جيدة ومستدامة للصور والموارد الأخرى التي لها خصائص مشابهة هي ببساطة إجابة مبرمَجة. إذا كنت توليف مواردك يدويًا، هذا يعني أنها خطأ، فستنسى أو ستشعر بالكسل، وإلا سيرتكب أحد غيرك هذا الخطأ مضمونًا.

القصة الملحمية لمطوّري البرامج الشغوفين بالأداء

يشتمل البحث من خلال مساحة تحسين الصور على مرحلتين مختلفتين: وقت الإنشاء ووقت التشغيل.

  • إنّ بعض التحسينات مرتبطة بالمورد نفسه، مثلاً اختيار التنسيق ونوع الترميز المناسبَين، وضبط إعدادات الضغط لكل برنامج ترميز، وإزالة البيانات الوصفية غير الضرورية، وما إلى ذلك. يمكن تنفيذ هذه الخطوات في "وقت الإنشاء".
  • ويتم تحديد التحسينات الأخرى حسب نوع العميل الذي يطلبه وخصائصه، ويجب إجراؤها في "وقت التشغيل": اختيار المورد المناسب لنسخة DPR الخاصة بالعميل وعرض العرض المقصود، مع مراعاة سرعة شبكة العميل، وتفضيلات المستخدم والتطبيق، وما إلى ذلك.

أدوات وقت الإنشاء موجودة ولكن يمكن تحسينها. على سبيل المثال، يمكن تحقيق قدر كبير من التوفير من خلال ضبط إعداد "الجودة" ديناميكيًا لكل صورة وكل تنسيق صورة، ولكن لم أجد حتى الآن أي شخص يستخدمها خارج إطار البحث. إنه مجال جاهز للابتكار، ولكن لأغراض هذه المقالة، سأترك الأمر عنده. لنركّز على الجزء المتعلق بوقت التشغيل من القصة.

<img src="/image/thing" sizes="50vw"
        alt="image thing displayed at 50% of viewport width">

إنّ الغرض من التطبيق بسيط جدًا: استرجاع الصورة وعرضها بنسبة% 50 من إطار العرض الخاص بالمستخدم. هذا هو المكان الذي يغسل فيه معظم المصممين أيديهم ورؤوسهم للوصول إلى البار. في غضون ذلك، يعمل المطور الوعي بالأداء في الفريق لليلة طويلة:

  1. للحصول على أفضل ضغط، تريد أن تستخدم تنسيق الصورة الأمثل لكل عميل: WebP في Chrome وJPEG XR لـ Edge وJPEG إلى الباقي.
  2. للحصول على أفضل جودة مرئية، تحتاج إلى إنشاء متغيرات متعددة لكل صورة بدرجات دقة مختلفة: 1x، و1.5x، و2x، و2.5x، و3x، وربما عدد قليل من الصور في المنتصف.
  3. ولتجنب عرض وحدات بكسل غير ضرورية، تحتاج إلى فهم ما تعنيه عبارة "50٪ من إطار العرض للمستخدم في الواقع"، أن هناك الكثير من طرق العرض المختلفة لإطار العرض!
  4. بشكل مثالي، تريد أيضًا تقديم تجربة مرنة حيث يجلب المستخدمون على الشبكات البطيئة دقة أقل تلقائيًا. بعد كل شيء، حان وقت العمل بالزجاج.
  5. يعرض التطبيق أيضًا بعض عناصر التحكم التي تؤثر في موارد الصور التي يجب جلبها، لذلك هناك عوامل يجب أخذها في الاعتبار أيضًا.

أوه، ثم تدرك المصممة أنها بحاجة إلى عرض صورة مختلفة بعرض 100٪ إذا كان حجم إطار العرض صغيرًا لتحسين الوضوح. يعني ذلك أنّه علينا الآن تكرار العملية نفسها لمادة عرض أخرى، ثم جعل الجلب مشروطًا على حجم إطار العرض. هل ذكرت أن هذه الأمور صعبة؟ حسنًا، دعنا نتناولها. العنصر picture سينقلنا إلى أقصى حد:

<picture>
    <!-- serve WebP to Chrome and Opera -->
    <source
    media="(min-width: 50em)"
    sizes="50vw"
    srcset="/image/thing-200.webp 200w, /image/thing-400.webp 400w,
        /image/thing-800.webp 800w, /image/thing-1200.webp 1200w,
        /image/thing-1600.webp 1600w, /image/thing-2000.webp 2000w"
    type="image/webp">
    <source
    sizes="(min-width: 30em) 100vw"
    srcset="/image/thing-crop-200.webp 200w, /image/thing-crop-400.webp 400w,
        /image/thing-crop-800.webp 800w, /image/thing-crop-1200.webp 1200w,
        /image/thing-crop-1600.webp 1600w, /image/thing-crop-2000.webp 2000w"
    type="image/webp">
    <!-- serve JPEGXR to Edge -->
    <source
    media="(min-width: 50em)"
    sizes="50vw"
    srcset="/image/thing-200.jpgxr 200w, /image/thing-400.jpgxr 400w,
        /image/thing-800.jpgxr 800w, /image/thing-1200.jpgxr 1200w,
        /image/thing-1600.jpgxr 1600w, /image/thing-2000.jpgxr 2000w"
    type="image/vnd.ms-photo">
    <source
    sizes="(min-width: 30em) 100vw"
    srcset="/image/thing-crop-200.jpgxr 200w, /image/thing-crop-400.jpgxr 400w,
        /image/thing-crop-800.jpgxr 800w, /image/thing-crop-1200.jpgxr 1200w,
        /image/thing-crop-1600.jpgxr 1600w, /image/thing-crop-2000.jpgxr 2000w"
    type="image/vnd.ms-photo">
    <!-- serve JPEG to others -->
    <source
    media="(min-width: 50em)"
    sizes="50vw"
    srcset="/image/thing-200.jpg 200w, /image/thing-400.jpg 400w,
        /image/thing-800.jpg 800w, /image/thing-1200.jpg 1200w,
        /image/thing-1600.jpg 1600w, /image/thing-2000.jpg 2000w">
    <source
    sizes="(min-width: 30em) 100vw"
    srcset="/image/thing-crop-200.jpg 200w, /image/thing-crop-400.jpg 400w,
        /image/thing-crop-800.jpg 800w, /image/thing-crop-1200.jpg 1200w,
        /image/thing-crop-1600.jpg 1600w, /image/thing-crop-2000.jpg 2000w">
    <!-- fallback for browsers that don't support picture -->
    <img src="/image/thing.jpg" width="50%">
</picture>

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

للأسف، لا يتيح لنا العنصر picture تحديد أي قواعد السلوك الذي يجب أن يعمل به استنادًا إلى نوع الاتصال لدى العميل أو سرعته. ومع ذلك، فإنّ خوارزمية المعالجة تسمح لوكيل المستخدم بتعديل المورد الذي يجلبه في بعض الحالات. اطّلِع على الخطوة 5. علينا فقط أن نأمل أن يكون وكيل المستخدم ذكيًا بما يكفي. (ملاحظة: ليس هناك أيّ من عمليات التنفيذ الحالية). وبالمثل، لا تتوفر عناصر جذب في العنصر picture للسماح بمنطق خاص بالتطبيق يراعي إعدادات التطبيق أو المستخدم المفضّلة. للحصول على هاتين البتتين الأخيرتين، يجب نقل كل المنطق المذكور أعلاه إلى JavaScript، ولكن هذا بدون تحسينات ماسح التحميل المسبق التي يوفرها picture. حسنًا،

بغض النظر عن هذه القيود، فهي تعمل. حسنًا، على الأقل لهذا الأصل المحدد. يتمثل التحدي الحقيقي والطويل المدى هنا في أننا لا نتوقع أن يصمم المصمم أو المطوّر رموزًا برمجية مثل هذه يدويًا لكل أصل. إنه لغز ممتع ذهني من المحاولة الأولى، لكنه يفقد جاذبيته بعد ذلك مباشرة. نحتاج إلى التشغيل الآلي. ربما يمكن لـ IDE أو أدوات تحويل المحتوى الأخرى أن تنقذنا وتنشئ النموذج النموذجي أعلاه تلقائيًا.

أتمتة اختيار الموارد مع تعديلات العميل

خذ نفسًا عميقًا وعلق عدم تصديقك وفكر الآن في المثال التالي:

<meta http-equiv="Accept-CH" content="DPR, Viewport-Width, Width">
...
<picture>
    <source media="(min-width: 50em)" sizes="50vw" srcset="/image/thing">
    <img sizes="100vw" src="/image/thing-crop">
</picture>

في ما يتعلّق بالمثال أعلاه، يكفي أن يوفّر كل الإمكانات نفسها المتوفّرة في ترميز الصور الأطول أعلاه، كما أنّه يتيح للمطوّرين، كما سنوضّح، إمكانية تحكُّم كاملة في كيفية جلب موارد الصور ووقت جلبها. يكون النص "السحري" في السطر الأول يتيح إعداد تقارير تلميحات العميل ويطلب من المتصفح الإعلان عن نسبة وحدات البكسل للجهاز (DPR) وعرض إطار عرض التنسيق (Viewport-Width) وعرض العرض المقصود (Width) للموارد المرسَلة إلى الخادم.

عند تفعيل "تلميحات العميل"، يحتفظ الترميز الناتج من جهة العميل بمتطلبات العرض التقديمي فقط. لا يضطر المصمم إلى القلق بشأن أنواع الصور أو درجات دقة العميل أو نقاط التوقف المثالية لتقليل وحدات البايت التي يتم تسليمها أو معايير اختيار الموارد الأخرى. دعونا نواجه الأمر، إنه لم يحدث من قبل، ولا ينبغي عليهم ذلك. والأفضل من ذلك أنّ مطوّر البرامج لن يحتاج أيضًا إلى إعادة كتابة الترميز أعلاه وتوسيعه لأنّ العميل والخادم يتفاوضان بشأن الاختيار الفعلي للموارد.

يوفّر Chrome 46 توافقًا أصليًا مع التلميحات DPR وWidth وViewport-Width. يتم إيقاف التلميحات تلقائيًا، ويعمل <meta http-equiv="Accept-CH" content="..."> أعلاه كإشارة موافقة تطلب من Chrome إلحاق العناوين المحدّدة بالطلبات الصادرة. بعد تنفيذ ذلك، لنفحص عناوين الطلبات والاستجابة الخاصة بنموذج لطلب صورة:

مخطط تفاوض لتلميحات العميل

يعلن Chrome عن دعمه لتنسيق WebP من خلال العنوان "قبول الطلب"، وبالمثل، يعلن متصفّح Edge الجديد عن دعم JPEG XR عبر العنوان "قبول".

عناوين الطلبات الثلاثة التالية هي عناوين تلميحات العميل التي تعلن عن نسبة وحدات البكسل في جهاز جهاز العميل (3x)، وعرض إطار عرض التنسيق (460 بكسل)، وعرض العرض المقصود للمورد (230 بكسل). يوفر هذا الإجراء جميع المعلومات الضرورية للخادم لتحديد الصورة المثلى وفقًا لمجموعته الخاصة من السياسات، وهي: مدى توفّر الموارد التي تم إنشاؤها مسبقًا، وتكلفة إعادة الترميز أو تغيير حجم المورد، وشعبية المورد، وتحميل الخادم الحالي، وما إلى ذلك. في هذه الحالة على وجه الخصوص، يستخدم الخادم التلميحات DPR وWidth ويعرض مورد WebP، كما هو موضّح في العناوين Content-Type وContent-DPR وVary.

ليس هناك سحر هنا. لقد نقلنا اختيار الموارد من ترميز HTML إلى مفاوضات استجابة الطلب بين العميل والخادم. نتيجةً لذلك، لا يهتم HTML إلا بمتطلبات العرض التقديمي وهو أمر يمكننا الوثوق به في كتابة أي مصمم ومطوّر، بينما يتم تأجيل البحث من خلال مساحة تحسين الصور إلى أجهزة الكمبيوتر وأصبح الآن مُبرمَجًا بسهولة على نطاق واسع. هل تذكر مطوّرنا الوعي بالأداء؟ تكمن مهمتها الآن في كتابة خدمة صور يمكنها الاستفادة من التلميحات المقدَّمة وعرض الرد المناسب: يمكنها استخدام أي لغة أو خادم تريده، أو السماح لخدمة طرف ثالث أو شبكة توصيل للمحتوى بالقيام بذلك نيابةً عنها.

<img src="/image/thing" sizes="50vw"
        alt="image thing displayed at 50% of viewport width">

هل تذكر أيضًا هذا الرجل المذكور أعلاه؟ باستخدام تلميحات من العميل، أصبحت علامات الصورة المتواضعة الآن DPR وإطار العرض وزيادة العرض DPR بدون أي ترميز إضافي. إذا كنت بحاجة إلى إضافة اتجاه فني، يمكنك استخدام العلامة picture كما هو موضّح أعلاه، وإلا أصبحت جميع علامات الصور الحالية أكثر ذكاءً. تحسّن تلميحات العميل عناصر img وpicture الحالية.

التحكّم في اختيار الموارد مع مشغّل الخدمات

ServiceWorkers هو في الواقع خادم وكيل من جهة العميل يعمل في متصفحك. يعترض جميع الطلبات الصادرة ويسمح لك بفحص الردود وإعادة كتابتها وتخزينها مؤقتًا وتجميعها/توليفها. والأمر نفسه ينطبق على الصور، ومن خلال تفعيل تلميحات العميل، يمكن لـ ServiceWorker النشط التعرّف على طلبات الصور وفحص تلميحات العميل المُقدَّمة وتحديد منطق المعالجة الخاصة به.

self.onfetch = function(event) {
    var req = event.request.clone();
    console.log("SW received request for: " + req.url)
    for (var entry of req.headers.entries()) {
    console.log("\t" + entry[0] +": " + entry[1])
    }
    ...
}
خدمة نصائح العميل.

يمنحك ServiceWorkers تحكمًا كاملاً من جهة العميل في اختيار الموارد. يعد ذلك أمرًا بالغ الأهمية. دع هذا يتعمق، لأن الاحتمالات لا حصر لها تقريبًا:

  • يمكنك إعادة كتابة قيم العنوان التي حدّدها وكيل المستخدم لتلميحات العميل.
  • يمكنك إلحاق قيم رؤوس تلميحات العملاء الجدد بالطلب.
  • يمكنك إعادة كتابة عنوان URL وتوجيه طلب الصورة إلى خادم بديل (مثل شبكة توصيل المحتوى (CDN)).
    • ويمكنك أيضًا نقل قيم التلميح من العناوين إلى عنوان URL نفسه إذا كان ذلك يسهِّل نشر العناصر في بنيتك الأساسية.
  • يمكنك تخزين الردود مؤقتًا وتحديد منطق خاص للموارد التي يتم عرضها.
  • يمكنك تعديل ردّك بناءً على إمكانية اتصال المستخدمين.
  • يمكنك مراعاة عمليات إلغاء الإعدادات المفضّلة للتطبيقات والمستخدمين.
  • يمكنك فعل أي شيء تريده قلبك.

يوفّر العنصر picture عنصر التحكّم اللازم في الاتجاه الفني في ترميز HTML. تقدّم تلميحات العميل تعليقات توضيحية حول طلبات الصور الناتجة التي تتيح إمكانية التشغيل الآلي لاختيار الموارد. يوفر ServiceWorker إمكانات إدارة الطلبات والاستجابة على العميل. هذا هو الويب العملي القابل للتوسُّع.

الأسئلة الشائعة حول تلميحات العميل

  1. أين تتوفّر تلميحات العملاء؟ تم الشحن في Chrome 46. قيد المراجعة في Firefox وEdge.

  2. لماذا يوافق العميل على تلميحات الاقتراحات؟ ونريد خفض النفقات العامة للمواقع الإلكترونية التي لن تستخدم تعديلات العملاء. لتفعيل تلميحات العميل، يجب أن يقدّم الموقع الإلكتروني العنوان Accept-CH أو التوجيه <meta http-equiv> المكافئ في ترميز الصفحة. عند توفّر أي منهما، سيُلحق وكيل المستخدم التلميحات المناسبة في جميع طلبات الموارد الفرعية. وقد نوفّر في المستقبل آلية إضافية للحفاظ على هذا التفضيل لمصدر معيّن، ما سيسمح بتقديم التلميحات نفسها بشأن طلبات التنقل.

  3. لماذا نحتاج إلى تلميحات العميل إذا كان لدينا ServiceWorker؟ لا يمكن لـ ServiceWorkers الوصول إلى معلومات التنسيق والموارد وعرض إطار العرض. على الأقل، لن يتم ذلك بدون تقديم رحلات ذهاب وعودة مكلفة وتأخير طلب الصورة بشكل كبير، على سبيل المثال، عند بدء طلب صورة بواسطة المحلل اللغوي للتحميل المسبق. تتكامل تلميحات العميل مع المتصفح لإتاحة هذه البيانات كجزء من الطلب.

  4. هل تتوفر تعديلات للعملاء في ما يتعلّق بموارد الصور فقط؟ تتمثل حالة الاستخدام الأساسية وراء تلميحات DPR وعرض إطار العرض والعرض وتلميحات في تفعيل إمكانية اختيار الموارد لمواد عرض الصور. ومع ذلك، يتم تقديم التلميحات نفسها لجميع الموارد الفرعية بغض النظر عن نوعها، مثلاً تحصل طلبات CSS وJavaScript على المعلومات نفسها ويمكن استخدامهما لتحسين هذه الموارد أيضًا.

  5. بعض طلبات الصور لا تُبلغ عن العرض، لماذا؟ قد لا يعرف المتصفّح عرض العرض المقصود لأنّ الموقع الإلكتروني يعتمد على الحجم الأساسي للصورة. ونتيجةً لذلك، يتم حذف تلميح العرض لهذه الطلبات والطلبات التي لا تحتوي على "عرض العرض"، مثل مورد JavaScript. لتلقّي تلميحات عن العرض، احرص على تحديد قيمة الحجم في صورك.

  6. ماذا عن <insert my favorite hint>؟ تمكّن ServiceWorker المطوّرين من اعتراض جميع الطلبات الصادرة وتعديلها (مثل إضافة رؤوس جديدة). على سبيل المثال، من السهل إضافة معلومات تستند إلى NetInfo لتوضيح نوع الاتصال الحالي. راجع "Capability Reporting with ServiceWorker". يتم تنفيذ التلميحات "الأصلية" التي يتم شحنها في Chrome (DPR، العرض، عرض المورد) في المتصفح لأن التنفيذ المستند إلى حالة الخادم (SW) البحتة من شأنه أن يؤخر جميع طلبات الصور.

  7. أين يمكنني الاطّلاع على المزيد من المعلومات والاطّلاع على المزيد من العروض التوضيحية وماذا عن؟ يُرجى الاطّلاع على مستند الشرح ويمكنك فتح أي مشكلة على GitHub إذا كانت لديك ملاحظات أو أسئلة أخرى.