रशियन डॉल कैशिंग के अलावा, रेल्स ऐप्स में प्रदर्शन को गति देने के लिए और भी तकनीकें हैं। इस बार हम रेल्स के बिल्ट-इन कंडीशनल GET समर्थन को देखेंगे, जो आपको रेंडर्ड पेज को यूज़र के ब्राउज़र कैश में स्टोर करने की अनुमति देता है।
👋 और यदि आप कैशिंग के बाहर प्रदर्शन के बारे में अधिक पढ़ना पसंद करते हैं, तो हमने रूबी (ऑन रेल्स) प्रदर्शन के बारे में बहुत कुछ लिखा है, हमारे रूबी प्रदर्शन मॉनिटरिंग चेकलिस्ट को देखें।
Etag और Last-Modified हेडर्स
जब आपका ब्राउज़र आपके रेल्स ऐप में पेज के लिए HTTP GET अनुरोध निष्पादित करता है, तो राउटर इसे आपके कंट्रोलर एक्शन से जोड़ेगा। कंट्रोलर तब डेटाबेस से आवश्यक डेटा का अनुरोध करेगा और व्यू रेंडर करेगा। व्यू से रेंडर्ड HTML के साथ रिस्पॉन्स बॉडी में 200 OK रिस्पॉन्स कोड के साथ एक HTTP रिस्पॉन्स तब आपके ब्राउज़र को पार्स और प्रदर्शित करने के लिए वापस भेजा जाता है।
जब रिसोर्स का फिर से अनुरोध किया जाता है, तो हम उसी पाइपलाइन से गुजरेंगे। कुछ स्थितियों में, यह अनावश्यक है क्योंकि पेज बीच में नहीं बदला। इसके लिए, HTTP अपने ETag और Last-Modified हेडर्स प्रदान करता है। इनका उपयोग करके, ब्राउज़र रिस्पॉन्स बॉडी को स्टोर कर सकता है, और जब वे स्टेल हो जाते हैं तो उन्हें अमान्य करने के लिए हेडर्स का उपयोग कर सकता है।
Etags, या एंटिटी टैग्स, क्लाइंट-साइड कैश वैलिडेशन के लिए उपयोग किए जाते हैं, इसलिए आप उन्हें अपने HTTP रिस्पॉन्सेस के लिए कैश कीज़ के रूप में सोच सकते हैं। उन्हें हर अनुरोध के लिए HTTP रिस्पॉन्स हेडर में ब्राउज़र को वापस पास किया जाता है।
~ $ curl -I https://localhost:3000/products/1
HTTP/1.1 200 OK
...
ETag: W/"9462d76cc55aeb6249fa990e39231c7c"
Last-Modified: Wed, 25 Apr 2018 08:27:04 GMT
...
यदि रिस्पॉन्स बाद में दोहराया जाता है, तो ब्राउज़र अपने कैश में मौजूदा रिस्पॉन्स ढूंढता है और अंतिम अनुरोध से स्टोर किए गए Etag का उपयोग If-None-Match हेडर के रूप में करता है। यह हेडर हमारे रेल्स ऐप को बताएगा कि हमारे पास कैश में पहले से ही यह संस्करण है।
यदि अनुरोध से Etag वर्तमान से मेल खाता है, तो रेल्स रिस्पॉन्स बॉडी के बिना 304 Not Modified रिस्पॉन्स भेजेगा। यह ब्राउज़र को अपने लोकल कैश से उपयोग करने के लिए कहेगा।
~ $ curl -i -H 'If-None-Match: W/"9462d76cc55aeb6249fa990e39231c7c"' https://localhost:3000/products/1
HTTP/1.1 304 Not Modified
...
ETag: W/"9462d76cc55aeb6249fa990e39231c7c"
Last-Modified: Wed, 25 Apr 2018 08:27:04 GMT
...
रेल्स में कंडीशनल GET अनुरोध
यदि हम लोकल रेल्स एप्लिकेशन से पेज का अनुरोध करते हैं, तो हम देख सकते हैं कि रेल्स प्रत्येक अनुरोध के लिए स्वचालित रूप से एक Etag जोड़ता है। यदि हम कुछ बार उसी पेज का अनुरोध करते हैं, तो हम देख सकते हैं कि Etag प्रत्येक अनुरोध के लिए बदलता है।
हालांकि रेल्स डिफ़ॉल्ट रूप से प्रत्येक अनुरोध के लिए Etag उत्पन्न करता है, यह पूरे रिस्पॉन्स बॉडी के डाइजेस्ट का उपयोग करके इसे उत्पन्न करता है। इसका मतलब है कि लेआउट में <%= csrf_meta_tags %> Etag को फेंक देता है, क्योंकि csrf-टोकन मेटा टैग प्रत्येक अनुरोध के लिए बदलता है। चूंकि यह प्रत्येक अनुरोध के लिए बॉडी को बदलता है, Etag अमान्य हो जाता है और लोकल कैश को स्टेल चिह्नित किया जाता है।
इसके अलावा, रेल्स डिफ़ॉल्ट रूप से कभी 304 Not Modified नहीं लौटाएगा, क्योंकि लोकल कैश को हमारे कंट्रोलर में कभी स्पष्ट रूप से फ्रेश के रूप में चिह्नित नहीं किया जाता।
fresh_when और stale?
कंडीशनल GET के लिए अनुरोध हेडर से Etags का उपयोग करने के लिए, हमें लोकल कैश में एक ऑब्जेक्ट को स्पष्ट रूप से "फ्रेश" के रूप में चिह्नित करने की आवश्यकता है। उदाहरण के लिए, एक पेज के लिए जो प्रोडक्ट दिखाता है, हम कैश को तब तक फ्रेश रख सकते हैं जब तक प्रोडक्ट और व्यू टेम्पलेट्स नहीं बदलते। इसे काम करने के लिए, हम दो चीजें करेंगे।
- हम स्पष्ट रूप से उन मानों को सेट करेंगे जो हमारे Etag को बनाएंगे, क्योंकि पूरे रिस्पॉन्स बॉडी का उपयोग करने के लिए हमें यह जांचने के लिए पूरे बॉडी को रेंडर करना होगा कि कैश्ड रिस्पॉन्स वैध है, जो पेज को स्थानीय रूप से कैश करने से स्पीडअप को नकार देगा।
- हम अनुरोध हेडर से Etag की तुलना व्यू रेंडर करने से पहले हमारे द्वारा भविष्यवाणी किए गए से करेंगे, और यदि वे मेल खाते हैं तो रेंडरिंग को छोड़ देंगे।
रेल्स हेल्पर्स के साथ आता है जो हमारे लिए सब कुछ करता है। हम fresh_when का उपयोग करके Etag और Last-Modified तारीख को स्पष्ट रूप से प्रोडक्ट पर आधारित कर सकते हैं।
# app/views/products/show.html.erb
def show
@product = Product.find(params[:id])
fresh_when @product
end
यदि आपके पास स्पष्ट respond_to ब्लॉक है, तो fresh_when के बजाय stale? का उपयोग करें।
# app/views/products/show.html.erb
def show
@product = Product.find(params[:id])
if stale?(@product)
respond_to do |format|
format.html
end
end
end
अब, प्रोडक्ट पेज में से एक का अनुरोध करने पर रिस्पॉन्स लोकल रूप से कैश होगा। उसी पेज के किसी भी बाद के अनुरोध में Etag शामिल होगा जो रेल्स को बताएगा कि हमारे पास एक कैश्ड रिस्पॉन्स है, जिसकी तुलना नए Etag से की जाती है। यदि वह मेल खाता है, तो रेल्स पेज रेंडरिंग को छोड़ देगा, और तुरंत 304 Not Modified लौटाएगा।
नोट: पेज रीफ्रेश करने से हमेशा पेज का अनकैश्ड संस्करण अनुरोध किया जाएगा। अपने कंडीशनल GET को टेस्ट करने के लिए, लिंक या बैक बटन का उपयोग करके नेविगेट करें।
आपको यह लेख और ऐपसिग्नल अकादमी श्रृंखला के पिछले लेख कैसे लगे? हमारे पास रेल्स में कैशिंग के बारे में कुछ और लेख लाइन में हैं, लेकिन कृपया हमें यह बताने में संकोच न करें कि आप आगे क्या लिखना चाहेंगे (कैशिंग से संबंधित या अन्यथा)!