---
title: 构建优化
icon: clarity:bundle-solid
outline: 2
createTime: 2024/09/10 01:50:20
permalink: /guide/optimize-build/
---

## 图片优化 <Badge type="warning" text="试验性" />

当我们在 markdown 中使用 `[alt](url)` 或者 `<img src="url">` 嵌入图片后，虽然页面按照预期的显示了
图片。

由于图片的体积不同，当图片体积较小，网络情况良好的时候，我们不会感受到页面的布局有产生明显的抖动。
然而，当图片体积较大，或者网络情况较差时，由于图片为完成加载，原本页面上应该显示图片的位置被后面的
内容挤压，等到图片加载完成后，页面布局会发生变化，图片重新占据应该显示的位置，其它的内容被排开。

事实上这个体验相当不友好。特别是对于页面内的图片数量较多时，页面会频繁发生布局变化，这一过程还可能
感知到卡顿，较为明显的是布局的抖动。

因此，让页面布局稳定下来，图片是一个必须解决的问题。

从 [MDN > img](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/img#height) 我们可以知道：

::: info
`<img>` 同时包括 `height` 和 `width` 使浏览器在加载图像之前计算图像的长宽比。
此长宽比用于保留显示图像所需的空间，减少甚至防止在下载图像并将其绘制到屏幕上时布局的偏移。
减少布局偏移是良好用户体验和 Web 性能的主要组成部分。
:::

因此，主题围绕这个问题，提供了 一个解决方案：

为 markdown 文件中的 `[alt](url)` 或者 `<img src="url">` 自动添加 `width` 和 `height` 属性。

你可以通过配置 `markdownPower` 来启用它：

```ts
export default defineUserConfig({
  theme: plumeTheme({
    plugins: {
      markdownPower: {
        imageSize: true, // 'local' | 'all'
      },
    }
  })
})
```

启用此功能后，主题会通过图片资源地址，获取图片的原始尺寸，然后为图片添加 `width` 和 `height` 属性。

- 如果设置为 `'local'`， 则仅为 本地图片添加 `width` 和 `height` 属性。
- 如果设置为 `'all'`， 则包括 __本地图片__ 和 __网络图片__ 都 添加 `width` 和 `height` 属性。
- 如果设置为 `true`， 则等同于 `'local'`

::: important
请注意，出于性能考虑，即使您启用了此功能，该功能也仅在 构建生产包时生效。
:::

::: important
请谨慎使用 `'all'` 选项，该选项会在构建生产包时，请求所有 markdown 中包含的 远程图片资源，
这对于包含较多图片资源的站点而言，会使得构建时间变长。

主题也针对此类情况做了优化，请求远程图片仅在获取 __几 KB__ 的数据包足够分析尺寸后不再等待请求完成，
同时并发请求其他图片资源。这在一定程度上能够改善构建时间。
:::

## 图标优化

得益于 开源项目 [iconify](https://icon-sets.iconify.design/) 的强大，您可以在主题内使用大约 20 万 个图标。

当然，这并不意味着主题需要加载全部的图标。您可能已经注意到，主题推荐您在本地安装 `@iconify/json` 包，这需要
下载大约 __70Mb__ 的资源包，如果加载全部的图标到文档站点中，这太大太大了。

但请放心，主题仅会加载您有使用到的图标资源，这包括 导航栏、侧边栏、首页 Features 等配置中的 iconify 图标，
以及通过语法糖 `:[collect:name]:` 和 组件 `<Icon name="icon_name" />` 等各种方式使用的图标。

当从本地 `@iconify/json` 中加载图标时， iconify 通过 `[collect]:[name]` 的形式为图标命名，其中根据
`collect` 来区分图标所属的集合，每个集合拥有  100 ~ 1000+ 数量不等的图标，保存在以 `collect` 为维度的 `json`
文件中。当文档使用了比较多的不同的 `collect` 下的图标时，即使从本地加载和解析 `json`，也需要花费比较长的时间，
以主题站点为例，主题使用了 __54 个collect__ 超过 __160+ 个图标__, 在初始启动时，在图标解析加载大约需要耗费 `500ms`
的时间开销，这显然是难以接受的。

针对这种情况，主题会在首次启动时，缓存有使用的图标资源，当二次启动时，优先从缓存中加载图标，由于仅缓存有使用的
图标资源，加载这部分资源远比 频繁解析不同 `collect` 下的图标资源要快的多，且资源利用率更高。

其时间开销从 `500ms` 减少到了 `20ms` 甚至更低！这也进一步优化了 启动开发服务的时间！

::: info
使用 __54 个collect__ 下的图标资源 这种情况相对来说比较极端，这也意味着 54 次的 i/o 读取和 json 解析，
花费 `500ms` 的时间开销也算是正常，然而实际使用的图标数量仅 `160+ 个` 时，所带来的 直观感受是
__不应该花费这么长的时间的__ ，因此，缓存这部分的图标资源是一个很好的选择。
:::
