2017-04-26 25 views
5

मान लीजिए मैं यूआरएल इसलिए तरह की की एक सूची है:प्रतिक्रिया में छवियों को कैसे कैश करें?

[ '/images/1', '/images/2', ... ]

और मैं उन लोगों में से n prefetch करने के लिए इतना है कि छवियों के बीच संक्रमण तेजी से होता है चाहता हूँ। क्या मैं अब componentWillMount में कर रहा हूँ है निम्नलिखित:

componentWillMount() { 
     const { props } = this; 
     const { prefetchLimit = 1, document = dummyDocument, imgNodes } = props; 
     const { images } = document; 
     const toPrefecth = take(prefetchLimit, images); 
     const merged = zip(toPrefecth, imgNodes); 

     merged.forEach(([url, node]) => { 
     node.src = url; 
     }); 
    } 

imgNodes के साथ ऐसा तरह परिभाषित किया जा रहा:

imgNodes: times(_ => new window.Image(), props.prefetchLimit),

और times, zip, और takeramda से आ रही।

अब जब मैं उन यूआरएल का उपयोग के अंदर इतना की तरह प्रतिक्रिया:

<img src={url} />

यह जहां यूआरएल प्रयोग किया जाता है की परवाह किए बिना Etag और Expire टैग के अनुसार ब्राउज़र कैश करता है। जब भी हम दृश्य के अंदर n - 1 हिट करते हैं, तो imgNodes को उसी तरीके से पुन: उपयोग करते हुए, मैं अगले n छवियों को प्रीफ़ेच करने के लिए इसका उपयोग करने की भी योजना बना रहा हूं।

मेरा प्रश्न हैं:

  • इस यहाँ तक कि एक वैध विचार 100 + घटक है कि इस विचार का उपयोग करेगा दे लेकिन केवल 1 एक समय में दिखाई जाएगी है?

  • क्या मैं इसे कर कर स्मृति समस्याओं में भाग लेगा? मुझे लगता है कि imgNodes घटक को अनमाउंट किए जाने पर कचरा इकट्ठा किया जाएगा।

हम redux उपयोग कर रहे हैं तो मैं दुकान में इन छवियों को बचा सकता है लेकिन यह है कि जैसे मैं कैशिंग से निपटने कर रहा हूँ के बजाय ब्राउज़र की प्राकृतिक कैश का लाभ लगता है।

यह कितना बुरा विचार है?

+0

क्या आप इसके साथ कहीं भी गए थे? मुझे दिलचस्पी है ... –

+0

@MathieuK। हमारे पास मूल रूप से समान संरचना/इंटरफेस है जैसा ऊपर वर्णित है, सामान्य HTTP कैशिंग का लाभ उठा रहा है। –

+1

तो आप ब्राउज़र/HTTP के डिफ़ॉल्ट व्यवहार पर भरोसा करते हैं? –

उत्तर

1

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

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

आप इसे वादे के साथ हल करना चाहते हैं।

// create an utility function somewhere 
const checkImage = path => 
    new Promise(resolve => { 
     const img = new Image() 
     img.onload =() => resolve(path) 
     img.onerror =() => reject() 

     img.src = path 
    }) 

... 

// then in your component 
constructor(props) { 
    super(props) 
    this.state = { imagesLoaded: false } 
} 

// doesn't really matter whether you do it in componentWillMount or componentDidMount 
    componentWillMount() { 
     Promise.all(
      R.take(limit, imgUrls) 
      .map(checkImage) 
     ).then(() => this.setState({ imagesLoaded: true }), 
       () => console.error('could not load images')) 
    } 

render =() => 
    this.state.imagesLoaded 
     ? <BeautifulComponent /> 
     : <Skeleton /> 

स्मृति खपत के संबंध में - मुझे नहीं लगता कि कुछ भी बुरा होगा। ब्राउज़र सामान्य रूप से समांतर xhr अनुरोधों की संख्या को सीमित करते हैं, इसलिए आप किसी भी चीज को क्रैश करने के लिए एक विशाल ढेर उपयोग स्पाइक बनाने में सक्षम नहीं होंगे, क्योंकि अप्रयुक्त छवियां कचरा एकत्रित होंगी (फिर भी, ब्राउज़र कैश में संरक्षित)।

रेडक्स स्टोर ऐप स्टेटस स्टोर करने के लिए एक जगह है, ऐप संपत्ति नहीं, लेकिन फिर भी आप वहां कोई वास्तविक छवियां स्टोर नहीं कर पाएंगे।

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