समस्या
यह कोई रहस्य नहीं है कि इस दिन का प्रदर्शन वेब एप्लिकेशन की गुणवत्ता के मुख्य संकेतकों में से एक बना हुआ है। और, ज़ाहिर है, किसी भी वेब डेवलपर ने अपने आवेदन को अनुकूलित करने और सर्वर और क्लाइंट दोनों पर स्वीकार्य प्रदर्शन प्राप्त करने में एक घंटे से अधिक समय बिताया। इस तथ्य के बावजूद कि हार्डवेयर हर दिन अधिक से अधिक शक्तिशाली होता जा रहा है, वहाँ हमेशा अड़चनें होती हैं, जो चारों ओर से गुजरना मुश्किल हो सकता है। AJAX के आगमन के साथ, प्रति ग्राहक प्राप्त आंकड़ों की मात्रा के संदर्भ में HTTP अनुरोध "छोटा" हो गया, लेकिन उनकी संख्या में वृद्धि हुई। संचार चैनल काफी व्यापक हो सकते हैं, लेकिन कनेक्शन समय और सर्वर पर प्रतिक्रिया बनाने की प्रक्रिया में काफी समय लग सकता है। क्लाइंट पर क्वेरी क्वेरी परिणाम समग्र प्रदर्शन में काफी सुधार कर सकते हैं। इस तथ्य के बावजूद कि कैशिंग को HTTP प्रोटोकॉल स्तर पर कॉन्फ़िगर किया जा सकता है, यह अक्सर वास्तविक आवश्यकताओं को पूरा नहीं करता है।
कार्य
हमारे ग्राहक कैशिंग प्रणाली को निम्नलिखित आवश्यकताओं को पूरा करना चाहिए:
- किसी भी जटिलता के कैश प्रबंधन तर्क को लागू करने की क्षमता;
- विभिन्न अनुप्रयोगों में पुन: उपयोग करने की क्षमता;
- मौजूदा एप्लिकेशन में पारदर्शी रूप से एम्बेड करने की क्षमता;
- डेटा के प्रकार की स्वतंत्रता और उन्हें प्राप्त करने की विधि;
- कैश्ड डेटा को संग्रहीत करने की विधि से स्वतंत्रता;
मौजूदा आवेदन
मान लें कि हमारे पास पहले से ही एक कार्यशील अनुप्रयोग है जो AJAX के माध्यम से सर्वर से मार्कअप या डेटा प्राप्त करने के लिए jQuery का उपयोग करता है:
function myApp() { this.doMyAjax = function (settings) { settings.method = 'get'; settings.error = function (jqXHR, textStatus, errorThrown) {
कहीं, हम एक विधि कहते हैं जो डेटा के लिए कॉल करती है:
var app = new myApp(); app.myServerDataAccess();
कैशिंग परत
हम सबसे सरल कैशिंग परत को लागू करते हैं, जिसमें एक प्रॉक्सी शामिल होगी जो डेटा और कैश तक पहुंच को नियंत्रित करती है।
getData
जाने वाले इंटरफ़ेस में एकल
getData
विधि
getData
है। एक पूरी तरह से पारदर्शी प्रॉक्सी बस उसी इंटरफ़ेस का उपयोग करके अपने डेटा स्रोत पर कॉल को प्रस्तुत करता है:
function cacheProxy(source) { var source = source; this.getData = function (request, success, fail) { source.getData(request, success, fail); } }
कैश तक पहुंचने के लिए कुछ तर्क जोड़ें, जिन्हें हम थोड़ी देर बाद लागू करेंगे:
function cacheProxy(source, useLocalStorage) { var source = source; var cache = new localCache(useLocalStorage); this.getData = function (request, success, fail) { var fromCache = cache.get(request.id); if (fromCache !== null) { success(fromCache); } else { source.getData(request, function (result) { cache.set(request.id, result); success(result); }, fail); } } }
डेटा प्राप्त करने की कोशिश करते समय, प्रॉक्सी कैश में अपनी उपस्थिति की जांच करता है और यदि ऐसा है तो देता है। यदि वे नहीं हैं, तो वह उन्हें स्रोत का उपयोग करके प्राप्त करता है, उन्हें कैश में डालता है और उन्हें अनुरोधकर्ता को देता है।
हम
स्थानीय संग्रहण में डेटा रखने की क्षमता के साथ, कैश लागू करते हैं:
function localCache(useLocalStorage) { var data = useLocalStorage ? window.localStorage || {} : {}; this.get = function (key) { if (key in data) { return JSON.parse(data[key]); } return null; } this.set = function (key, value) { if (typeof (key) != 'string') { throw 'Key must be of string type.'; } if (value === null || typeof (value) == 'undefined') { throw 'Unexpected value type'; } data[key] = JSON.stringify(value); } }
डेटा को कैश किए गए डेटा की कुंजी / क्रमबद्ध जोड़े के रूप में संग्रहीत किया जाता है।
मौजूदा एप्लिकेशन में एकीकरण
जैसा कि आप देख सकते हैं, मौजूदा एप्लिकेशन में डेटा एक्सेस इंटरफेस और परिणामस्वरूप प्रॉक्सी अलग हैं (ऐसा मत सोचो कि यह हमारे जीवन को जटिल बनाने का प्रयास है, हमने प्रदर्शन उद्देश्यों के लिए जानबूझकर ऐसा किया था)। एकीकरण के लिए, यह एक एडाप्टर लिखने के लिए पर्याप्त है जो अनुमानित इंटरफ़ेस को लागू करता है और इसे लागू करता है:
function applyCacheProxyToMyApp(app) { var app = app; app.old_doMyAjax = app.doMyAjax; var proxy = new cacheProxy(this, true); app.doMyAjax = function (settings) { proxy.getData({ id: settings.url }, settings.success, settings.error); } this.getData = function (request, success, fail) { app.old_doMyAjax({ url: request.id, success: success, error: fail }); } } var patch = new applyCacheProxyToMyApp(app);
जैसा कि आप देख सकते हैं, हम किसी मौजूदा एप्लिकेशन में कोड की एक भी लाइन नहीं बदल रहे हैं। यदि आवश्यक हो तो कैशिंग को दर्द रहित रूप से बंद किया जा सकता है या फेंक दिया जा सकता है। समझ को जटिल नहीं करने के लिए, हम कैश सफाई एल्गोरिथ्म को लागू नहीं करेंगे यह किसी विशेष एप्लिकेशन में विशिष्ट आवश्यकताओं पर निर्भर हो सकता है।
बोनस
परिणामस्वरूप कैशिंग परत को लागू करना आसान है, उदाहरण के लिए, संसाधन-गहन दोहराव कार्यों के लिए:
function complicatedStuff(a, b) { return a * b; } function complicatedStuffAdapter(complicatedStuff) { var proxy = new cacheProxy(this, true); var source = complicatedStuff; this.complicatedStuff = function (a, b) { var result; proxy.getData({id: a.toString() + '_' + b, a: a, b: b}, function(res) { result = res; }); return result; } this.getData = function (request, success, fail) { success(source(request.a, request.b)); } } var p = new complicatedStuffAdapter(complicatedStuff); function test() { alert(p.complicatedStuff(4, 5)); }
निष्कर्ष में
हमने आपके द्वारा किए जाने वाले किसी भी ऑपरेशन को पूरा करने के लिए केवल दृष्टिकोण पर विचार किया। कई अनुप्रयोग हैं। लॉगिंग से लेकर जटिल पहलू-आधारित एल्गोरिदम के कार्यान्वयन तक, यह सब आपकी आवश्यकताओं और कल्पना पर निर्भर करता है।