静态资源管理
正确管理静态资源(如图片、字体、CSS 文件和其他资源)对于构建专业的文档网站至关重要。本章介绍 Rspress 如何处理静态资源以及组织它们的最佳实践。
理解静态资源
什么是静态资源?
静态资源是不需要处理并直接提供给用户的文件:
- 图片: PNG, JPG, SVG, GIF, WebP
- 字体: WOFF, WOFF2, TTF, OTF
- 样式表: CSS 文件
- 文档: PDF, ZIP 文件
- 媒体: 视频、音频文件
- 数据: JSON, XML 文件
资源加载策略
Rspress 提供多种处理资源的方式:
- Public 目录: 用于通过 URL 直接引用的资源
- 相对导入: 用于打包器处理的资源
- 外部 URL: 用于 CDN 托管的资源
Public 目录
基本用法
将资源放在 public 目录中以直接提供:
my-rspress-site/
├── docs/
├── public/
│ ├── images/
│ │ ├── logo.png
│ │ └── screenshot.png
│ ├── fonts/
│ │ └── custom-font.woff2
│ └── favicon.ico
└── rspress.config.ts使用绝对路径引用 public 资源:
markdown
<!-- 在您的 Markdown 文件中 -->

<img src="/images/screenshot.png" alt="截图" />子目录组织
按类型组织资源:
public/
├── images/
│ ├── icons/
│ │ ├── check.svg
│ │ └── cross.svg
│ ├── screenshots/
│ │ ├── dashboard.png
│ │ └── settings.png
│ └── logos/
│ ├── logo-light.png
│ └── logo-dark.png
├── downloads/
│ ├── user-guide.pdf
│ └── template.zip
└── videos/
└── demo.mp4Base Path 配置
如果您的网站部署到子目录:
typescript
// rspress.config.ts
export default defineConfig({
base: '/my-docs/', // 网站部署在 example.com/my-docs/
});资源会自动添加前缀:
markdown
<!-- 自动变成 /my-docs/images/logo.png -->
图片处理
基本图片
markdown
<!-- 相对于 public 目录 -->

<!-- 在 HTML 中使用尺寸属性 -->
<img src="/images/photo.jpg" width="600" height="400" alt="照片" />响应式图片
使用 HTML picture 元素实现响应式图片:
markdown
<picture>
<source media="(max-width: 768px)" srcset="/images/mobile.jpg" />
<source media="(max-width: 1200px)" srcset="/images/tablet.jpg" />
<img src="/images/desktop.jpg" alt="响应式图片" />
</picture>图片优化
在添加图片之前进行优化:
bash
# 安装图片优化工具
npm install -g imagemin-cli
# 优化图片
imagemin public/images/*.{jpg,png} --out-dir=public/images/optimized
# 或使用在线工具:
# - TinyPNG: https://tinypng.com/
# - Squoosh: https://squoosh.app/
# - ImageOptim (Mac): https://imageoptim.com/SVG 图片
SVG 图片非常适合 logo 和图标:
markdown
<!-- 内联 SVG -->
<svg width="100" height="100" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
<!-- 外部 SVG 文件 -->
深色模式图片
为浅色/深色主题提供不同的图片:
tsx
// components/ThemedImage.tsx
import { useTheme } from 'rspress/runtime';
export function ThemedImage({ lightSrc, darkSrc, alt }) {
const { theme } = useTheme();
return (
<img
src={theme === 'dark' ? darkSrc : lightSrc}
alt={alt}
/>
);
}mdx
import { ThemedImage } from '../components/ThemedImage';
<ThemedImage
lightSrc="/images/logo-light.png"
darkSrc="/images/logo-dark.png"
alt="Logo"
/>字体
自定义字体
向您的网站添加自定义字体:
public/
└── fonts/
├── CustomFont-Regular.woff2
├── CustomFont-Bold.woff2
└── CustomFont-Italic.woff2创建 CSS 文件:
css
/* styles/fonts.css */
@font-face {
font-family: 'CustomFont';
src: url('/fonts/CustomFont-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'CustomFont';
src: url('/fonts/CustomFont-Bold.woff2') format('woff2');
font-weight: 700;
font-style: normal;
font-display: swap;
}在配置中导入:
typescript
// rspress.config.ts
export default defineConfig({
head: [
['link', { rel: 'stylesheet', href: '/styles/fonts.css' }],
],
});Google 字体
通过 CDN 使用 Google 字体:
typescript
// rspress.config.ts
export default defineConfig({
head: [
[
'link',
{
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap',
},
],
],
});CSS 和样式表
全局样式
添加全局 CSS:
public/
└── styles/
└── custom.csscss
/* public/styles/custom.css */
:root {
--primary-color: #007bff;
--secondary-color: #6c757d;
}
.custom-container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.highlight {
background-color: yellow;
padding: 2px 4px;
}在配置中导入:
typescript
// rspress.config.ts
export default defineConfig({
head: [
['link', { rel: 'stylesheet', href: '/styles/custom.css' }],
],
});组件样式
使用 CSS Modules 实现组件特定样式:
tsx
// components/Card.tsx
import styles from './Card.module.css';
export function Card({ children }) {
return <div className={styles.card}>{children}</div>;
}css
/* components/Card.module.css */
.card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
margin: 20px 0;
}主题覆盖
覆盖默认主题样式:
css
/* public/styles/theme-override.css */
/* 覆盖导航背景 */
.rspress-nav {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
/* 覆盖代码块主题 */
.rspress-code-block {
border-radius: 12px;
}
/* 覆盖侧边栏宽度 */
.rspress-sidebar {
width: 280px;
}可下载资源
文档文件
提供可下载的资源:
public/
└── downloads/
├── api-reference.pdf
├── quick-start-guide.pdf
└── code-samples.zip在文档中链接到它们:
markdown
# 资源
下载我们的资源:
- [API 参考 (PDF)](/downloads/api-reference.pdf)
- [快速入门指南 (PDF)](/downloads/quick-start-guide.pdf)
- [代码示例 (ZIP)](/downloads/code-samples.zip)视频和音频
嵌入视频
嵌入视频文件:
markdown
<video controls width="100%">
<source src="/videos/tutorial.mp4" type="video/mp4" />
<source src="/videos/tutorial.webm" type="video/webm" />
您的浏览器不支持视频播放。
</video>YouTube/Vimeo 嵌入
markdown
<!-- YouTube -->
<iframe
width="560"
height="315"
src="https://www.youtube.com/embed/VIDEO_ID"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>Favicon 和 Meta 图片
Favicon
添加 favicon 文件:
public/
├── favicon.ico
├── favicon-16x16.png
├── favicon-32x32.png
└── apple-touch-icon.png在 rspress.config.ts 中配置:
typescript
export default defineConfig({
icon: '/favicon.ico',
head: [
['link', { rel: 'icon', type: 'image/png', sizes: '16x16', href: '/favicon-16x16.png' }],
['link', { rel: 'icon', type: 'image/png', sizes: '32x32', href: '/favicon-32x32.png' }],
['link', { rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png' }],
],
});Open Graph 图片
添加社交媒体预览图片:
typescript
export default defineConfig({
head: [
['meta', { property: 'og:image', content: '/images/og-image.png' }],
['meta', { property: 'og:image:width', content: '1200' }],
['meta', { property: 'og:image:height', content: '630' }],
['meta', { name: 'twitter:card', content: 'summary_large_image' }],
['meta', { name: 'twitter:image', content: '/images/twitter-card.png' }],
],
});资源优化
图片格式
选择适当的格式:
- JPEG: 照片、有许多颜色的复杂图片
- PNG: 带透明度的图形、截图
- SVG: Logo、图标、简单图形
- WebP: 现代格式、最佳压缩(带后备)
压缩
压缩资源以加快加载速度:
bash
# JPG/PNG 压缩
imagemin public/images/*.{jpg,png} --plugin.webp --out-dir=public/images/compressed
# SVG 优化
npx svgo public/images/*.svg懒加载
懒加载图片以获得更好的性能:
markdown
<img src="/images/large-image.jpg" loading="lazy" alt="大图" />最佳实践
文件命名
使用一致、描述性的名称:
✅ 好的:
- dashboard-screenshot-2024.png
- user-authentication-flow.svg
- api-integration-guide.pdf
❌ 不好的:
- IMG_1234.png
- pic.svg
- download.pdf组织
按目的或类型组织:
public/
├── images/
│ ├── features/ # 功能图片
│ ├── tutorials/ # 教程截图
│ └── ui/ # UI 元素
├── downloads/
│ ├── guides/ # 用户指南
│ └── samples/ # 代码示例
└── media/
├── videos/ # 视频内容
└── audio/ # 音频内容文件大小
保持合理的文件大小:
- 图片: < 200KB (优化较大的图片)
- 文档: < 10MB
- 视频: 对大视频使用流媒体服务
故障排除
图片未加载
- 检查文件路径: 确保路径正确
markdown
<!-- 错误 -->

<!-- 正确 -->
验证文件存在: 检查
public目录检查 base path: 确保 base path 配置与部署路径匹配
大文件大小
bash
# 检查文件大小
du -h public/images/*
# > 1MB 的文件应该优化
find public -type f -size +1M性能提示
优化加载
- 使用 WebP 格式并带后备
- 对折叠下方的图片实施懒加载
- 使用适当的尺寸(不要为缩略图加载 4K 图片)
- 在服务器上启用压缩
- 为静态资源使用 CDN
下一步
最佳实践
- 在添加图片之前优化它们
- 使用适当的图片格式
- 为可访问性提供替代文本
- 逻辑地组织资源
- 考虑为大图片使用懒加载
文件大小
- 尽可能将图片保持在 200KB 以下
- 在上传前压缩 PDF
- 对大视频使用视频流服务
- 在慢速连接上测试加载时间
工具
- TinyPNG - 图片压缩
- Squoosh - 图片优化
- SVGOMG - SVG 优化
- ImageOptim - Mac 图片优化器