-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
feat: add preloadImages option to eager-load slide background images #2450
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Adds a new `preloadImages` frontmatter option that generates `<link rel="preload">` tags for all images referenced in slide frontmatter (`image:` property). This improves presentation smoothness by loading background images immediately on page load rather than on-demand when each slide is first displayed. Usage: ```yaml --- preloadImages: true # or 'dev' | 'build' --- ``` The option follows the same pattern as `remoteAssets` - can be set to `true` for always-on, or 'dev'/'build' to enable only in specific modes.
✅ Deploy Preview for slidev ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds a preloadImages configuration option to eagerly load slide background images on page load, eliminating the visible loading delay when navigating to slides with background images.
Changes:
- Added
preloadImagesconfiguration option (acceptstrue,false,'dev', or'build') - Implemented image collection logic that scans slide frontmatter and generates
<link rel="preload">tags - Updated type definitions, schema, and default configuration
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| packages/types/src/frontmatter.ts | Added type definition for the new preloadImages configuration option |
| packages/parser/src/config.ts | Set default value to false for the preloadImages option |
| packages/slidev/node/setups/indexHtml.ts | Implemented image collection and preload link generation logic |
| packages/vscode/schema/headmatter.json | Auto-generated schema update for VS Code extension support |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| for (const slide of data.slides) { | ||
| const image = slide.frontmatter.image | ||
| if (image && typeof image === 'string') { | ||
| // Handle relative paths - prefix with base | ||
| if (image.startsWith('/') && !image.startsWith('//')) { | ||
| images.add(`${base}${image.slice(1)}`) | ||
| } | ||
| else if (!image.startsWith('http://') && !image.startsWith('https://') && !image.startsWith('//')) { | ||
| // Relative path without leading slash | ||
| images.add(`${base}${image}`) |
Copilot
AI
Feb 2, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When base already ends with a / and the image path starts with /, this will create a double slash in the URL (e.g., base/ + image with leading / removed becomes base//image). Consider ensuring the base doesn't end with a slash or handle the concatenation more robustly.
| for (const slide of data.slides) { | |
| const image = slide.frontmatter.image | |
| if (image && typeof image === 'string') { | |
| // Handle relative paths - prefix with base | |
| if (image.startsWith('/') && !image.startsWith('//')) { | |
| images.add(`${base}${image.slice(1)}`) | |
| } | |
| else if (!image.startsWith('http://') && !image.startsWith('https://') && !image.startsWith('//')) { | |
| // Relative path without leading slash | |
| images.add(`${base}${image}`) | |
| const normalizedBase = base.endsWith('/') ? base : `${base}/` | |
| for (const slide of data.slides) { | |
| const image = slide.frontmatter.image | |
| if (image && typeof image === 'string') { | |
| // Handle relative paths - prefix with base | |
| if (image.startsWith('/') && !image.startsWith('//')) { | |
| images.add(`${normalizedBase}${image.slice(1)}`) | |
| } | |
| else if (!image.startsWith('http://') && !image.startsWith('https://') && !image.startsWith('//')) { | |
| // Relative path without leading slash | |
| images.add(`${normalizedBase}${image}`) |
| let body = '' | ||
|
|
||
| const inputs: any[] = [] | ||
| const preloadImages = collectPreloadImages(data, mode, base || '/') |
Copilot
AI
Feb 2, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fallback value '/' for base may not work correctly with the path concatenation logic in collectPreloadImages. If base is '/', then concatenating base + image for a relative path will produce '/image' instead of image, and for absolute paths like '/path', it will produce '//path'. Consider using an empty string '' as the fallback instead.
| const preloadImages = collectPreloadImages(data, mode, base || '/') | |
| const preloadImages = collectPreloadImages(data, mode, base || '') |
Address code review feedback: - Normalize base to always end with / before path concatenation - Use empty string as fallback instead of '/' to handle root correctly Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
| titleTemplate: '%s - Slidev', | ||
| addons: [], | ||
| remoteAssets: false, | ||
| preloadImages: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would consider having it true by default. Or what's your concern?
…cheduling Extract image URLs at parse time from all sources (frontmatter, markdown, Vue component props, CSS url()) and store in `images[]` on SlideInfoBase. This field survives build-mode content stripping. Build-time: generates `<link rel="preload" as="image">` tags in HTML head. Runtime: navigation-aware composable preloads current + ahead window immediately, then all remaining slides after 3s. Configurable via headmatter `preloadImages` (default: true). Supersedes slidevjs#2450 with comprehensive coverage.
Summary
Adds a new
preloadImagesfrontmatter option that generates<link rel="preload">tags for all images referenced in slide frontmatter (image:property).Problem
When presenting slides with background images (set via
image:frontmatter), each image loads on-demand when the slide is first displayed. This causes a visible loading delay (~0.5s) on first navigation to each slide, disrupting presentation flow.Solution
This PR adds a
preloadImagesoption that collects allimage:frontmatter values at build time and injects<link rel="preload" as="image">tags into the HTML head. This tells the browser to fetch all slide images immediately on page load.Usage
```yaml
preloadImages: true # or 'dev' | 'build'
```
The option follows the same pattern as `remoteAssets`:
Changes
Test Plan