将SVG图标导入Svelte应用程序的最佳方式
我有大约 80 个自定义 SVG 图标,我将它们导入到 Svelte 前端应用程序中。它基于https://github.com/sveltejs/template构建,使用 Rollup 构建,包括 Typescript、Tailwind 和所有现代好东西。
困境在于如何将图标添加到应用程序中。作为 SVG,图标是不超过 2kB 的简短 XML 文本字符串。
选项 1:作为图像资产
- 将所有图标上传
foo.svg到public/assets/icons. - 创建一个
<Icon type="foo' />使用<img src="foo.svg>.
这种方法意味着图标不是代码的一部分。
优点:图标可以由前端代码按需动态加载。无需将所有图标捆绑到应用程序代码中。
缺点:如果有很多新图标,页面加载速度会很慢,并且浏览器必须获取十几个 1kB 文件。将应用程序部署为 PWA 意味着我们需要手动告诉它预先缓存图标。
选项 2:作为应用程序构建的一部分
- 使用类似https://github.com/cristovao-trevisan/svelte-icon或https://github.com/codefeathers/rollup-plugin-svelte-svg 之类的东西将每个图标直接导入到代码中:
import Home from './icons/home.svg'; - 创建一个 svelte 组件,选择正确的导入组件或 SVG 字符串并显示它。
在这里,图标作为文本字符串与应用程序本身捆绑在一起。
优点:图标作为应用程序包的一部分提供。缓存是不必要的。可以在加载时动态修改一些图标代码,例如颜色、视图框等。
缺点:没有必要在应用程序中包含所有图标以减少到第一个字节的时间。不能在不增加复杂性的情况下进行捆绑拆分等。使渲染变慢,因为 Javascript 代码需要首先将字符串转换为 SVG,而不仅仅是加载图像。
问题
- 从这个分析来看,在应用程序中构建图标似乎是一个更好的方法,但我错过了什么吗?
- 如果“图标”是 50-100kB 的详细图像而不是这里的小字符串,那么演算会改变吗?
回答
以下方法具有以下优点:
- 一个中心点来维护您的应用程序的所有图标
- 减少了获取 SVG 图标的网络请求
- 整个应用程序中可重复使用的图标,无需重复的 svg 元素
有一个专用的 Icon.svelte 组件设置,如下所示:
<script>
export let name;
export let width = "1rem";
export let height = "1rem";
export let focusable = false;
let icons = [
{
box: 24,
name: "save",
svg: `<g stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><path d="M17 21v-8H7v8"/><path d="M7 3v5h8"/></g>`
},
{
box: 32,
name: "trash",
svg: `<path d="M12 12h2v12h-2z" /><path d="M18 12h2v12h-2z" /><path d="M4 6v2h2v20a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8h2V6zm4 22V8h16v20z" /><path d="M12 2h8v2h-8z" />`
}
];
let displayIcon = icons.find((e) => e.name === name);
</script>
<svg
class={$$props.class}
{focusable}
{width}
{height}
viewBox="0 0 {displayIcon.box} {displayIcon.box}">{@html displayIcon.svg}</svg>
然后你可以像这样使用它:
<Icon name="trash" />