पब्लिश किया गया: 20 फ़रवरी, 2025
बड़े एआई मॉडल को भरोसेमंद तरीके से डाउनलोड करना एक मुश्किल काम है. अगर उपयोगकर्ताओं का इंटरनेट कनेक्शन बंद हो जाता है या वे आपकी वेबसाइट या वेब ऐप्लिकेशन बंद कर देते हैं, तो वे आंशिक रूप से डाउनलोड की गई मॉडल फ़ाइलें खो देते हैं. साथ ही, आपके पेज पर वापस आने पर उन्हें फिर से शुरू करना पड़ता है. Background Fetch API को प्रोग्रेसिव बेहतर बनाने के तौर पर इस्तेमाल करके, उपयोगकर्ता अनुभव को काफ़ी बेहतर बनाया जा सकता है.
सर्विस वर्कर रजिस्टर करना
बैकग्राउंड फ़ेच एपीआई का इस्तेमाल करने के लिए, आपके ऐप्लिकेशन को सर्विस वर्कर रजिस्टर करना होगा.
if ('serviceWorker' in navigator) {
window.addEventListener('load', async () => {
const registration = await navigator.serviceWorker.register('sw.js');
console.log('Service worker registered for scope', registration.scope);
});
}
बैकग्राउंड फ़ेच को ट्रिगर करना
ब्राउज़र फ़ेच करते समय, उपयोगकर्ता को प्रोग्रेस दिखती है. साथ ही, उसे डाउनलोड रद्द करने का तरीका भी दिखता है. डाउनलोड पूरा होने के बाद, ब्राउज़र, सेवा वर्कर को शुरू करता है और ऐप्लिकेशन, रिस्पॉन्स के आधार पर कार्रवाई कर सकता है.
Background Fetch API, ऑफ़लाइन होने पर भी फ़ेच करने की प्रोसेस शुरू कर सकता है. उपयोगकर्ता के दोबारा कनेक्ट होने के साथ ही, डाउनलोड शुरू हो जाता है. अगर उपयोगकर्ता ऑफ़लाइन हो जाता है, तो प्रोसेस तब तक के लिए रुक जाती है, जब तक उपयोगकर्ता फिर से ऑनलाइन नहीं हो जाता.
नीचे दिए गए उदाहरण में, उपयोगकर्ता Gemma 2B डाउनलोड करने के लिए बटन पर क्लिक करता है. फ़ेच करने से पहले, हम यह जांच करते हैं कि मॉडल को पहले डाउनलोड और कैश किया गया था या नहीं, ताकि हम ज़रूरत से ज़्यादा संसाधनों का इस्तेमाल न करें. अगर यह कैश मेमोरी में सेव नहीं है, तो हम बैकग्राउंड में फ़ेच करने की प्रोसेस शुरू कर देते हैं.
const FETCH_ID = 'gemma-2b';
const MODEL_URL =
'https://storage.googleapis.com/jmstore/kaggleweb/grader/g-2b-it-gpu-int4.bin';
downloadButton.addEventListener('click', async (event) => {
// If the model is already downloaded, return it from the cache.
const modelAlreadyDownloaded = await caches.match(MODEL_URL);
if (modelAlreadyDownloaded) {
const modelBlob = await modelAlreadyDownloaded.blob();
// Do something with the model.
console.log(modelBlob);
return;
}
// The model still needs to be downloaded.
// Feature detection and fallback to classic `fetch()`.
if (!('BackgroundFetchManager' in self)) {
try {
const response = await fetch(MODEL_URL);
if (!response.ok || response.status !== 200) {
throw new Error(`Download failed ${MODEL_URL}`);
}
const modelBlob = await response.blob();
// Do something with the model.
console.log(modelBlob);
return;
} catch (err) {
console.error(err);
}
}
// The service worker registration.
const registration = await navigator.serviceWorker.ready;
// Check if there's already a background fetch running for the `FETCH_ID`.
let bgFetch = await registration.backgroundFetch.get(FETCH_ID);
// If not, start a background fetch.
if (!bgFetch) {
bgFetch = await registration.backgroundFetch.fetch(FETCH_ID, MODEL_URL, {
title: 'Gemma 2B model',
icons: [
{
src: 'icon.png',
size: '128x128',
type: 'image/png',
},
],
downloadTotal: await getResourceSize(MODEL_URL),
});
}
});
getResourceSize()
फ़ंक्शन, डाउनलोड किए गए डेटा का बाइट साइज़ दिखाता है. इसे लागू करने के लिए, HEAD
अनुरोध करें.
const getResourceSize = async (url) => {
try {
const response = await fetch(url, { method: 'HEAD' });
if (response.ok) {
return response.headers.get('Content-Length');
}
console.error(`HTTP error: ${response.status}`);
return 0;
} catch (error) {
console.error('Error fetching content size:', error);
return 0;
}
};
डाउनलोड की प्रोग्रेस की जानकारी
बैकग्राउंड फ़ेच शुरू होने के बाद, ब्राउज़र BackgroundFetchRegistration
दिखाता है.
इसका इस्तेमाल करके, उपयोगकर्ता को डाउनलोड की प्रोग्रेस के बारे में बताया जा सकता है. इसके लिए, progress
इवेंट का इस्तेमाल करें.
bgFetch.addEventListener('progress', (e) => {
// There's no download progress yet.
if (!bgFetch.downloadTotal) {
return;
}
// Something went wrong.
if (bgFetch.failureReason) {
console.error(bgFetch.failureReason);
}
if (bgFetch.result === 'success') {
return;
}
// Update the user about progress.
console.log(`${bgFetch.downloaded} / ${bgFetch.downloadTotal}`);
});
फ़ेच पूरा होने की सूचना उपयोगकर्ताओं और क्लाइंट को देना
बैकग्राउंड फ़ेच पूरा होने पर, आपके ऐप्लिकेशन के सेवा वर्कर को एक backgroundfetchsuccess
इवेंट मिलता है.
यह कोड, सेवा वर्कर में शामिल होता है. आखिर में मौजूद updateUI()
कॉल की मदद से, ब्राउज़र के इंटरफ़ेस को अपडेट किया जा सकता है, ताकि उपयोगकर्ता को बैकग्राउंड में फ़ेच किए गए डेटा के बारे में सूचना दी जा सके. आखिर में, क्लाइंट को डाउनलोड पूरा होने के बारे में बताएं. उदाहरण के लिए, postMessage()
का इस्तेमाल करके.
self.addEventListener('backgroundfetchsuccess', (event) => {
// Get the background fetch registration.
const bgFetch = event.registration;
event.waitUntil(
(async () => {
// Open a cache named 'downloads'.
const cache = await caches.open('downloads');
// Go over all records in the background fetch registration.
// (In the running example, there's just one record, but this way
// the code is future-proof.)
const records = await bgFetch.matchAll();
// Wait for the response(s) to be ready, then cache it/them.
const promises = records.map(async (record) => {
const response = await record.responseReady;
await cache.put(record.request, response);
});
await Promise.all(promises);
// Update the browser UI.
event.updateUI({ title: 'Model downloaded' });
// Inform the clients that the model was downloaded.
self.clients.matchAll().then((clientList) => {
for (const client of clientList) {
client.postMessage({
message: 'download-complete',
id: bgFetch.id,
});
}
});
})(),
);
});
सेवा वर्कर से मैसेज पाना
क्लाइंट पर डाउनलोड पूरा होने के बारे में भेजा गया मैसेज पाने के लिए,
message
इवेंट के लिए सुनें. सेवा वर्कर से मैसेज मिलने के बाद, एआई मॉडल के साथ काम किया जा सकता है और उसे Cache API की मदद से सेव किया जा सकता है.
navigator.serviceWorker.addEventListener('message', async (event) => {
const cache = await caches.open('downloads');
const keys = await cache.keys();
for (const key of keys) {
const modelBlob = await cache
.match(key)
.then((response) => response.blob());
// Do something with the model.
console.log(modelBlob);
}
});
बैकग्राउंड में फ़ेच करने की प्रोसेस रद्द करना
उपयोगकर्ता को किसी डाउनलोड को रद्द करने की अनुमति देने के लिए, BackgroundFetchRegistration
के abort()
तरीके का इस्तेमाल करें.
const registration = await navigator.serviceWorker.ready;
const bgFetch = await registration.backgroundFetch.get(FETCH_ID);
if (!bgFetch) {
return;
}
await bgFetch.abort();
मॉडल को कैश मेमोरी में सेव करना
डाउनलोड किए गए मॉडल को कैश मेमोरी में सेव करें, ताकि आपके उपयोगकर्ता मॉडल को सिर्फ़ एक बार डाउनलोड करें. बैकग्राउंड फ़ेच एपीआई, डाउनलोड करने के अनुभव को बेहतर बनाता है. हालांकि, आपको हमेशा क्लाइंट-साइड एआई में सबसे छोटे मॉडल का इस्तेमाल करना चाहिए.
इन एपीआई की मदद से, उपयोगकर्ताओं के लिए क्लाइंट-साइड एआई का बेहतर अनुभव दिया जा सकता है.
डेमो
इस तरीके को पूरी तरह से लागू करने का उदाहरण, डेमो और उसके सोर्स कोड में देखा जा सकता है.

आभार
इस गाइड की समीक्षा, फ़्रांकोइस बफ़ोर, ऐंड्रे बंदरा, सेबैस्टियन बेंज, मौड नाल्पस, और ऐलेक्ज़ेंड्रा क्लेपर ने की है.