Skip to content

Conversation

@quinnypig
Copy link
Contributor

Summary

Adds a new preloadImages frontmatter 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 preloadImages option that collects all image: 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`:

  • `true` - always enabled
  • `'dev'` - only in dev mode
  • `'build'` - only in production builds
  • `false` (default) - disabled

Changes

  • `packages/types/src/frontmatter.ts` - Add `preloadImages` type definition
  • `packages/parser/src/config.ts` - Add default value
  • `packages/slidev/node/setups/indexHtml.ts` - Collect images and generate preload links
  • `packages/vscode/schema/headmatter.json` - Auto-generated schema update

Test Plan

  1. Create a presentation with multiple slides using `image:` frontmatter
  2. Add `preloadImages: true` to headmatter
  3. Build/dev and verify `` tags appear in HTML head
  4. Navigate through slides - images should load instantly without delay

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.
Copilot AI review requested due to automatic review settings February 2, 2026 21:48
@netlify
Copy link

netlify bot commented Feb 2, 2026

Deploy Preview for slidev ready!

Name Link
🔨 Latest commit 107b60b
🔍 Latest deploy log https://app.netlify.com/projects/slidev/deploys/698121f105ef0100087c2b96
😎 Deploy Preview https://deploy-preview-2450--slidev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Contributor

Copilot AI left a 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 preloadImages configuration option (accepts true, 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.

Comment on lines 32 to 42

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}`)
Copy link

Copilot AI Feb 2, 2026

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.

Suggested change
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}`)

Copilot uses AI. Check for mistakes.
let body = ''

const inputs: any[] = []
const preloadImages = collectPreloadImages(data, mode, base || '/')
Copy link

Copilot AI Feb 2, 2026

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.

Suggested change
const preloadImages = collectPreloadImages(data, mode, base || '/')
const preloadImages = collectPreloadImages(data, mode, base || '')

Copilot uses AI. Check for mistakes.
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,
Copy link
Member

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?

troshab added a commit to troshab/slidev that referenced this pull request Feb 11, 2026
…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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants