rstudio / bslib

Tools for theming Shiny and R Markdown via Bootstrap 3, 4, or 5.
https://rstudio.github.io/bslib/
Other
466 stars 57 forks source link

Font file count #667

Open schloerke opened 1 year ago

schloerke commented 1 year ago

Describe the problem

When saving the dependencies for the shiny preset theme, 70x .woff files are saved. But only 16x .woff links exist in font.css

I'm ok if they're all used, but it seems excessive for the amount of links inside the font.css file.

Reprex of behavior:

shiny_theme <- bslib::bs_theme(version = 5, preset = "shiny")
deps <- bslib::bs_theme_dependencies(shiny_theme)
out_dir <- "my_dir"
dir.create(out_dir)
withr::with_options(
  list(htmltools.dir.version = FALSE),
  ignore <- lapply(deps, htmltools::copyDependencyToDir, out_dir)
)
length(dir(file.path(out_dir, "bootstrap", "fonts"), pattern = "\\.woff$"))
#> [1] 70

woff_count <- function(file) {
  parts <- unlist(strsplit(readLines(file), ";"))
  has_woff <- grepl("fonts/[a-zA-Z0-9_-]*\\.woff", parts)
  sum(has_woff)
}

woff_count(file.path(out_dir, "bootstrap", "bootstrap.min.css"))
#> [1] 0
woff_count(file.path(out_dir, "bootstrap", "font.css"))
#> [1] 16

readLines(file.path(out_dir, "/bootstrap/font.css")) %>% 
  strsplit(";") %>% 
  unlist() %>% {.[grepl('fonts/[a-zA-Z0-9_-]*\\.woff', .)]} %>% length()
[1] 16

Session Info


─ Session info ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.3.0 (2023-04-21)
 os       macOS Ventura 13.3.1
 system   aarch64, darwin20
 ui       X11
 language (EN)
 collate  en_US.UTF-8
 ctype    en_US.UTF-8
 tz       America/New_York
 date     2023-07-11
 pandoc   3.1 @ /opt/homebrew/bin/pandoc

─ Packages ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 package     * version    date (UTC) lib source
 bslib       * 0.5.0.9000 2023-07-11 [1] Github (rstudio/bslib@64de13a)
 cachem        1.0.8      2023-05-01 [1] CRAN (R 4.3.0)
 callr         3.7.3      2022-11-02 [1] CRAN (R 4.3.0)
 cli           3.6.1      2023-03-23 [1] CRAN (R 4.3.0)
 clisymbols    1.2.0      2017-05-21 [1] CRAN (R 4.3.0)
 colorout      1.2-2      2023-05-16 [1] Github (jalvesaq/colorout@79931fd)
 crayon        1.5.2      2022-09-29 [1] CRAN (R 4.3.0)
 desc          1.4.2      2022-09-08 [1] CRAN (R 4.3.0)
 devtools      2.4.5      2022-10-11 [1] CRAN (R 4.3.0)
 digest        0.6.31     2022-12-11 [1] CRAN (R 4.3.0)
 ellipsis      0.3.2      2021-04-29 [1] CRAN (R 4.3.0)
 fansi         1.0.4      2023-01-22 [1] CRAN (R 4.3.0)
 fastmap       1.1.1      2023-02-24 [1] CRAN (R 4.3.0)
 fs            1.6.2      2023-04-25 [1] CRAN (R 4.3.0)
 git2r         0.32.0     2023-04-12 [1] CRAN (R 4.3.0)
 glue          1.6.2      2022-02-24 [1] CRAN (R 4.3.0)
 htmltools     0.5.5.9000 2023-07-11 [1] Github (rstudio/htmltools@e97a314)
 htmlwidgets   1.6.2      2023-03-17 [1] CRAN (R 4.3.0)
 httpuv        1.6.11     2023-05-11 [1] CRAN (R 4.3.0)
 jquerylib     0.1.4      2021-04-26 [1] CRAN (R 4.3.0)
 jsonlite      1.8.5      2023-06-05 [1] CRAN (R 4.3.0)
 later         1.3.1      2023-05-02 [1] CRAN (R 4.3.0)
 lifecycle     1.0.3      2022-10-07 [1] CRAN (R 4.3.0)
 magrittr      2.0.3      2022-03-30 [1] CRAN (R 4.3.0)
 memoise       2.0.1      2021-11-26 [1] CRAN (R 4.3.0)
 memuse        4.2-3      2023-01-24 [1] CRAN (R 4.3.0)
 mime          0.12       2021-09-28 [1] CRAN (R 4.3.0)
 miniUI        0.1.1.1    2018-05-18 [1] CRAN (R 4.3.0)
 pillar        1.9.0      2023-03-22 [1] CRAN (R 4.3.0)
 pkgbuild      1.4.0      2022-11-27 [1] CRAN (R 4.3.0)
 pkgconfig     2.0.3      2019-09-22 [1] CRAN (R 4.3.0)
 pkgload       1.3.2      2022-11-16 [1] CRAN (R 4.3.0)
 prettyunits   1.1.1      2020-01-24 [1] CRAN (R 4.3.0)
 processx      3.8.1      2023-04-18 [1] CRAN (R 4.3.0)
 profvis       0.3.8      2023-05-02 [1] CRAN (R 4.3.0)
 promises      1.2.0.1    2021-02-11 [1] CRAN (R 4.3.0)
 prompt        1.0.1      2023-05-16 [1] Github (gaborcsardi/prompt@7ef0f2e)
 ps            1.7.5      2023-04-18 [1] CRAN (R 4.3.0)
 purrr         1.0.1      2023-01-10 [1] CRAN (R 4.3.0)
 R6            2.5.1      2021-08-19 [1] CRAN (R 4.3.0)
 Rcpp          1.0.10     2023-01-22 [1] CRAN (R 4.3.0)
 remotes       2.4.2      2021-11-30 [1] CRAN (R 4.3.0)
 rlang         1.1.1      2023-04-28 [1] CRAN (R 4.3.0)
 rprojroot     2.0.3      2022-04-02 [1] CRAN (R 4.3.0)
 sass          0.4.6      2023-05-03 [1] CRAN (R 4.3.0)
 sessioninfo   1.2.2      2021-12-06 [1] CRAN (R 4.3.0)
 shiny       * 1.7.4.9002 2023-07-11 [1] Github (rstudio/shiny@6fc0628)
 stringi       1.7.12     2023-01-11 [1] CRAN (R 4.3.0)
 stringr       1.5.0      2022-12-02 [1] CRAN (R 4.3.0)
 tibble        3.2.1      2023-03-20 [1] CRAN (R 4.3.0)
 urlchecker    1.0.1      2021-11-30 [1] CRAN (R 4.3.0)
 usethis       2.2.1      2023-06-23 [1] CRAN (R 4.3.0)
 utf8          1.2.3      2023-01-31 [1] CRAN (R 4.3.0)
 vctrs         0.6.2      2023-04-19 [1] CRAN (R 4.3.0)
 withr         2.5.0      2022-03-03 [1] CRAN (R 4.3.0)
 xtable        1.8-4      2019-04-21 [1] CRAN (R 4.3.0)

 [1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library

gadenbuie commented 1 year ago

@schloerke those font files include all of the fonts downloaded for the Bootswatch presets provided by bslib, so you definitely don't want all of them. It looks like you're on the right path of finding the fonts needed for preset = "shiny" and copying only those.

schloerke commented 1 year ago

I don't mind trimming the set of font files myself, but it feels like {bslib} should only provide the usable set of fonts... not all fonts bslib knows about.

gadenbuie commented 1 year ago

but it feels like {bslib} should only provide the usable set of fonts... not all fonts bslib knows about.

I'm not sure I follow and my confusion probably rests on what you mean by provide.

Within the package, bslib bundles the fonts used by Bootstrap or Bootswatch. We store all of the fonts in one location and provide that collection of fonts by making them available in the bs_theme() dependency. AFAICT, we don't inline those fonts or bundle them into Bootstrap, but they're made available upon request. In that sense we provide all of the fonts bslib knows about, but this is a local server-side copy and not something we need to optimize. Only the requested fonts are sent to the client.

If you invert the question and find where the fonts are used, many fonts are used in more than one file.

fonts <-
 fs::path_package("bslib", "fonts") |>
 fs::dir_ls(glob = "*.woff") |>
 fs::path_file()

fonts[1:3]
#> [1] "1Ptxg8zYS_SKggPN4iEgvnHyvveLxVs9pbCIPrc.woff"
#> [2] "1Ptxg8zYS_SKggPN4iEgvnHyvveLxVvaorCIPrc.woff"
#> [3] "1adeadb2fe618c5ed46221f15e12b9c8.woff"

files <- vector("list", length(fonts))
names(files) <- fonts

for (font in fonts) {
  files[[font]] <- processx::run(
    "grep",
    args = c("-rl", font, fs::path_package("bslib"))
  )
  # grepl -l returns the file name where a match is found
  files[[font]] <- strsplit(files[[font]]$stdout, "\n")[[1]]
}

font_used_in_file_count <- vapply(files, length, integer(1))

sum(font_used_in_file_count)
#> [1] 169
all(font_used_in_file_count > 0)
#> [1] TRUE