عرض المسارات مسبقًا باستخدام ميزة "تفاعل الانطباق"

هل العرض من جهة الخادم ليس من جهة الخادم ولكنّك تريد تسريع أداء موقعك الإلكتروني في React؟ تجربة العرض المسبق

react-snap هي جهة خارجية. تعرض مسبقًا صفحات على موقعك الإلكتروني في شكل ملفات HTML ثابتة. يمكن أن تحسين سرعة عرض الصفحة مرات في تطبيقك.

في ما يلي مقارنة بين التطبيق نفسه مع ميزة العرض المُسبَق أو بدونها المحملة على جهاز جوّال واتصال بشبكة الجيل الثالث تم محاكاته:

مقارنة بين عمليات التحميل جنبًا إلى جنب ويتم تحميل الإصدار الذي يستخدم العرض المسبق بسرعة 4.2 ثوانٍ.

لماذا يُعدّ ذلك مفيدًا؟

تكمن مشكلة الأداء الرئيسية للتطبيقات الكبيرة المكونة من صفحة واحدة في أن على المستخدم الانتظار إلى حين انتهاء حِزم JavaScript التي يتألف منها الموقع الإلكتروني. التنزيل قبل أن يتمكنوا من رؤية أي محتوى حقيقي. كلما كبر حجم الحزم، لفترة أطول سيضطر المستخدم إلى انتظارها.

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

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

وصلة تفاعلية

يستخدم react-snap لعبة Puppeteer من أجل إنشاء ملفات HTML معروضة مسبقًا لمسارات مختلفة في تطبيقك. إلى ابدأ، وقم بتثبيتها كتبعية للتطوير:

npm install --save-dev react-snap

أضِف بعد ذلك النص البرمجي postbuild في package.json:

"scripts": {
  //...
  "postbuild": "react-snap"
}

سيؤدي هذا تلقائيًا إلى تشغيل الأمر react-snap في كل مرة يتم فيها إنشاء نسخة جديدة التطبيقات المقدمة (npm build).

آخر شيء سيتعين عليك القيام به هو تغيير طريقة تشغيل التطبيق. غيِّر ملف src/index.js إلى ما يلي:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));
const rootElement = document.getElementById("root");

if (rootElement.hasChildNodes()) {
  ReactDOM.hydrate(<App />, rootElement);
} else {
  ReactDOM.render(<App />, rootElement);
}

بدلاً من استخدام ReactDOM.render فقط لعرض عنصر React الجذر مباشرةً في DOM، يتحقّق هذا مما إذا كانت أي عُقد فرعية موجودة من قبل لتحديد ما إذا كان قد تم عرض محتوى HTML مسبقًا (أو عرضه على الخادم). في هذه الحالة، يتم استخدام ReactDOM.hydrate بدلاً من ذلك لإرفاق الحدث المستمعين إلى HTML الذي تم إنشاؤه بالفعل بدلاً من إنشائه من جديد.

سيؤدي إنشاء التطبيق إلى إنشاء ملفات HTML ثابتة كحمولات كل مسار يتم الزحف إليه. يمكنك إلقاء نظرة على شكل حمولة HTML مثل النقر على عنوان URL لطلب HTML ثم النقر على المعاينات ضمن "أدوات مطوري البرامج في Chrome"

المقارنة قبل وبعد. تُظهر اللقطة اللاحقة المحتوى لعرضه.

وميض من محتوى غير نمطي

على الرغم من عرض HTML الثابت الآن على الفور تقريبًا، فإنه لا يزال بدون نمط افتراضيًا، الأمر الذي قد يتسبب في ظهور مشكلة "وميض غير ذي نمط المحتوى" (FOUC). يمكن ملاحظة ذلك بشكل خاص إذا كنت تستخدم CSS-in-JS لإنشاء أدوات اختيار، إذ يجب إنهاء حزمة JavaScript قبل تطبيق أي أنماط.

للمساعدة في منع حدوث ذلك، يمكن استخدام CSS الحرج أو الحد الأدنى من محتوى CSS اللازم لعرض الصفحة الأولية، يمكن أن يتم تضمينه مباشرةً في <head> من وثيقة HTML. يستخدم react-snap مكتبة أخرى تابعة لجهة خارجية ضمن minimalcss لاستخراج أي CSS المهمة لمسارات مختلفة. يمكنك تفعيل ذلك عن طريق تحديد التالية في ملف package.json:

"reactSnap": {
  "inlineCss": true
}

بعد الاطّلاع على معاينة الردّ في "أدوات مطوري البرامج في Chrome"، سيتم الآن عرض صفحة ذات نمط معيّن يتضمّن محتوى CSS مهمًا.

المقارنة قبل وبعد. تعرض اللقطة اللاحقة المحتوى وقد تم تصميمه باستخدام CSS الأساسي المضمّن.

الخاتمة

إذا لم تكن مسارات العرض من جهة الخادم في تطبيقك، استخدِم react-snap لعرض محتوى HTML الثابت مسبقًا للمستخدمين.

  1. تثبيته كتبعية للتطوير والبدء بالإعداد التلقائي الإعدادات.
  2. استخدام خيار inlineCss التجريبي لتضمين محتوى CSS المهم إذا كان يعمل على موقعك الإلكتروني
  3. إذا كنت تستخدم تقسيم الرمز على مستوى المكونات في أي مسارات، فيجب الحرص على عدم عرض حالة التحميل مسبقًا للمستخدمين تشير رسالة الأشكال البيانية ملف تمهيدي حول react-snap تتناول هذا بمزيد من التفصيل.