{"id":48861745,"url":"https://github.com/crper/idle-resource-loader","last_synced_at":"2026-04-15T16:30:55.032Z","repository":{"id":304617771,"uuid":"1019381047","full_name":"crper/idle-resource-loader","owner":"crper","description":"Lightweight resource preloading SDK that intelligently utilizes browser idle time for optimal performance. Features smart concurrency control, dynamic time slicing, and user experience first design.","archived":false,"fork":false,"pushed_at":"2025-09-11T06:49:36.000Z","size":102,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-21T07:04:51.781Z","etag":null,"topics":["intelligent-scheduler","prefetch","preloader","requestidlecallback","resource-loading","typescript","typescript-library"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/idle-resource-loader","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/crper.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-14T08:38:24.000Z","updated_at":"2025-08-05T06:51:37.000Z","dependencies_parsed_at":"2025-07-14T09:56:02.543Z","dependency_job_id":"4a11039c-6c01-4447-b89e-7b416b3a4fa3","html_url":"https://github.com/crper/idle-resource-loader","commit_stats":null,"previous_names":["crper/idle-resource-loader"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/crper/idle-resource-loader","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crper%2Fidle-resource-loader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crper%2Fidle-resource-loader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crper%2Fidle-resource-loader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crper%2Fidle-resource-loader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/crper","download_url":"https://codeload.github.com/crper/idle-resource-loader/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crper%2Fidle-resource-loader/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31849673,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-15T15:24:51.572Z","status":"ssl_error","status_checked_at":"2026-04-15T15:24:39.138Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["intelligent-scheduler","prefetch","preloader","requestidlecallback","resource-loading","typescript","typescript-library"],"created_at":"2026-04-15T16:30:54.346Z","updated_at":"2026-04-15T16:30:55.006Z","avatar_url":"https://github.com/crper.png","language":"TypeScript","readme":"# idle-resource-loader\n\n[中文文档](./README_zh-CN.md) | English\n\nA lightweight resource preloading SDK that intelligently utilizes browser idle time for optimal performance without blocking the main thread.\n\n## Features\n\n- **🎯 Unified API**: Single `loadResources` function with strategy-based loading\n- **⚡ Smart Concurrency**: Intelligent batching (default 1, max 2) with sequential batch processing\n- **🔄 Idle Time Utilization**: Uses `requestIdleCallback` for non-blocking background loading\n- **🛡️ Resource Type Detection**: Automatic loader selection based on file extensions\n- **💾 Memory Optimized**: AbortController-based timeout handling prevents leaks\n- **🚀 Lightweight**: Only 2.7KB gzipped, zero dependencies\n- **📦 ES Module Ready**: Full support for modern build tools (Vite, Webpack, etc.)\n- **🔧 TypeScript**: Complete type definitions and intelligent hints\n- **🌐 Cross-Browser**: Graceful degradation for older browsers\n\n## Installation\n\n```bash\nnpm install idle-resource-loader\n```\n\n## Quick Start\n\n```typescript\nimport { loadResources } from 'idle-resource-loader'\n\n// 🚀 Immediate loading (default) - for critical resources\nloadResources('https://example.com/hero-image.jpg')\n\n// 🔄 Idle loading - for non-critical resources\nloadResources('https://example.com/background-video.mp4', {\n  strategy: 'idle',\n})\n\n// 📦 Batch loading with smart concurrency control\nloadResources(['image1.jpg', 'image2.png', 'image3.webp'], {\n  batchSize: 5, // Requests 5, automatically limited to 2 for optimal performance\n  timeout: 10000,\n  onError: (url, error) =\u003e console.warn(`Failed to load: ${url}`),\n})\n```\n\n## How It Works\n\n### Loading Strategies\n\n**Immediate Loading (default)**\n\n- Processes resources in sequential batches to avoid network congestion\n- Each batch processes up to 2 resources concurrently (prioritizes page initialization resources)\n- Waits for current batch to complete before starting the next batch\n- Best for critical resources needed right away\n\n**Idle Loading**\n\n- Uses `requestIdleCallback` to process resources during browser idle time\n- Processes one resource per idle callback to avoid blocking the main thread\n- Automatically pauses when page becomes hidden (Page Visibility API)\n- Falls back to `setTimeout` when `requestIdleCallback` is unavailable\n- Best for non-critical resources that can be loaded in background\n\n### Resource Type Detection\n\nThe SDK automatically selects the optimal loader based on file extensions:\n\n- **Images**: `.jpg`, `.jpeg`, `.png`, `.gif`, `.webp`, `.svg` → Uses `Image` constructor\n- **Audio**: `.mp3`, `.wav`, `.ogg` → Uses `Audio` constructor\n- **Video**: `.mp4`, `.webm`, `.mov`, `.avi`, `.mkv`, `.flv` → Uses `\u003cvideo\u003e` element\n- **Fonts**: `.woff`, `.woff2`, `.ttf` → Uses `\u003clink\u003e` element with `rel=\"preload\"`\n- **Other**: All other file types → Uses `fetch` API with `no-cors` mode\n\n## API Reference\n\n### `loadResources(resources, options?)`\n\n#### Parameters\n\n- **`resources`**: `string | string[]`\n  - Single URL string or array of URL strings\n  - **Supported formats**: HTTP/HTTPS URLs, relative paths, protocol-relative URLs\n  - **Security**: Dangerous protocols (javascript:, data:, file:, etc.) are automatically filtered\n- **`options`**: `LoadResourcesOptions` (optional)\n  - `strategy`: `'immediate' | 'idle'` - Loading strategy (default: `'immediate'`)\n  - `batchSize`: `number` - Resources per batch (default: `1`, max: `2`)\n  - `timeout`: `number` - Timeout in milliseconds (default: `15000`)\n  - `onError`: `(url: string, error: Error) =\u003e void` - Error callback\n\n#### Examples\n\n```typescript\n// Future resources preloading (recommended)\nloadResources(['/next-page/hero-image.jpg', '/modal/success-icon.svg'], { strategy: 'idle' })\n\n// Supported URL formats\nloadResources([\n  'https://cdn.example.com/image.jpg', // Absolute HTTPS URL\n  'http://example.com/image.jpg', // Absolute HTTP URL\n  '/assets/image.jpg', // Root-relative path\n  'assets/image.jpg', // Relative path\n  '//cdn.example.com/image.jpg', // Protocol-relative URL\n])\n\n// Error handling\nloadResources(['/assets/image1.jpg', '/assets/image2.jpg'], {\n  strategy: 'idle',\n  onError: (url, error) =\u003e {\n    console.error(`Failed to load ${url}:`, error.message)\n  },\n})\n\n// Large resource lists with sequential batch processing\nconst resources = Array.from({ length: 100 }, (_, i) =\u003e `/assets/image-${i}.jpg`)\nloadResources(resources, {\n  strategy: 'idle',\n  batchSize: 2, // Process 2 resources per batch, then wait for completion\n})\n```\n\n## Browser Compatibility\n\n| Feature               | Required    | Fallback       |\n| --------------------- | ----------- | -------------- |\n| `fetch`               | ✅ Required | None           |\n| `requestIdleCallback` | ⚡ Optional | `setTimeout`   |\n| `AbortController`     | ⚡ Optional | Simple timeout |\n\n**Polyfill Strategy**: The SDK delegates polyfill handling to your build tools (Webpack, Vite, etc.) and polyfill libraries (core-js, etc.) for maximum flexibility.\n\n## How It Works\n\n### Immediate Loading Strategy\n\n- **Smart Concurrency**: Default 2 concurrent requests, max 3 to respect browser limits\n- **Batch Processing**: Large arrays are processed in optimal chunks\n- **Timeout Protection**: AbortController prevents hanging requests\n\n### Idle Loading Strategy\n\n- **Dynamic Time Slicing**: Processes 1 resource per idle callback based on available time\n- **Page Visibility**: Automatically pauses when page is hidden\n- **Time Management**: Reserves 12ms for other tasks to prevent main thread blocking\n\n### Supported Resource Types\n\n| Type   | Extensions                                 | Loader            |\n| ------ | ------------------------------------------ | ----------------- |\n| Images | `jpg`, `jpeg`, `png`, `gif`, `webp`, `svg` | `\u003cimg\u003e` element   |\n| Audio  | `mp3`, `wav`, `ogg`                        | `\u003caudio\u003e` element |\n| Video  | `mp4`, `webm`, `mov`, `avi`, `mkv`, `flv`  | `\u003cvideo\u003e` element |\n| Fonts  | `woff`, `woff2`, `ttf`                     | `\u003clink\u003e` preload  |\n| Others | Any extension                              | `fetch()` API     |\n\n## ⚠️ Important Usage Guidelines\n\n### ✅ DO - Recommended Use Cases\n\n```typescript\n// ✅ Preload future/next-page resources\nloadResources(\n  ['/next-page/hero-image.jpg', '/modal/success-icon.svg', '/future-section/background.webp'],\n  { strategy: 'idle' },\n)\n\n// ✅ Preload resources from API/config\nconst futureAssets = await fetch('/api/next-page-assets').then((r) =\u003e r.json())\nloadResources(futureAssets, { strategy: 'idle' })\n\n// ✅ Critical resources with immediate loading\nloadResources(['/hero-banner.jpg', '/critical-font.woff2'], { strategy: 'immediate' })\n```\n\n### ❌ DON'T - Avoid These Patterns\n\n```typescript\n// ❌ DON'T: Static imports cause bundle bloat\nimport logo from '@/assets/logo.png'\nimport img1 from '@/assets/img1.jpg'\nimport img2 from '@/assets/img2.jpg'\nloadResources([logo, img1, img2])  // Increases bundle size by MBs!\n\n// ❌ DON'T: Preload current component resources\nfunction MyComponent() {\n  return \u003cimg src=\"/current-logo.png\" /\u003e  // Browser already requests this\n}\nloadResources(['/current-logo.png'])  // Redundant and wasteful\n\n// ❌ DON'T: Dangerous URLs (automatically filtered for security)\nloadResources([\n  'javascript:alert(\"xss\")',           // XSS risk\n  'data:text/html,\u003cscript\u003e',          // Data URL risk\n  'file:///etc/passwd',               // Local file access\n  'ftp://example.com/file'            // Unsupported protocol\n])\n```\n\n### 💡 Why These Guidelines Matter\n\n- **Static imports** add all assets to your main bundle, increasing initial load time\n- **Current component resources** are already requested by the browser during rendering\n- **Future resources** benefit most from idle-time preloading\n- **Sequential batch processing** prevents network congestion and respects browser limits\n\n## Best Practices\n\n1. **Use immediate loading for critical resources** that are needed right away\n2. **Use idle loading for future resources** that might be needed later\n3. **Trust the sequential batching** - SDK processes batches sequentially to avoid network congestion\n4. **Handle errors gracefully** with the `onError` callback\n5. **Use URL strings only** - avoid static imports to prevent bundle bloat\n6. **Leverage automatic resource type detection** - the SDK chooses optimal loaders based on file extensions\n\n## Performance\n\n- **Bundle Size**: 2.7KB gzipped (9.2KB uncompressed)\n- **Memory Usage**: Minimal, with automatic cleanup and AbortController-based timeout handling\n- **Network Impact**: Sequential batch processing respects browser connection limits (max 2 concurrent)\n- **Main Thread**: Non-blocking with `requestIdleCallback` for idle strategy\n- **Resource Loading**: Automatic loader selection optimized for each resource type\n\n## TypeScript\n\nFull TypeScript support with intelligent IntelliSense:\n\n```typescript\nimport { loadResources, type LoadResourcesOptions } from 'idle-resource-loader'\n\nconst options: LoadResourcesOptions = {\n  strategy: 'idle',\n  batchSize: 2,\n  timeout: 10000,\n  onError: (url: string, error: Error) =\u003e {\n    // Type-safe error handling\n  },\n}\n```\n\n## License\n\nMIT © [crper](https://github.com/crper)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrper%2Fidle-resource-loader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcrper%2Fidle-resource-loader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrper%2Fidle-resource-loader/lists"}