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