Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/parser/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export function getDefaultConfig(): SlidevConfig {
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?

monaco: true,
monacoTypesSource: 'local',
monacoTypesAdditionalPackages: [],
Expand Down
38 changes: 38 additions & 0 deletions packages/slidev/node/setups/indexHtml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,48 @@ function toAttrValue(unsafe: unknown) {
return JSON.stringify(escapeHtml(String(unsafe)))
}

function shouldEnable(option: boolean | 'dev' | 'build' | undefined, mode: string): boolean {
if (option === true)
return true
if (option === mode)
return true
return false
}

function collectPreloadImages(data: ResolvedSlidevOptions['data'], mode: string, base: string): string[] {
if (!shouldEnable(data.config.preloadImages, mode))
return []

const images = new Set<string>()
// Normalize base to always end with /
const normalizedBase = base ? (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}`)
}
else {
images.add(image)
}
}
}

return Array.from(images)
}

export default async function setupIndexHtml({ mode, entry, clientRoot, userRoot, roots, data, base }: Omit<ResolvedSlidevOptions, 'utils'>): Promise<string> {
let main = await readFile(join(clientRoot, 'index.html'), 'utf-8')
let body = ''

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

for (const root of roots) {
const path = join(root, 'index.html')
Expand Down Expand Up @@ -75,6 +112,7 @@ export default async function setupIndexHtml({ mode, entry, clientRoot, userRoot
link: [
data.config.favicon ? { rel: 'icon', href: data.config.favicon } : null,
...webFontsLink,
...preloadImages.map(href => ({ rel: 'preload', as: 'image', href })),
].filter(x => x),
meta: [
{ 'http-equiv': 'Content-Type', 'content': 'text/html; charset=UTF-8' },
Expand Down
9 changes: 9 additions & 0 deletions packages/types/src/frontmatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ export interface HeadmatterConfig extends TransitionOptions {
* @default false
*/
remoteAssets?: boolean | 'dev' | 'build'
/**
* Preload slide images (from `image` frontmatter) on page load
*
* This improves presentation smoothness by loading all background images
* immediately rather than on-demand when each slide is displayed.
*
* @default false
*/
preloadImages?: boolean | 'dev' | 'build'
/**
* Show a download button in the SPA build,
* could also be a link to custom pdf
Expand Down
18 changes: 18 additions & 0 deletions packages/vscode/schema/headmatter.json
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,24 @@
"markdownDescription": "Download remote assets in local using vite-plugin-remote-assets",
"default": false
},
"preloadImages": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "string",
"const": "dev"
},
{
"type": "string",
"const": "build"
}
],
"description": "Preload slide images (from `image` frontmatter) on page load\n\nThis improves presentation smoothness by loading all background images immediately rather than on-demand when each slide is displayed.",
"markdownDescription": "Preload slide images (from `image` frontmatter) on page load\n\nThis improves presentation smoothness by loading all background images\nimmediately rather than on-demand when each slide is displayed.",
"default": false
},
"download": {
"type": [
"boolean",
Expand Down
Loading