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

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

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

यहां एक नकली 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 में, इसके बारे में ज़्यादा जानकारी दी गई है.