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

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

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

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

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

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

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

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

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

प्रतिक्रिया-स्नैप

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