تأجيل جافاسكريبت وعرض محتوى مؤقت عند تحميل الصفحة الأولي

ماذا عن: تأجيل جافاسكريبت Discourse

أضف سمات defer إلى جميع ملفات جافاسكريبت إن أمكن. تأجيل تحميل وتنفيذ جافاسكريبت يسمح للمتصفح ببدء تحليل HTML وعرضه ورسمه.

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

أفكار للمحتوى المؤقت الثابت:

  • شاشة ترحيب بالشعار ودائرة تحميل
  • عرض الموضوع مع مشاركات من الواجهة الخلفية

إثبات المفهوم وطلب السحب (POC and PR)

لأحدث إثبات للمفهوم وطلب السحب - يرجى الاطلاع على هذا المنشور.


ملفات جافاسكريبت المورد (vendor-javascript) وجميع ملفات جافاسكريبت السابقة لا يتم تأجيلها حاليًا.
@انظر: https://github.com/rr-it/discourse/commit/328efd5c055f5f2a4d93b5e52268cfe92913faf7

نرحب جدًا بالأفكار حول كيفية حل هذا.


تحميل جافاسكريبت: async مقابل defer مقابل لا شيء

المزيد حول خيارات تحميل جافاسكريبت - بما في ذلك defer: Efficiently load JavaScript with defer and async
(هذا ليس حول تسريع تشغيل Discourse الفعلي.)


Fastboot/إعادة الترطيب

قرأت هذا المقال:
يبدو أن الاستنتاج هناك هو تطبيق Fastboot/إعادة الترطيب.
هل هناك جدول زمني لهذا؟

4 إعجابات

سيؤدي ذلك إلى بقاء LCP بعد تمهيد EmberJS وإعادة عرضه، مما لا يعالج المشكلة الرئيسية المتعلقة بتصنيفات Google الجديدة.

هذه هي خطتنا الحالية متوسطة المدى لمعالجة LCP في Discourse.

إعجابَين (2)

اعتبارًا من Chrome 88، لم يعد هذا صحيحًا لحسن الحظ! :rocket:
لم أكن أعرف بهذا الأمر حتى الآن. :))

“قبل هذا التغيير، كان إزالة عنصر ما يتسبب في عدم اعتباره مرشحًا صالحًا لـ LCP. […] بعد هذا التغيير، لا يزال العنصر الذي تمت إزالته يعتبر مرشحًا صالحًا لـ LCP.”

“سيؤدي التغيير لتضمين المحتوى الذي تمت إزالته لاحقًا من DOM كأكبر طلاء محتوى محتمل إلى تحسين أوقات أكبر طلاء محتوى للمواقع التي تحتوي على صور [لـ Discourse: عناصر نصية] بنفس الحجم يتم إدراجها عدة مرات. هذا نمط شائع للكاروسيلات، بالإضافة إلى بعض أطر عمل JavaScript التي تقوم بـ العرض من جانب الخادم.”


سجل تغييرات LCP

قد تكون هناك تغييرات جيدة أخرى في المستقبل:

إعجاب واحد (1)

فيما يلي بعض الإحصائيات المحاكاة لصفحة موضوع مع تطبيق POC.

Lighthouse: “القيم تقديرية وقد تختلف.”

WebPageTest

webpagetest.org

محاكاة Moto4G


ملاحظة: نحن السهم الأسود في الأعلى.


ملاحظات:

  • 0 ثوانٍ - ثانيتان - شاشة فارغة:
    يتجاهل WebPageTest defer لـ JavaScript ويقوم بتنزيل جميع نصوص JavaScript البرمجية قبل إجراء أول رسم - وهذا يعمل بشكل صحيح على جهاز حقيقي.
  • 2.5 ثانية - LCP: محتوى ثابت من عرض الخادم
  • 3.5 ثوانٍ - تغيير مرئي: تم تحميل الشعار
  • 6.5 ثوانٍ - تغيير مرئي: محتوى من عرض EmberJs
  • 7 ثوانٍ - اكتمال مرئي

PageSpeed Insights

عنصر أكبر رسم محتوى (Largest Contentful Paint)

يحدد PageSpeed بشكل صحيح عقدة النص الثابتة من عرض الخادم كعنصر FCP LCP:
div.row > div.topic-body > div.post > p

عقدة النص المعروضة بواسطة EmberJs:
div.row > div.topic-body > div.regular.contents > div.cooked > p

ولكن يبدو أن PageSpeed لا يستخدم عقدة النص الثابتة المحددة بشكل صحيح لنتيجته المحاكاة: FCP و LCP المحاكاة كبيران جدًا.

بيانات المستخدم الحقيقية

دعنا ننتظر 14-28 يومًا أخرى للحصول على بيانات “حقيقية” من Chrome UX Report مع تطبيق POC.

إحصائيات بدون تطبيق POC لصفحة الموضوع المختبرة:
(البيانات تخص عنوان URL للموضوع هذا فقط - وليست للمنشأ بأكمله.)

4 إعجابات

يا له من اكتشاف مثير للاهتمام! عمل رائع!

ما الذي تحصل عليه مع هذا الامتداد https://chrome.google.com/webstore/detail/web-vitals/ahfhijdlegdabablpippeagghigmibma؟

3 إعجابات

عبر امتداد Web Vitals Chrome

  • على سطح المكتب
  • إصدار Chromium 90.0.4430.212
  • التحميل الأول في نافذة تصفح متخفي جديدة


ملاحظة حول تأخير الإدخال الأول: انتظرت حتى تم تحميل الصفحة بالكامل ثم نقرت على الخلفية - أي بعد انتهاء عرض EmberJs.


ملاحظة حول تأخير الإدخال الأول: هنا نقرت على الخلفية فور ظهور المحتوى الثابت لأول مرة. أضف وقت رد فعلي :sloth: فوق هذا التأخير في الإدخال الأول.

ملاحظة إضافية حول النسب المئوية أسفل الأشرطة في هذه الرسوم البيانية:
النسب المئوية ليست ذات صلة كبيرة لأنها تقارن فقط القيم المقاسة بالقيم الأصلية. الأصل هو صفحة ويب TYPO3 مع تثبيت مجلد فرعي لـ Discourse.

إعجابَين (2)

فكرة رائعة! @rrit

أتفق تمامًا أن Discourse هو تطبيق ويب بطيء جدًا وثقيل على JavaScript، إذا كان بإمكاننا تأجيل ملفات CSS/JS، فسيساعد ذلك بشكل كبير في تسريع LCP و FCP و FID و CLS.

سيساعد حقًا رؤية هذا الأمر يتم تطبيقه، فنحن والعديد من الأشخاص الآخرين نواجه هذه المشكلة. جميع مواقع Discourse تفشل في Core Web Vitals. إذا قمنا بتقديم صفحة HTML ثابتة سريعة للمستخدمين في المرة الأولى و/أو أجلنا كل منطق JS/CSS في التحميل الأولي الأول، وبهذه الطريقة يمكننا تسريع جميع الصفحات وتجاوز درجات CWV! متحمس لرؤية هذا الأمر في تحديث Discourse الأساسي.

جميع مواقع Discourse تشهد انخفاضًا في تصنيفات Google بسبب فشل المواقع في اجتياز Core Web Vitals.

إعجابَين (2)

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

هل يمكنك محاولة إضافة إعداد موقع في طلب السحب الخاص بك @rrit؟ سيكون من الجيد أيضًا إضافة بعض اختبارات RSpec للتحقق من السلوك مع تمكين / تعطيل الإعداد.

5 إعجابات

ألا يعني هذا أنه يمكننا ببساطة وضع مؤشر دوران بملء الشاشة (بعرض 100% وارتفاع 100%) على الصفحة التي يعرضها الخادم، واستبداله بتطبيق Ember عندما يتم تشغيله أخيرًا للحصول على LCP منخفض للغاية؟

يمكننا جعل مؤشر الدوران هذا بتنسيق SVG يحاكي واجهة مستخدم Discourse لجعل الانتقال أكثر سلاسة وأقل شبهاً بـ FOUC.

إعجابَين (2)

أعتقد أن الجزء الأساسي هو “مرشح” LCP

هل سيتم اعتباره أكبر طلاء للمحتوى فقط إذا كان بالفعل الأكبر (أو على الأقل بنفس الحجم) مما يتم عرضه في النهاية؟

إذًا، استخدام عرض الزاحف يعمل بشكل جيد لأن المحتوى (أي النص) هو نفسه إلى حد كبير؟

(أنا أخمن في الغالب هنا، بناءً على لقطات الشاشة أعلاه - لم أجرب مؤشر دوران بملء الشاشة)

إعجاب واحد (1)

تم تطبيق علامة الميزة.

أنا لست مطور Ruby على الإطلاق - في هذا الأمر أحتاج بالتأكيد إلى بعض المساعدة.

هل يمكنني دفع إثبات المفهوم الخاص بي إلى فرع جديد في مستودع discourse/discourse، قبل القيام بطلب سحب على main؟

هذا هو طلب السحب الخاص بي لهذه الميزة:

@david هل يمكنك مساعدتي في تطوير اختبارات RSpec لهذه التغييرات:

app/helpers/application_helper.rb: spec/helpers/application_helper_spec.rb

لا أرى اختبارات وحدات قابلة للتطبيق هنا. يبدو أنها قابلة للاختبار من خلال اختبارات التكامل فقط.
app/models/theme.rb
app/models/theme_field.rb

اضطررت إلى تعطيل علامة التأجيل لمشغل اختبار QUnit: app/views/qunit/index.html.erb
قبل ذلك، كانت اختبارات QUnit لا تزال تعمل مع علامة الميزة "javascript defer" = false. والآن تعمل الاختبارات أيضًا مع "javascript defer" = true.

إعجابَين (2)

من المحتمل أن يكون هذا محظورًا بالفعل بواسطة https://chromium.googlesource.com/chromium/src/+/master/docs/speed/metrics_changelog/2020_11_lcp.md:

لم تعد الصور التي تملأ منفذ العرض، والتي تعادل بصريًا الخلفيات، تُعتبر أكبر محتوى يتم عرضه في وقت الاستجابة (LCP)


نقطة جيدة: انظر Largest Contentful Paint (LCP)  |  Articles  |  web.dev

بالنسبة لعناصر النص، يتم النظر فقط في حجم عقد النص الخاصة بها (أصغر مستطيل يحيط بجميع عقد النص).

بالنسبة لجميع العناصر، لا يتم النظر في أي هوامش أو حشو أو حدود مطبقة عبر CSS.

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

انظر: أمثلة LCP


لقد استخدمت في الواقع عرض noscript للمشاركات داخل صفحة الموضوع. تتطابق فئات CSS قليلاً مع الفئات الحقيقية - لذا فإن المظهر متساوٍ.

انظر: التغييرات على app/views/layouts/application.html.erb

تعديل: خطئي، هذا في الواقع عرض الزاحف: app/views/topics/show.html.erb

إعجابَين (2)

في إثبات المفهوم، تم دمج ميزتين - هل نقسمهما إلى علامتي ميزة تجريبيتين؟

  • جافا سكريبت مع علامة تأجيل (علامة ميزة في لوحة تحكم الإعدادات)
    ~~ (علامة ميزة مخفية حيث يلزم إعادة بناء الحاوية أو مسح ذاكرة التخزين المؤقت للموضوع لهذا الغرض) ~~ ← إصلاح: التبديل السريع مع ذاكرة التخزين المؤقت
  • عرض محتوى ثابت في عرض الموضوع (علامة ميزة في لوحة تحكم الإعدادات)

ها نحن ذا: علامات الميزات


بالطبع، يتم تحقيق التأثير الكامل على LCP فقط باستخدام كليهما: FCP: محتوى ثابت

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

إعجابَين (2)

الانطباع الأول من Google Search Console مع تطبيق POC منذ 2022-01-30:

سطح المكتب

استغرق ظهور النتائج لسطح المكتب بعض الوقت:


ملاحظة: الخط الأخضر القديم يمثل صفحات الويب غير التابعة لـ Discourse على نفس النطاق.

الجوال


ملاحظة: الخط الأخضر القديم يمثل صفحات الويب غير التابعة لـ Discourse على نفس النطاق.

دعونا ننتظر 7-14 يومًا أخرى لنأمل في رؤية المزيد من التحسينات لصفحات الجوال حيث يتم حساب القيم في المتوسط على مدار الـ 28 يومًا الماضية - يتم حساب 12 يومًا فقط مع تطبيق POC حاليًا.

5 إعجابات

ملخص LCP حول إثبات المفهوم

تم تطبيق إثبات المفهوم منذ 2022-01-30 واستغرق +4 أسابيع للتأثير على جميع الصفحات في تقرير “Core Web Vitals” الخاص بـ Google Search Console - بناءً على بيانات CrUX.

جميع صفحات الموضوعات في المنطقة الخضراء لـ LCP (مقاسة بواسطة CrUX):

  • سطح المكتب: LCP 1.7 ثانية
  • الجوال: LCP 2.0 ثانية

بيانات LCP: Google Search Console/CrUX

انطباع من Google Search Console مع تطبيق إثبات المفهوم منذ 2022-01-30:

سطح المكتب


ملاحظة: الخط الأخضر الأساسي القديم يمثل صفحات الويب غير Discourse على نفس النطاق.

عناوين URL جيدة

الجوال


ملاحظة: الخط الأخضر الأساسي القديم يمثل صفحات الويب غير Discourse على نفس النطاق.

عناوين URL جيدة

مشكلة LCP: أطول من 2.5 ثانية (الجوال)


ملاحظة: صفحات الموضوعات فقط تعرض محتوى ثابتًا قبل محتوى EmberJS


الموافقة على طلب السحب (PR) مع علامات الميزات مطلوبة

@sam هل يمكنك تفويض هذا الطلب إلى شخص ما لإلقاء نظرة عليه للموافقة عليه، من فضلك.

3 إعجابات

سنقوم بالتأكيد بمراجعتها بعناية، إنها تغيير كبير جدًا وقد يستغرق الأمر بعض الوقت للوصول إليها.

5 إعجابات

@rrit شكراً لمشاركة البيانات من موقعك! لقد ناقشنا هذا داخليًا، وأخشى أننا لن نضيف هذه الوظيفة إلى Discourse الأساسي في الوقت الحالي.

بينما تعد مقاييس Web Vital التي شاركتها مثيرة للإعجاب للغاية، فإن وميض محتوى “عرض الزاحف” لا يوفر تجربة مستخدم رائعة. تساعد تغييرات التنسيق التي أجريتها بالتأكيد، ولكن ستحتاج إلى تعديلها لكل موقع Discourse يحتوي على تنسيق مخصص.

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


كل ما سبق، Discourse قابل للتوسيع بشكل كبير، لذلك أعتقد أنه من الممكن تمامًا تنفيذ فكرتك في إضافة Discourse ومشاركتها هنا في Plugin.

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

باستخدام هذه التقنية، يمكنك كتابة برنامج وسيط يتحقق من استجابات text/html، ويقوم بتحليلها، ثم يضيف سمات defer عند الضرورة.

يمكن إضافة البرمجيات الوسيطة من إضافة على النحو التالي:

# name: my-plugin
# about: وصف إضافتي
# version: 1.0
# url: https://example.org

require_relative "lib/script_defer_middleware"

on(:after_initializers) do
  Rails.configuration.middleware.use(ScriptDeferMiddleware)
end

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

10 إعجابات

إذا وجدت وقتًا لهذا، فمن المحتمل أن أقوم بتنفيذ إضافة.

ولكن في الوقت الحالي أحاول التأقلم مع نهج التصحيح في web_only.yml:

# ليس رمزًا زائفًا تم اختباره!
hooks:
  after_code:
    - exec:
        cd: $home
        cmd:
          - curl https://patch-diff.githubusercontent.com/raw/discourse/discourse/pull/15858.diff | git apply
4 إعجابات

يبدو Ember FastBoot نهجًا طويل الأجل مثاليًا. في هذه الأثناء، يظل موضوع LCP ساخنًا:

إعجابَين (2)

شكراً لعملك على هذا @rrit :+1:

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

5 إعجابات