2012-04-20 16 views
48

में एक छवि कैश कैसे करते हैं मेरे मित्र और मैं ऐसी वेबसाइट पर काम कर रहे हैं जहां हम भविष्य में उन्हें तेजी से प्रदर्शित करने के लिए कुछ छवियों को कैश करना चाहते हैं। मेरे पास दो मुख्य प्रश्न हैं:आप जावास्क्रिप्ट

  1. आप छवि को कैश कैसे करते हैं?
  2. कैश किए जाने के बाद आप एक छवि का उपयोग कैसे करते हैं? (और सिर्फ सत्यापित करने के लिए, अगर एक छवि पेज एक पर कैश किया गया है, यह संभव है यह कैश से कॉल करने के लिए पेज बी पर इसका इस्तेमाल करने, सही है?)

इसके अलावा, यह संभव स्थापित करने के लिए है जब छवि का कैश संस्करण समाप्त हो जाएगा?

यह बहुत सराहना की जाएगी यदि एक उदाहरण और/या किसी पृष्ठ का एक लिंक जो इसका वर्णन करता है, शामिल था।

हम या तो कच्चे जावास्क्रिप्ट या jQuery संस्करण का उपयोग कर ठीक हैं।

+10

आप नहीं है। ब्राउज़र करता है। – Pointy

+0

ब्राउज़र कैश छवियों को स्वचालित रूप से करता है? –

+6

@ लॉगन: हां, ब्राउजर स्वचालित रूप से छवियों को कैश करता है, बशर्ते आपका सर्वर ब्राउज़र को बताने के लिए आवश्यक हेडर भेजता है, इसे कैश करने के लिए सुरक्षित है। (ये हेडर ब्राउज़र को समाप्ति समय भी बता सकते हैं, जो आपके प्रश्न का हिस्सा है।) – icktoofay

उत्तर

92

ब्राउज़र में किसी भी तरह से एक छवि लोड हो जाने के बाद, यह ब्राउज़र कैश में होगा और अगली बार इसका उपयोग तब किया जाएगा जब यह उपयोग वर्तमान पृष्ठ में हो या किसी अन्य पृष्ठ में क्योंकि ब्राउज़र कैश से समाप्त होने से पहले छवि का उपयोग किया जाता है।

तो, छवियों को सटीक करने के लिए, आपको बस उन्हें ब्राउज़र में लोड करना है। यदि आप छवियों का एक गुच्छा सटीक करना चाहते हैं, तो जावास्क्रिप्ट से ऐसा करना सबसे अच्छा है क्योंकि यह आमतौर पर जावास्क्रिप्ट से किए गए पृष्ठ लोड को नहीं रखेगा। आप क्या कर सकते हैं कि इस तरह:

function preloadImages(array) { 
    if (!preloadImages.list) { 
     preloadImages.list = []; 
    } 
    var list = preloadImages.list; 
    for (var i = 0; i < array.length; i++) { 
     var img = new Image(); 
     img.onload = function() { 
      var index = list.indexOf(this); 
      if (index !== -1) { 
       // remove image from the array once it's loaded 
       // for memory consumption reasons 
       list.splice(index, 1); 
      } 
     } 
     list.push(img); 
     img.src = array[i]; 
    } 
} 

preloadImages(["url1.jpg", "url2.jpg", "url3.jpg"]); 

इस समारोह में कई बार के रूप में कहा जा सकता है के रूप में आप चाहते हैं और हर बार, यह सिर्फ precache को अधिक छवियों जोड़ देगा।

एक बार छवियों को जावास्क्रिप्ट के माध्यम से इस तरह से पहले से लोड किया गया है, तो ब्राउज़र उन्हें अपने कैश में रखेगा और आप केवल अन्य स्थानों (अपने वेब पृष्ठों में) के सामान्य यूआरएल का उल्लेख कर सकते हैं और ब्राउज़र उस यूआरएल को अपने कैश से लाएगा नेटवर्क के बजाय।

आखिरकार समय के साथ, ब्राउज़र कैश थोड़ी देर में उपयोग नहीं की जाने वाली सबसे पुरानी चीजों को भर सकता है और टॉस कर सकता है। तो आखिरकार, छवियों को कैश से बाहर कर दिया जाएगा, लेकिन उन्हें थोड़ी देर के लिए वहां रहना चाहिए (इस पर निर्भर करता है कि कैश कितना बड़ा है और कितनी अन्य ब्राउज़िंग की जाती है)। हर बार छवियों को वास्तव में फिर से लोड किया जाता है या किसी वेब पेज में उपयोग किया जाता है, यह स्वचालित रूप से ब्राउज़र कैश में अपनी स्थिति को रीफ्रेश करता है ताकि उन्हें कैश से बाहर निकलने की संभावना कम हो।

ब्राउज़र कैश क्रॉस-पेज है, इसलिए यह ब्राउज़र में लोड किए गए किसी भी पृष्ठ के लिए काम करता है। तो आप अपनी साइट में एक ही स्थान पर सटीक हो सकते हैं और ब्राउज़र कैश तब आपकी साइट के सभी अन्य पृष्ठों के लिए काम करेगा।


जब जैसा कि ऊपर precaching, छवियों एसिंक्रोनस रूप से लोड किए गए हैं ताकि वे लोड हो रहा है या अपने पेज का प्रदर्शन बंद नहीं होंगे। लेकिन, अगर आपके पृष्ठ में अपनी कई छवियां हैं, तो ये सटीक छवियां आपके पृष्ठ में प्रदर्शित छवियों के साथ बैंडविड्थ या कनेक्शन के लिए प्रतिस्पर्धा कर सकती हैं। आम तौर पर, यह एक उल्लेखनीय मुद्दा नहीं है, लेकिन धीमे कनेक्शन पर, यह सटीक मुख्य पृष्ठ की लोडिंग को धीमा कर सकता है। यदि प्रीलोड छवियों को अंतिम रूप से लोड करने के लिए ठीक था, तो आप फ़ंक्शन के एक संस्करण का उपयोग कर सकते हैं जो प्रीलोडिंग शुरू करने के लिए प्रतीक्षा करेगा जब तक कि अन्य सभी पृष्ठ संसाधन पहले ही लोड नहीं हो जाते थे।

function preloadImages(array, waitForOtherResources, timeout) { 
    var loaded = false, list = preloadImages.list, imgs = array.slice(0), t = timeout || 15*1000, timer; 
    if (!preloadImages.list) { 
     preloadImages.list = []; 
    } 
    if (!waitForOtherResources || document.readyState === 'complete') { 
     loadNow(); 
    } else { 
     window.addEventListener("load", function() { 
      clearTimeout(timer); 
      loadNow(); 
     }); 
     // in case window.addEventListener doesn't get called (sometimes some resource gets stuck) 
     // then preload the images anyway after some timeout time 
     timer = setTimeout(loadNow, t); 
    } 

    function loadNow() { 
     if (!loaded) { 
      loaded = true; 
      for (var i = 0; i < imgs.length; i++) { 
       var img = new Image(); 
       img.onload = img.onerror = img.onabort = function() { 
        var index = list.indexOf(this); 
        if (index !== -1) { 
         // remove image from the array once it's loaded 
         // for memory consumption reasons 
         list.splice(index, 1); 
        } 
       } 
       list.push(img); 
       img.src = imgs[i]; 
      } 
     } 
    } 
} 

preloadImages(["url1.jpg", "url2.jpg", "url3.jpg"], true); 
preloadImages(["url99.jpg", "url98.jpg"], true); 
+0

इस उदाहरण में आप प्रत्येक यूआरएल के लिए एक नई छवि वस्तु बना रहे हैं। यदि आप लूप के बाहर आईएमजी वैरिएबल सेट करते हैं और केवल src को अपडेट करते हैं, तो इसका प्रभाव समान होना चाहिए और संसाधनों पर कटौती होनी चाहिए – cadlac

+0

@ कैडलैक - लेकिन यह सुनिश्चित करने के लिए कि ब्राउज़र वास्तव में प्रत्येक छवि को डॉउलोड और कैश करेगा, आपको करना होगा एक नई .src संपत्ति सेट करने से पहले एक छवि डाउनलोड करने तक प्रतीक्षा करें। अन्यथा ब्राउज़र केवल पूर्व डाउनलोड को रोक सकता है और इसे सफलतापूर्वक कैश नहीं कर सकता है। – jfriend00

+0

ऐसा लगता है कि बिना इंतजार किए ब्राउज़र के नए संस्करणों पर काम करना प्रतीत होता है, लेकिन आप एक अच्छा मुद्दा बनाते हैं। मुझे इसकी अनुकूलता देखने के लिए कुछ पुराने ब्राउज़रों पर इसे आज़माएं :) :) – cadlac

10

@Pointy ने कहा कि आप जावास्क्रिप्ट के साथ छवियों को कैश नहीं करते हैं, ब्राउज़र ऐसा करता है। तो यह हो सकता है कि आप जो पूछ रहे हैं और हो सकता है ... लेकिन आप जावास्क्रिप्ट का उपयोग कर छवियों को प्रीलोड कर सकते हैं। उन सभी छवियों को डालने के द्वारा जिन्हें आप सरणी में प्रीलोड करना चाहते हैं और उस सरणी में सभी छवियों को छिपी हुई आईएमजी तत्वों में डालकर, आप छवियों को प्रभावी ढंग से प्रीलोड (या कैश) करते हैं।

आपकी छवियों पूर्व लोड हो रहा है
छवियों के
फ़ाइल का आकार .htaccess फ़ाइल में एक कैश समय निर्धारित करना और base64 उन्हें एन्कोडिंग:

var images = [ 
'/path/to/image1.png', 
'/path/to/image2.png' 
]; 

$(images).each(function() { 
var image = $('<img />').attr('src', this); 
}); 
+2

क्या एक पृष्ठ पर एक छवि को प्रीलोड करना संभव होगा (इसे प्रदर्शित किए बिना), फिर इसे अगले पृष्ठ पर प्रदर्शित करें? –

+1

मेरे ज्ञान के लिए यदि आप एक पृष्ठ पर एक छवि को प्रीलोड करते हैं तो इसे ब्राउज़र कैश में दर्ज किया जाएगा और फिर किसी भी अन्य पेज पर तेज़ी से प्रदर्शित होगा। अगर यह गलत है, तो कृपया मुझे सही करें। –

2

कुछ चीजें आप देख सकते हैं।

प्रीलोड: http://perishablepress.com/3-ways-preload-images-css-javascript-ajax/

कैशिंग: http://www.askapache.com/htaccess/speed-up-sites-with-htaccess-caching.html

बेस 64 एन्कोडिंग के लिए एक जोड़े को अलग अलग विचार कर रहे हैं, कुछ लोगों का कहना है कि HTTP अनुरोध बैंडविड्थ दलदल, जबकि अन्य का कहना है कि "माना जाता है" लोड हो रहा है बेहतर। मैं इसे हवा में छोड़ दूंगा।

0

हां, ब्राउज़र स्वचालित रूप से आपके लिए छवियों को कैश करता है।

हालांकि, आप समाप्त होने के लिए एक छवि कैश सेट कर सकते हैं। इस स्टैक ओवरफ़्लो सवालों की जाँच करें और जवाब:

Cache Expiration On Static Images

1

मैं अतुल्यकालिक जे एस के माध्यम से छवियों पहले से लोड होने के लिए एक similar answer है। उन्हें गतिशील रूप से लोड करना सामान्य रूप से उन्हें लोड करने जैसा ही होता है। वे कैश करेंगे।

कैशिंग के लिए, आप ब्राउज़र को नियंत्रित नहीं कर सकते हैं लेकिन आप इसे सर्वर के माध्यम से सेट कर सकते हैं। यदि आपको मांग पर वास्तव में ताजा संसाधन लोड करने की आवश्यकता है, तो आप ताजा संसाधन लोड करने के लिए cache buster technique का उपयोग कर सकते हैं।

1

कहते हैं भले ही अपने प्रश्न "जावास्क्रिप्ट का उपयोग कर", तो आप किसी भी संपत्ति को पहले से लोड करने के लिए एक लिंक टैग की prefetch विशेषता का उपयोग कर सकते हैं। (अगस्त 10, 2016) इस लेखन के रूप में यह सफारी में समर्थित नहीं है, लेकिन इसके अलावा सभी जगह है: कि IE 9 http://caniuse.com/#search=prefetch

नोट:

<link rel="prefetch" href="(url)">

अधिक समर्थन पर जानकारी यहाँ , 10 caniuse मैट्रिक्स में सूचीबद्ध नहीं हैं क्योंकि माइक्रोसॉफ्ट ने उनके लिए समर्थन बंद कर दिया है।

तो अगर आप वास्तव में जावास्क्रिप्ट का उपयोग करने पर अटक कर रहे थे, आप jQuery का उपयोग गतिशील रूप में अच्छी तरह ;-) अपने पृष्ठ पर इन तत्वों को जोड़ने के

+0

अच्छा अच्छा अच्छा अच्छा है! –

1

मैं एक ऐसी ही तकनीक का उपयोग छवियों Lazyload को सकता है, लेकिन मदद नहीं कर सकता लेकिन ध्यान दें कि जावास्क्रिप्ट पहले लोडिंग पर ब्राउज़र कैश तक नहीं पहुंचता है।

मेरे उदाहरण:

मैं 4 छवियों के साथ मेरे होमपेज पर एक घूर्णन बैनर स्लाइडर 2 सेकंड प्रतीक्षा करें, की तुलना में जावास्क्रिप्ट अगली छवि लोड करता है, है 2 सेकंड, आदि इंतजार कर रहा है

इन छवियों में अद्वितीय यूआरएल होते हैं जो जब भी मैं उन्हें संशोधित करता हूं, तो उन्हें कैशिंग हेडर मिलते हैं जो ब्राउज़र में एक वर्ष तक कैश करेंगे।

max-age: 31536000, public 

अब जब मैं Chrome DevTools खोलने के लिए और 'डे अक्षम कैश' विकल्प सक्रिय नहीं है सुनिश्चित करें और पहली बार के लिए पृष्ठ लोड (कैश को साफ़ करने के बाद) सभी छवियों को लाने के लिए और 200 स्थिति है। बैनर में सभी छवियों के पूर्ण चक्र के बाद नेटवर्क अनुरोध बंद हो जाते हैं और कैश की गई छवियों का उपयोग किया जाता है।

अब जब मैं नियमित रीफ्रेश करता हूं या उपपृष्ठ पर जाता हूं और वापस क्लिक करता हूं, तो कैश में मौजूद छवियों को अनदेखा किया जाता है। मैं क्रोम devtools के नेटवर्क टैब में "डिस्क कैश से" एक ग्रे संदेश देखने की उम्मीद करेंगे। इसके बजाय मैं ग्रे के बजाए ग्रीन स्टेटस सर्कल के साथ हर दो सेकंड में अनुरोधों को पास करता हूं, मुझे डेटा स्थानांतरित किया जाता है, इसलिए मुझे लगता है कि जावास्क्रिप्ट से कैश का उपयोग नहीं किया जाता है। जब भी पृष्ठ लोड हो जाता है तो यह छवि को आसानी से प्राप्त करता है।

इसलिए होमपेज के प्रत्येक अनुरोध छवि की कैशिंग नीति के बावजूद 4 अनुरोधों को ट्रिगर करता है।

उपर्युक्त को ध्यान में रखते हुए और नए http2 मानक अधिकांश वेबसर्वर और ब्राउज़र अब समर्थन करते हैं, मुझे लगता है कि lazyloading का उपयोग करना बंद करना बेहतर है क्योंकि http2 सभी छवियों को लगभग एक साथ लोड करेगा।

यदि यह क्रोम डेवटोल्स में एक बग है तो यह वास्तव में आश्चर्य की बात है कि मेरे किसी ने अभी तक यह नहीं देखा है। ;)

यदि यह सच है, तो lazyloading का उपयोग केवल बैंडविड्थ उपयोग को बढ़ाता है।

अगर मैं गलत हूं तो कृपया मुझे सही करें। :)

0

मैं हमेशा छवियों को लोड करने के लिए Konva JS: Image Events में उल्लिखित उदाहरण का उपयोग करना पसंद करता हूं।

  1. आप, वस्तु या सरणी के रूप में छवि यूआरएल की एक सूची की आवश्यकता है उदाहरण के लिए:

    var sources = { lion: '/assets/lion.png', monkey: '/assets/monkey.png' };

  2. परिभाषित समारोह परिभाषा तथा उसे कॉलबैक फ़ंक्शन जहां यह छवि URL की सूची प्राप्त करता है अपने तर्कों की सूची में है, इसलिए जब यह छवि के लोड न हो आप अपने वेब पेज पर excution शुरू कर सकते हैं:

function loadImages(sources, callback) { 
 
       var images = {}; 
 
       var loadedImages = 0; 
 
       var numImages = 0; 
 
       for (var src in sources) { 
 
        numImages++; 
 
       } 
 
       for (var src in sources) { 
 
        images[src] = new Image(); 
 
        images[src].onload = function() { 
 
         if (++loadedImages >= numImages) { 
 
          callback(images); 
 
         } 
 
        }; 
 
        images[src].src = sources[src]; 
 
       } 
 
      }

  1. अंत में, आप फ़ंक्शन को कॉल करने की जरूरत है। आप से उदाहरण के लिए यह कॉल कर सकते हैं jQuery के दस्तावेज तैयार

$(document).ready(function(){ loadImages(sources, buildStage); });

संबंधित मुद्दे