å€§èŠæš¡ããŠã³ããŒãã®ããã®å¹ççãªããã³ããšã³ãããã¯ã°ã©ãŠã³ããã§ããã®å®è£ æ¹æ³ãåŠã³ãã°ããŒãã«ãªWebã¢ããªã§ã¹ã ãŒãºãªãŠãŒã¶ãŒäœéšãšæé©ãªããã©ãŒãã³ã¹ã確ä¿ããŸãã
ããã³ããšã³ãã®ããã¯ã°ã©ãŠã³ããã§ããïŒå€§èŠæš¡ããŠã³ããŒã管çããã¹ã¿ãŒãã
仿¥ã®Webã¢ããªã±ãŒã·ã§ã³ã§ã¯ããŠãŒã¶ãŒã¯å€§èŠæš¡ãªããŠã³ããŒããæ±ãå Žåã§ããã·ãŒã ã¬ã¹ã§å¿çæ§ã®é«ãäœéšãæåŸ ããŠããŸããå¹ççãªããã¯ã°ã©ãŠã³ããã§ããã¡ã«ããºã ãå®è£ ããããšã¯ãããžãã£ããªãŠãŒã¶ãŒäœéšãæäŸããã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãæé©åããããã«äžå¯æ¬ ã§ãããã®ã¬ã€ãã§ã¯ãå€§èŠæš¡ããŠã³ããŒãã管çããããã®ããã³ããšã³ãããã¯ã°ã©ãŠã³ããã§ããæè¡ã®å æ¬çãªæŠèŠã説æãããã¡ã€ã«ãµã€ãºããããã¯ãŒã¯ç¶æ³ã«é¢ããããã¢ããªã±ãŒã·ã§ã³ãå¿çæ§ãä¿ã¡ããŠãŒã¶ãŒãã¬ã³ããªãŒã§ããç¶ããããšãä¿èšŒããŸãã
ãªãããã¯ã°ã©ãŠã³ããã§ãããéèŠãªã®ã
ãŠãŒã¶ãŒãããŠã³ããŒããéå§ãããšããã©ãŠã¶ã¯éåžžããã®ãªã¯ãšã¹ãããã©ã¢ã°ã©ãŠã³ãã§åŠçããŸããããã¯ããã€ãã®åé¡ãåŒãèµ·ããå¯èœæ§ããããŸãïŒ
- UIã®ããªãŒãºïŒ ãã©ãŠã¶ã®ã¡ã€ã³ã¹ã¬ããããããã¯ãããUIãããªãŒãºãããå¿çããªããªã£ããããããšããããŸãã
- 壿ªãªãŠãŒã¶ãŒäœéšïŒ ãŠãŒã¶ãŒã¯é å»¶ããã©ã¹ãã¬ãŒã·ã§ã³ãçµéšããã¢ããªã±ãŒã·ã§ã³ã«å¯ŸããåŠå®çãªå°è±¡ã«ã€ãªããå¯èœæ§ããããŸãã
- ãããã¯ãŒã¯ã®ããã«ããã¯ïŒ è€æ°ã®åæããŠã³ããŒãããŠãŒã¶ãŒã®åž¯åå¹ ã飜åãããå šäœçãªãããã¯ãŒã¯ããã©ãŒãã³ã¹ã«åœ±é¿ãäžããå¯èœæ§ããããŸãã
- ããŠã³ããŒãã®äžæïŒ ãŠãŒã¶ãŒããã©ãŠã¶ã®ã¿ããéããããä»ã®ããŒãžã«ç§»åããããããšãããŠã³ããŒããäžæãããæåããããçŽãå¿ èŠãçããããšããããŸãã
ããã¯ã°ã©ãŠã³ããã§ããã¯ãããŠã³ããŒããå¥ã®ã¹ã¬ããã§å®è¡ãããããšã§ãããã®åé¡ã«å¯ŸåŠããã¡ã€ã³ã¹ã¬ãããžã®åœ±é¿ãæå°éã«æããå šäœçãªãŠãŒã¶ãŒäœéšãåäžãããŸãã
äž»èŠãªæŠå¿µãšæè¡
ããã³ããšã³ãã®ããã¯ã°ã©ãŠã³ããã§ãããå®è£ ããããã«ãããã€ãã®æè¡ããã¯ããã¯ã䜿çšã§ããŸãïŒ
1. Service Worker
Service Workerã¯ããã©ãŠã¶ã®ã¡ã€ã³ã¹ã¬ãããšã¯å¥ã«ããã¯ã°ã©ãŠã³ãã§å®è¡ãããJavaScriptãã¡ã€ã«ã§ããWebã¢ããªã±ãŒã·ã§ã³ãšãããã¯ãŒã¯ã®éã®ãããã·ãšããŠæ©èœãããªãã©ã€ã³ãµããŒããããã·ã¥éç¥ãããã¯ã°ã©ãŠã³ãåæãªã©ã®æ©èœãå¯èœã«ããŸããService Workerã¯ãææ°ã®ããã¯ã°ã©ãŠã³ããã§ããå®è£ ã®åºç€ãšãªããŸãã
äŸïŒService Workerã®ç»é²
```javascript if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/service-worker.js') .then(registration => { console.log('Service Worker registered with scope:', registration.scope); }) .catch(error => { console.error('Service Worker registration failed:', error); }); } ```
2. Streams API
Streams APIã¯ãããŒã¿ãå©çšå¯èœã«ãªãã«ã€ããŠæ®µéçã«åŠçããæ¹æ³ãæäŸããŸããããã¯ããã¡ã€ã«å šäœãäžåºŠã«ã¡ã¢ãªã«èªã¿èŸŒãã®ã§ã¯ãªããããŒã¿ããã£ã³ã¯ïŒå¡ïŒã§åŠçã§ãããããå€§èŠæš¡ãªããŠã³ããŒãã«ç¹ã«åœ¹ç«ã¡ãŸãã
äŸïŒStreams APIã䜿çšããããŒã¿ã®ããŠã³ããŒããšåŠç
```javascript fetch('/large-file.zip') .then(response => { const reader = response.body.getReader(); let receivedLength = 0; let chunks = []; return new Promise((resolve, reject) => { function pump() { reader.read().then(({ done, value }) => { if (done) { resolve(chunks); return; } chunks.push(value); receivedLength += value.length; console.log('Received', receivedLength, 'bytes'); pump(); }).catch(reject); } pump(); }); }) .then(chunks => { // Process the downloaded chunks console.log('Download complete!', chunks); }) .catch(error => { console.error('Download failed:', error); }); ```
3. `fetch()` API
`fetch()` APIã¯`XMLHttpRequest`ã®çŸä»£çãªä»£æ¿ææ®µã§ããããããã¯ãŒã¯ãªã¯ãšã¹ããããæè»ãã€åŒ·åã«è¡ãæ¹æ³ãæäŸããŸãããªã¯ãšã¹ããšã¬ã¹ãã³ã¹ã®ã¹ããªãŒã ãªã©ã®æ©èœããµããŒãããŠãããããã¯ã°ã©ãŠã³ããã§ããã®ã·ããªãªã«çæ³çã§ãã
4. Background Fetch APIïŒå®éšçæ©èœïŒ
Background Fetch APIã¯ãããã¯ã°ã©ãŠã³ãã§ã®å€§èŠæš¡ãªããŠã³ããŒããåŠçããããã«ç¹å¥ã«èšèšãããå°çšAPIã§ããããŠã³ããŒãã®ç®¡çã鲿ã®è¿œè·¡ãäžæã®åŠçãè¡ãããã®æšæºåãããæ¹æ³ãæäŸããŸãããã ãããã®APIã¯ãŸã å®é𿮵éã§ããããã¹ãŠã®ãã©ãŠã¶ã§ãµããŒããããŠããããã§ã¯ãªãããšã«æ³šæãå¿ èŠã§ããäºææ§ã確ä¿ããããã«ãããªãã£ã«ãæ©èœæ€åºã®äœ¿çšãæ€èšããŠãã ããã
ããã¯ã°ã©ãŠã³ããã§ããã®å®è£ ïŒã¹ããããã€ã¹ãããã¬ã€ã
以äžã«ãService WorkerãšStreams APIã䜿çšããŠããã¯ã°ã©ãŠã³ããã§ãããå®è£ ããããã®ã¹ããããã€ã¹ãããã¬ã€ãã瀺ããŸãïŒ
ã¹ããã1ïŒService Workerãç»é²ãã
`service-worker.js`ãã¡ã€ã«ãäœæããã¡ã€ã³ã®JavaScriptãã¡ã€ã«ã§ç»é²ããŸãïŒäžèšã®äŸãåç §ïŒã
ã¹ããã2ïŒService Workerã§ãã§ãããªã¯ãšã¹ããã€ã³ã¿ãŒã»ãããã
`service-worker.js`ãã¡ã€ã«å ã§ã`fetch`ã€ãã³ãããªãã¹ã³ãã倧ããªãã¡ã€ã«ãžã®ãªã¯ãšã¹ããã€ã³ã¿ãŒã»ããããŸããããã«ãããããã¯ã°ã©ãŠã³ãã§ããŠã³ããŒããåŠçã§ããããã«ãªããŸãã
```javascript self.addEventListener('fetch', event => { if (event.request.url.includes('/large-file.zip')) { event.respondWith(handleBackgroundFetch(event.request)); } }); async function handleBackgroundFetch(request) { try { const response = await fetch(request); // Use the Streams API to process the response const reader = response.body.getReader(); // ... (process the stream and save the data) return new Response('Download in progress', { status: 202 }); // Accepted } catch (error) { console.error('Background fetch failed:', error); return new Response('Download failed', { status: 500 }); // Internal Server Error } } ```
ã¹ããã3ïŒã¹ããªãŒã ãåŠçããããŒã¿ãä¿åãã
`handleBackgroundFetch`颿°å ã§ãStreams APIã䜿çšããŠã¬ã¹ãã³ã¹ããã£ããã£ã³ã¯ã§èªã¿åããŸãããã®åŸããããã®ãã£ã³ã¯ãIndexedDBãFile System Access APIïŒå©çšå¯èœãªå ŽåïŒãªã©ã®ããŒã«ã«ã¹ãã¬ãŒãžã¡ã«ããºã ã«ä¿åããŠãåŸã§ååŸã§ããããã«ããŸããIndexedDBã®æäœãç°¡çŽ åããããã«ã`idb`ã®ãããªã©ã€ãã©ãªã®äœ¿çšãæ€èšããŠãã ããã
```javascript // Example using IndexedDB (requires an IndexedDB library like 'idb') import { openDB } from 'idb'; async function handleBackgroundFetch(request) { try { const response = await fetch(request); const reader = response.body.getReader(); const db = await openDB('my-download-db', 1, { upgrade(db) { db.createObjectStore('chunks'); } }); let chunkIndex = 0; while (true) { const { done, value } = await reader.read(); if (done) { break; } await db.put('chunks', value, chunkIndex); chunkIndex++; // Send progress update to the UI (optional) self.clients.matchAll().then(clients => { clients.forEach(client => client.postMessage({ type: 'download-progress', progress: chunkIndex })); }); } await db.close(); return new Response('Download complete', { status: 200 }); // OK } catch (error) { console.error('Background fetch failed:', error); return new Response('Download failed', { status: 500 }); } } ```
ã¹ããã4ïŒãã¡ã€ã«ãåæ§æãã
ãã¹ãŠã®ãã£ã³ã¯ãããŠã³ããŒããããŠä¿åãããããããããå ã®ãã¡ã€ã«ã«åæ§æã§ããŸããéžæããã¹ãã¬ãŒãžã¡ã«ããºã ïŒäŸïŒIndexedDBïŒãããã£ã³ã¯ãæ£ããé åºã§ååŸããçµåããŸãã
```javascript async function reassembleFile() { const db = await openDB('my-download-db', 1); const tx = db.transaction('chunks', 'readonly'); const store = tx.objectStore('chunks'); let chunks = []; let cursor = await store.openCursor(); while (cursor) { chunks.push(cursor.value); cursor = await cursor.continue(); } await tx.done; await db.close(); // Combine the chunks into a single Blob const blob = new Blob(chunks); // Create a download link const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'downloaded-file.zip'; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } ```
ã¹ããã5ïŒããŠã³ããŒãã®é²æã衚瀺ãã
ããŠã³ããŒãã®é²æã衚瀺ããããšã§ããŠãŒã¶ãŒã«èŠèŠçãªãã£ãŒãããã¯ãæäŸããŸãã`postMessage` APIã䜿çšããŠãService Workerããã¡ã€ã³ã¹ã¬ããã«é²ææŽæ°ãéä¿¡ã§ããŸãã
```javascript // In the service worker (as shown in step 3): self.clients.matchAll().then(clients => { clients.forEach(client => client.postMessage({ type: 'download-progress', progress: chunkIndex })); }); // In the main thread: navigator.serviceWorker.addEventListener('message', event => { if (event.data.type === 'download-progress') { const progress = event.data.progress; // Update the progress bar in the UI console.log('Download progress:', progress); } }); ```
é«åºŠãªãã¯ããã¯ãšèæ ®äºé
1. ã¬ãžã¥ãŒã ïŒåéå¯èœïŒããŠã³ããŒã
äžæãããããŠã³ããŒãããŠãŒã¶ãŒãåéã§ããããã«ãã¬ãžã¥ãŒã ããŠã³ããŒããå®è£ ããŸããããã¯ã`fetch`ãªã¯ãšã¹ãã®`Range`ããããŒã䜿çšããŠãããŠã³ããŒãããããã¡ã€ã«ã®ç¯å²ãæå®ããããšã§å®çŸã§ããŸãããããæ©èœããã«ã¯ããµãŒããŒãç¯å²ãªã¯ãšã¹ãããµããŒãããŠããå¿ èŠããããŸãã
```javascript // Example of a resumable download async function resumableDownload(url, startByte = 0) { const response = await fetch(url, { headers: { 'Range': `bytes=${startByte}-` } }); if (response.status === 206) { // Partial Content // ... process the response stream and append to existing file } else { // Handle errors or start from the beginning } } ```
2. ãšã©ãŒãã³ããªã³ã°ãšãªãã©ã€ã¡ã«ããºã
ãããã¯ãŒã¯ãšã©ãŒããã®ä»ã®åé¡ãé©åã«åŠçããããã«ãå ç¢ãªãšã©ãŒãã³ããªã³ã°ãå®è£ ããŸãã倱æããããŠã³ããŒããèªåçã«å詊è¡ããããã«ãææ°ããã¯ãªãä»ãã®ãªãã©ã€ã¡ã«ããºã ã®äœ¿çšãæ€èšããŠãã ããã
3. ãã£ãã·ã³ã°æŠç¥
äžèŠãªããŠã³ããŒããé¿ããããã«ããã£ãã·ã³ã°æŠç¥ãå®è£ ããŸããService Workerã®Cache APIã䜿çšããŠãããŠã³ããŒããããã¡ã€ã«ãä¿åããå©çšå¯èœãªå Žåã¯ãã£ãã·ã¥ããæäŸã§ããŸããã¢ããªã±ãŒã·ã§ã³ã®ããŒãºã«å¿ããŠãããã£ãã·ã¥ãã¡ãŒã¹ããæ¬¡ã«ãããã¯ãŒã¯ããããããã¯ãŒã¯ãã¡ãŒã¹ããæ¬¡ã«ãã£ãã·ã¥ããªã©ã®æŠç¥ã®äœ¿çšãæ€èšããŠãã ããã
4. ããŠã³ããŒãã®åªå é äœä»ã
ã¢ããªã±ãŒã·ã§ã³ãè€æ°ã®åæããŠã³ããŒããèš±å¯ããå ŽåãæãéèŠãªããŠã³ããŒããæåã«å®äºããããã«ãåªå é äœä»ãã¡ã«ããºã ã®å®è£ ãæ€èšããŸãããã¥ãŒã䜿çšããŠããŠã³ããŒãã管çãããŠãŒã¶ãŒã®å¥œã¿ããã®ä»ã®åºæºã«åºã¥ããŠåªå é äœãä»ããããšãã§ããŸãã
5. ã»ãã¥ãªãã£ã«é¢ããèæ ®äºé
ã»ãã¥ãªãã£ã®è匱æ§ãé²ãããã«ãããŠã³ããŒãããããã¡ã€ã«ã¯åžžã«æ€èšŒããŠãã ããããã¡ã€ã«ããã©ãŠã¶ã«ãã£ãŠæ£ããåŠçãããããã«ãé©åãªãã¡ã€ã«æ¡åŒµåãšMIMEã¿ã€ãã䜿çšããŸããã³ã³ãã³ãã»ãã¥ãªãã£ããªã·ãŒïŒCSPïŒã䜿çšããŠãã¢ããªã±ãŒã·ã§ã³ãèªã¿èŸŒãããªãœãŒã¹ã®çš®é¡ãå¶éããããšãæ€èšããŠãã ããã
6. åœéåãšããŒã«ã©ã€ãŒãŒã·ã§ã³
ããŠã³ããŒã管çã·ã¹ãã ãåœéåãšããŒã«ã©ã€ãŒãŒã·ã§ã³ããµããŒãããŠããããšã確èªããŠãã ããã鲿ã¡ãã»ãŒãžããšã©ãŒã¡ãã»ãŒãžããŠãŒã¶ãŒã®åžæããèšèªã§è¡šç€ºããŸããç°ãªããã¡ã€ã«ãšã³ã³ãŒãã£ã³ã°ãæåã»ãããæ£ããåŠçããŠãã ããã
äŸïŒã°ããŒãã«ãªEã©ãŒãã³ã°ãã©ãããã©ãŒã
ããŠã³ããŒãå¯èœãªã³ãŒã¹ææïŒPDFããããªãªã©ïŒãæäŸããã°ããŒãã«ãªEã©ãŒãã³ã°ãã©ãããã©ãŒã ãæ³åããŠã¿ãŠãã ãããããã¯ã°ã©ãŠã³ããã§ããã䜿çšããããšã§ããã®ãã©ãããã©ãŒã ã¯æ¬¡ã®ããšãå¯èœã«ãªããŸãïŒ
- ã€ã³ã¿ãŒããããäžå®å®ãªå°åïŒäŸïŒéçºéäžåœã®èŸ²æéšïŒã®åŠçã§ããæ¥ç¶ãæç¶çã§ãã£ãŠãã³ã³ãã³ãã®ããŠã³ããŒããç¶ç¶ã§ããããã«ããŸããããã§ã¯ã¬ãžã¥ãŒã ããŠã³ããŒããéåžžã«éèŠã§ãã
- 倧ããªãããªè¬çŸ©ã®ããŠã³ããŒãäžã«UIãããªãŒãºããã®ãé²ããã¹ã ãŒãºãªåŠç¿äœéšãä¿èšŒããŸãã
- ãŠãŒã¶ãŒã«ããŠã³ããŒãã®åªå é äœãéžæãããªãã·ã§ã³ãæäŸããŸããäŸãã°ããªãã·ã§ã³ã®è£è¶³è³æãããä»é±ã®è¬çŸ©è³æãåªå ãããããšãã§ããŸãã
- ç°ãªããããã¯ãŒã¯é床ã«èªåçã«é©å¿ããããŠã³ããŒãã®ãã£ã³ã¯ãµã€ãºã調æŽããŠããã©ãŒãã³ã¹ãæé©åããŸãã
ãã©ãŠã¶ã®äºææ§
Service Workerã¯çŸä»£ã®ãã©ãŠã¶ã§åºããµããŒããããŠããŸããããããäžéšã®å€ããã©ãŠã¶ã§ã¯ãµããŒããããŠããªãå ŽåããããŸããæ©èœæ€åºã䜿çšããŠService Workerã®ãµããŒãã確èªããå€ããã©ãŠã¶åãã«ãã©ãŒã«ããã¯ã¡ã«ããºã ãæäŸããŠãã ãããBackground Fetch APIã¯ãŸã å®é𿮵éãªã®ã§ãããåºãäºææ§ã確ä¿ããããã«ããªãã£ã«ã®äœ¿çšãæ€èšããŠãã ããã
çµè«
å€§èŠæš¡ããŠã³ããŒãã®ããã®å¹ççãªããã³ããšã³ãããã¯ã°ã©ãŠã³ããã§ããã®å®è£ ã¯ãçŸä»£ã®Webã¢ããªã±ãŒã·ã§ã³ã§ã·ãŒã ã¬ã¹ãªãŠãŒã¶ãŒäœéšãæäŸããããã«äžå¯æ¬ ã§ããService WorkerãStreams APIã`fetch()` APIãªã©ã®æè¡ã掻çšããããšã§ã倧ããªãã¡ã€ã«ãæ±ãå Žåã§ããã¢ããªã±ãŒã·ã§ã³ã®å¿çæ§ãä¿ã¡ããŠãŒã¶ãŒãã¬ã³ããªãŒã§ããç¶ããããšãã§ããŸããããã©ãŒãã³ã¹ãæé©åããå ç¢ã§ä¿¡é Œæ§ã®é«ãããŠã³ããŒã管çã·ã¹ãã ãæäŸããããã«ãã¬ãžã¥ãŒã ããŠã³ããŒãããšã©ãŒãã³ããªã³ã°ããã£ãã·ã³ã°æŠç¥ãªã©ã®é«åºŠãªãã¯ããã¯ãèæ ®ããããšãå¿ããªãã§ãã ããããããã®åŽé¢ã«çŠç¹ãåœãŠãããšã§ããŠãŒã¶ãŒã®å Žæããããã¯ãŒã¯ç¶æ³ã«é¢ããããããé åçã§æºè¶³ã®ããäœéšãåµåºããçã«ã°ããŒãã«ãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããšãã§ããŸãã