रिएक्शन-स्नैप के साथ प्री-रेंडरिंग रूट

क्या आपको सर्वर साइड रेंडरिंग की सुविधा का इस्तेमाल नहीं करना है, लेकिन फिर भी अपनी React साइट की परफ़ॉर्मेंस को बेहतर बनाना है? वीडियो को पहले से रेंडर करने की सुविधा आज़माएं!

react-snap, तीसरे पक्ष की एक लाइब्रेरी है. यह आपकी साइट के पेजों को स्टैटिक एचटीएमएल फ़ाइलों में पहले से रेंडर करती है. इससे आपके ऐप्लिकेशन में फ़र्स्ट पेंट का समय बेहतर हो सकता है.

यहां एक ही ऐप्लिकेशन की तुलना की गई है. इसमें, ऐप्लिकेशन को सिम्युलेट किए गए 3G कनेक्शन और मोबाइल डिवाइस पर, पहले से रेंडर किए जाने के साथ और उसके बिना लोड किए जाने की तुलना की गई है:

लोड होने में लगने वाले समय की तुलना. पहले से रेंडर किए गए वर्शन का इस्तेमाल करने पर, वीडियो 4.2 सेकंड तेज़ी से लोड होता है.

यह जानकारी आपके काम की क्यों है?

बड़े सिंगल-पेज ऐप्लिकेशन की परफ़ॉर्मेंस से जुड़ी मुख्य समस्या यह है कि उपयोगकर्ता को कोई भी असल कॉन्टेंट देखने से पहले, साइट बनाने वाले JavaScript बंडल के डाउनलोड होने का इंतज़ार करना पड़ता है. बंडल जितना बड़ा होगा, उपयोगकर्ता को उतना ही ज़्यादा इंतज़ार करना होगा.

इसे ठीक करने के लिए, कई डेवलपर ऐप्लिकेशन को सिर्फ़ ब्राउज़र पर बूट करने के बजाय, सर्वर पर रेंडर करते हैं. हर पेज/रूट ट्रांज़िशन के साथ, सर्वर पर पूरा एचटीएमएल जनरेट होता है और ब्राउज़र पर भेजा जाता है. इससे, पेज दिखने में लगने वाला समय कम हो जाता है, लेकिन टाइम टू फ़र्स्ट बाइट धीमा हो जाता है.

पहले से रेंडर करना एक अलग तकनीक है, जो सर्वर रेंडरिंग से कम जटिल है. हालांकि, इससे आपके ऐप्लिकेशन में फ़र्स्ट पेंट के समय को बेहतर बनाने का भी एक तरीका मिलता है. बिल्ड के समय, हर रूट की स्टैटिक एचटीएमएल फ़ाइलें जनरेट करने के लिए, बिना यूज़र इंटरफ़ेस वाले ब्राउज़र का इस्तेमाल किया जाता है. इसके बाद, इन फ़ाइलों को ऐप्लिकेशन के लिए ज़रूरी JavaScript बंडल के साथ शिप किया जा सकता है.

react-snap

react-snap, आपके ऐप्लिकेशन में अलग-अलग रास्तों की पहले से रेंडर की गई एचटीएमएल फ़ाइलें बनाने के लिए, Puppeteer का इस्तेमाल करता है. शुरू करने के लिए, इसे डेवलपमेंट डिपेंडेंसी के तौर पर इंस्टॉल करें:

npm install --save-dev react-snap

इसके बाद, अपने package.json में postbuild स्क्रिप्ट जोड़ें:

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

इससे, हर बार ऐप्लिकेशन का नया बिल्ड (npm build) बनाने पर, react-snap कमांड अपने-आप चल जाएगा.

आखिर में, आपको ऐप्लिकेशन को बूट करने का तरीका बदलना होगा. 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 में रेंडर करने के बजाय, यह देखा जाता है कि कोई चाइल्ड नोड पहले से मौजूद है या नहीं. इससे यह पता चलता है कि एचटीएमएल कॉन्टेंट पहले से रेंडर किया गया था या सर्वर पर रेंडर किया गया था. अगर ऐसा है, तो ReactDOM.hydrate का इस्तेमाल, नया एचटीएमएल बनाने के बजाय, पहले से बनाए गए एचटीएमएल में इवेंट लिसनर को अटैच करने के लिए किया जाता है.

ऐप्लिकेशन को बिल्ड करने पर, अब क्रॉल किए गए हर रूट के लिए, स्टैटिक एचटीएमएल फ़ाइलें, पेलोड के तौर पर जनरेट होंगी. एचटीएमएल अनुरोध के यूआरएल पर क्लिक करके, यह देखा जा सकता है कि एचटीएमएल पेलोड कैसा दिखता है. इसके बाद, Chrome DevTools में झलक टैब पर क्लिक करें.

पहले और बाद की तुलना. बाद के शॉट में, रेंडर किया गया कॉन्टेंट दिखता है.

बिना स्टाइल वाले कॉन्टेंट का फ़्लैश

स्टैटिक एचटीएमएल अब तुरंत रेंडर हो जाता है. हालांकि, यह डिफ़ॉल्ट रूप से स्टाइल नहीं किया जाता. इस वजह से, "बिना स्टाइल वाले कॉन्टेंट का फ़्लैश" (एफ़ओयूसी) दिखने की समस्या हो सकती है. यह खास तौर पर तब ध्यान देने वाली बात हो सकती है, जब सिलेक्टर जनरेट करने के लिए, CSS-in-JS लाइब्रेरी का इस्तेमाल किया जा रहा हो. ऐसा इसलिए, क्योंकि किसी भी स्टाइल को लागू करने से पहले, JavaScript बंडल को पूरा लागू होना होगा.

इस समस्या से बचने के लिए, ज़रूरी सीएसएस या शुरुआती पेज को रेंडर करने के लिए ज़रूरी कम से कम सीएसएस को सीधे एचटीएमएल दस्तावेज़ के <head> में इनलाइन किया जा सकता है. react-snap, अलग-अलग रूट के लिए ज़रूरी सीएसएस निकालने के लिए, minimalcss के तहत तीसरे पक्ष की किसी अन्य लाइब्रेरी का इस्तेमाल करता है. इसे चालू करने के लिए, अपनी package.json फ़ाइल में ये चीज़ें बताएं:

"reactSnap": {
  "inlineCss": true
}

Chrome DevTools में रिस्पॉन्स की झलक देखने पर, अब आपको स्टाइल किया गया पेज दिखेगा. इसमें, ज़रूरी सीएसएस को इनलाइन किया गया होगा.

पहले और बाद की तुलना. दूसरे शॉट में दिखाया गया है कि इनलाइन की गई क्रिटिकल सीएसएस की वजह से, कॉन्टेंट रेंडर हो गया है और उसे स्टाइल किया गया है.

नतीजा

अगर आपने अपने ऐप्लिकेशन में सर्वर-साइड रेंडरिंग रूट का इस्तेमाल नहीं किया है, तो अपने उपयोगकर्ताओं को स्टैटिक एचटीएमएल को पहले से रेंडर करने के लिए, react-snap का इस्तेमाल करें.

  1. इसे डेवलपमेंट डिपेंडेंसी के तौर पर इंस्टॉल करें और सिर्फ़ डिफ़ॉल्ट सेटिंग के साथ शुरू करें.
  2. अगर आपकी साइट के लिए, एक्सपेरिमेंट के तौर पर उपलब्ध inlineCss विकल्प काम करता है, तो ज़रूरी सीएसएस को इनलाइन करने के लिए इसका इस्तेमाल करें.
  3. अगर किसी रूट में कॉम्पोनेंट लेवल पर कोड को अलग-अलग हिस्सों में बांटा जा रहा है, तो ध्यान रखें कि आप अपने उपयोगकर्ताओं को लोडिंग स्टेटस को पहले से रेंडर न करें. react-snap README में इस बारे में ज़्यादा जानकारी दी गई है.