如何在RMarkdown生成的HTML中仅嵌入用到的Font Awesome图标?
问题描述
在RMarkdown中使用reactable()构建表格时,通过reactablefmtr的icon_sets()添加Font Awesome图标,仅用到4个核心图标,但生成的HTML文件却嵌入了完整的Font Awesome库,导致文件体积从约1MB暴涨至近5MB。如何配置才能只嵌入实际使用到的图标?
最小复现代码
--- title: "embedded_fa_icons" output: html_document --- ```{r setup, include=FALSE} library(reactable) library(reactablefmtr) library(palmerpenguins) library(dplyr) knitr::opts_chunk$set(echo = FALSE)
Penguin stats
data <- sample_n(penguins, 50) %>% filter(!is.na(bill_length_mm)) %>% select(species, bill_length_mm, bill_depth_mm, flipper_length_mm, body_mass_g)
reactable( data, columns = list( bill_length_mm = colDef(cell = icon_sets(data, icons = c("ruler"))), bill_depth_mm = colDef(cell = icon_sets(data, icons = c("ruler-vertical"))), flipper_length_mm = colDef(cell = icon_sets(data, icons = c("ruler-horizontal"))), body_mass_g = colDef(cell = icon_sets(data, icons = c("balance-scale-left", "balance-scale", "balance-scale-right"))) ) )
## 解决方案 ### 方法一:禁用内置图标嵌入,改用CDN加载(最简便) `reactablefmtr`的`icon_sets()`函数默认会将完整的Font Awesome库嵌入HTML(参数`embed_fontawesome = TRUE`),只需将该参数设为`FALSE`,并手动引入Font Awesome的CDN链接即可避免体积膨胀。 1. 在RMarkdown的YAML下方添加CDN引入: ```html <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
- 修改
icon_sets()调用,添加embed_fontawesome = FALSE参数:
reactable( data, columns = list( bill_length_mm = colDef(cell = icon_sets(data, icons = c("ruler"), embed_fontawesome = FALSE)), bill_depth_mm = colDef(cell = icon_sets(data, icons = c("ruler-vertical"), embed_fontawesome = FALSE)), flipper_length_mm = colDef(cell = icon_sets(data, icons = c("ruler-horizontal"), embed_fontawesome = FALSE)), body_mass_g = colDef(cell = icon_sets(data, icons = c("balance-scale-left", "balance-scale", "balance-scale-right"), embed_fontawesome = FALSE)) ) )
这种方式下,HTML不再打包完整图标库,而是通过CDN按需加载所需图标,文件体积会回到1MB左右,且CDN资源有缓存加持,加载速度更快。
方法二:手动嵌入所需图标SVG(无外部依赖)
如果不想依赖CDN,可以直接将用到的图标SVG代码嵌入表格,完全避免加载多余资源:
- 从Font Awesome官网下载所需图标的SVG代码(如
ruler、ruler-vertical等); - 在R代码中定义SVG字符串,传入
icon_sets()并禁用内置嵌入:
# 示例:定义ruler图标的SVG ruler_svg <- '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M496 64c17.7 0 32 14.3 32 32v320c0 17.7-14.3 32-32 32H160c-17.7 0-32-14.3-32-32V96c0-17.7 14.3-32 32-32H496zM160 32C71.6 32 0 103.6 0 192V320c0 88.4 71.6 160 160 160H496c88.4 0 160-71.6 160-160V192c0-88.4-71.6-160-160-160H160zm32 128c0-8.8 7.2-16 16-16H464c8.8 0 16 7.2 16 16s-7.2 16-16 16H208c-8.8 0-16-7.2-16-16zm0 64c0-8.8 7.2-16 16-16H464c8.8 0 16 7.2 16 16s-7.2 16-16 16H208c-8.8 0-16-7.2-16-16zm0 64c0-8.8 7.2-16 16-16H464c8.8 0 16 7.2 16 16s-7.2 16-16 16H208c-8.8 0-16-7.2-16-16z"/></svg>' reactable( data, columns = list( bill_length_mm = colDef(cell = icon_sets(data, icons = c(ruler_svg), embed_fontawesome = FALSE)), # 其他列同理替换为对应SVG ) )
方法三:使用fontawesome包按需导出图标
借助R的fontawesome包,可以精准导出所需图标,再传入icon_sets():
- 安装并加载包:
install.packages("fontawesome") library(fontawesome)
- 导出所需图标为SVG字符串:
ruler <- fa(name = "ruler", output = "svg") ruler_vertical <- fa(name = "ruler-vertical", output = "svg") ruler_horizontal <- fa(name = "ruler-horizontal", output = "svg") balance_scale_left <- fa(name = "balance-scale-left", output = "svg") balance_scale <- fa(name = "balance-scale", output = "svg") balance_scale_right <- fa(name = "balance-scale-right", output = "svg")
- 传入
icon_sets()并禁用内置嵌入:
reactable( data, columns = list( bill_length_mm = colDef(cell = icon_sets(data, icons = c(ruler), embed_fontawesome = FALSE)), bill_depth_mm = colDef(cell = icon_sets(data, icons = c(ruler_vertical), embed_fontawesome = FALSE)), flipper_length_mm = colDef(cell = icon_sets(data, icons = c(ruler_horizontal), embed_fontawesome = FALSE)), body_mass_g = colDef(cell = icon_sets(data, icons = c(balance_scale_left, balance_scale, balance_scale_right), embed_fontawesome = FALSE)) ) )
内容的提问来源于stack exchange,提问作者MarkusN
相关产品推荐
相关产品推荐

