هل العرض من جهة الخادم ليس من جهة الخادم ولكنّك تريد تسريع أداء موقعك الإلكتروني في React؟ جرِّب ميزة "العرض المُسبَق".
react-snap
هي مكتبة تابعه لجهة خارجية
تعرض الصفحات على موقعك الإلكتروني مسبقًا في ملفات HTML ثابتة. ويمكن أن يؤدي ذلك إلى
تحسين
وقت عرض المحتوى لأول مرة
في تطبيقك.
في ما يلي مقارنة بين التطبيق نفسه مع العرض المسبق المُحمّل على اتصال 3G وجهاز جوّال تمت محاكاته وبدونه:
ما الفائدة من ذلك؟
تتمثل المشكلة الرئيسية في الأداء المتعلّقة بالتطبيقات الكبيرة المكوّنة من صفحة واحدة في أنّه على المستخدم الانتظار إلى أن يكتمل تحميل حِزم JavaScript التي تشكّل الموقع الإلكتروني، لكي يتمكّن من الاطّلاع على أي محتوى حقيقي. كلما زاد حجم الحزم، طالت مدة انتظار المستخدم.
لحلّ هذه المشكلة، يعتمد العديد من المطوّرين أسلوب عرض التطبيق على الخادم بدلاً من تشغيله على المتصفّح فقط. مع كل انتقال إلى صفحة أو مسار، يتم إنشاء ملف HTML كامل على الخادم وإرساله إلى المتصفّح، ما يقلل من أوقات عرض الصفحة الأولى، ولكن بتكلفة ازدياد مدة تحميل أول بايت.
العرض المُسبَق هو تقنية منفصلة أقل تعقيدًا من عرض الخادم، ولكنه يقدّم أيضًا طريقة لتحسين أوقات "العرض الأوّل" في تطبيقك. يتم استخدام متصفّح بلا واجهة مستخدم لإنشاء ملفات HTML ثابتة لكل مسار أثناء وقت الإنشاء. يمكن بعد ذلك إرسال هذه الملفات مع حِزم JavaScript المطلوبة لتطبيق .
react-snap
يستخدم 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 المهمة.
الخاتمة
إذا لم تكن مسارات العرض من جهة الخادم في تطبيقك، يمكنك استخدام
react-snap
لعرض محتوى HTML ثابت مسبقًا للمستخدمين.
- قم بتثبيتها كتبعية للتطوير والبدء بالإعدادات الافتراضية فقط.
- ويمكنك استخدام خيار
inlineCss
التجريبي لتضمين محتوى CSS المهم إذا كان مناسبًا لموقعك الإلكتروني. - إذا كنت تستخدِم ميزة تقسيم الرموز البرمجية على مستوى المكوّنات ضمن أيّ مسارات، يجب
توخّي الحذر من عدم عرض حالة التحميل مسبقًا للمستخدمين. يتناولملف
react-snap
README هذه المسألة بمزيد من التفصيل.