+++ title = "Optimitza la càrrega amb un subconjunt de font personalitzat" date = 2023-04-29 updated = 2025-01-12 description = "Aprèn com crear un subconjunt personalitzat que només inclogui els glifs necessaris." [taxonomies] tags = ["funcionalitat", "tutorial"] [extra] social_media_card = "social_cards/ca_blog_custom_font_subset.jpg" +++ ## El problema Les fonts personalitzades causen parpelleig de text a Firefox. Per veure un gif i més detalls, mira [aquesta issue](https://github.com/welpo/tabi/issues/75). ## La solució Per solucionar això, tabi carrega un subconjunt de glifs per a l'encapçalament. Donat que això augmenta lleugerament el temps de càrrega inicial, és una bona idea intentar minimitzar la mida d'aquest subconjunt. Per defecte, tabi inclou fitxers de subconjunts per a caràcters en anglès i espanyol (amb alguns símbols). Aquests fitxers es carreguen quan la pàgina o el lloc web de Zola està en aquest idioma. {% admonition(type="tip") %} Si estàs fent servir una font personalitzada, pots crear el teu propi subconjunt (segueix llegint) o desactivar completament els subconjunts predeterminats amb `enable_subset = false` a `config.toml`. {% end %} Per a una optimització addicional, a continuació t'expliquem com crear un subconjunt de fonts personalitzat que només inclogui els caràcters utilitzats en el teu encapçalament. ## Requisits Instal·la aquestes eines: - [fonttools](https://github.com/fonttools/fonttools) - [brotli](https://github.com/google/brotli) Executa `pip install fonttools brotli` per instal·lar totes dues. ## L'script El següent script pren un fitxer `config.toml` i un fitxer de font com a entrada, extreu els caràcters necessaris, crea un subconjunt de la font i genera un fitxer CSS que conté el subconjunt codificat en base64. ```bash #!/usr/bin/env bash usage() { echo "Usage: $0 [--config | -c CONFIG_FILE] [--font | -f FONT_FILE] [--output | -o OUTPUT_PATH]" echo echo "Options:" echo " --config, -c Path to the config.toml file." echo " --font, -f Path to the font file." echo " --output, -o Output path for the generated custom_subset.css file (default: current directory)" echo " --help, -h Show this help message and exit" } # La sortida per defecte és el directori actual. output_path="." # Opcions de la línia de comandes. while [ "$#" -gt 0 ]; do case "$1" in --config|-c) config_file="$2" shift 2 ;; --font|-f) font_file="$2" shift 2 ;; --output|-o) output_path="$2" shift 2 ;; --help|-h) usage exit 0 ;; *) echo "Unknown option: $1" usage exit 1 ;; esac done # Comprova si s'han proporcionat les opcions -c i -f. if [ -z "$config_file" ]; then echo "Error: --config|-c option is required." usage exit 1 fi if [ -z "$font_file" ]; then echo "Error: --font|-f option is required." usage exit 1 fi # Comprova si els fitxers de configuració i de font existeixen. if [ ! -f "$config_file" ]; then echo "Error: Config file '$config_file' not found." exit 1 fi if [ ! -f "$font_file" ]; then echo "Error: Font file '$font_file' not found." exit 1 fi # Extreu el títol i els noms del menú del fitxer de configuració. title=$(awk -F' = ' '/^title/{print $2}' "$config_file" | tr -d '"') menu_names=$(awk -F' = ' '/^menu/{f=1;next} /socials/{f=0} f && /name/{print $2}' "$config_file" | cut -d',' -f1 | tr -d '"' ) language_names=$(awk -F' = ' '/^language_name\./{print $2}' "$config_file" | tr -d '"' ) # Si el lloc web és multilingüe, obté les traduccions del menú. if [ -n "$language_names" ]; then for menu_name in $menu_names; do # Find the line with the menu name inside a [languages.*.translations] section and get the translated menus. menu_translation=$(awk -F' = ' "/\\[languages.*\\.translations\\]/{f=1;next} /^\\[/ {f=0} f && /$menu_name =/{print \$2}" "$config_file" | tr -d '"' ) # Add the found menu value to the translations string menu_names+="$menu_translation" done fi # Combina les cadenes extretes. combined="$title$menu_names$language_names" # Obté els caràcters únics. unique_chars=$(echo "$combined" | grep -o . | sort -u | tr -d '\n') # Crea un fitxer temporal per a subset.woff2. temp_subset=$(mktemp) # Crea el subconjunto. pyftsubset "$font_file" \ --text="$unique_chars" \ --layout-features="*" --flavor="woff2" --output-file="$temp_subset" --with-zopfli # Codifica en base64 el fitxer temporal subset.woff2 i crea el fitxer CSS. base64_encoded_font=$(base64 -i "$temp_subset") echo "@font-face{font-family:\"Inter Subset\";src:url(data:application/font-woff2;base64,$base64_encoded_font);}" > "$output_path/custom_subset.css" # Elimina el fitxer temporal subset.woff2. rm "$temp_subset" ``` ## Ús Guarda l'script a algun lloc com `~/bin/subset_font`. Fes-lo executable amb `chmod +x ~/bin/subset_font`. Ara pots executar-lo amb les opcions requerides `--config` i `--font`: ```bash ~/bin/subset_font --config path/to/config.toml --font path/to/font.woff2 ``` De forma predeterminada, això generarà un fitxer `custom_subset.css` al directori actual. Utilitza `-o` o `--output` per especificar una ruta diferent: ```bash ~/bin/subset_font -c path/to/config.toml -f path/to/font.woff2 -o path/to/output ``` Col·loca aquest fitxer `custom_subset.css` dins del directori `static/` del teu projecte de Zola. ## Automatització amb un Pre-commit Hook És possible que canviïs el títol o les opcions del menú del teu lloc web, la qual cosa faria que el subconjunt personalitzat deixés de ser útil. Per automatitzar el procés de creació d'aquest fitxer, pots integrar l'script en un ganxo (hook) pre-commit de Git que s'activi en detectar canvis al fitxer `config.toml`, executi l'script i guardi el fitxer CSS resultant al directori `static/` del teu lloc web. 1. Crea un fitxer `.git/hooks/pre-commit` al teu projecte de Git, si encara no existeix. 2. Fes-lo executable amb `chmod +x .git/hooks/pre-commit`. 3. Afegeix el següent codi al fitxer: ```bash # Comprova si config.toml s'ha modificat. if git diff --cached --name-only | grep -q "config.toml"; then echo "config.toml modified. Running subset_font…" # Executa l'script subset_font. ~/bin/subset_font -c config.toml -f static/fonts/Inter4.woff2 -o static/ # Afegeix el fitxer subset.css generat al commit. git add static/custom_subset.css fi ``` Asegura't de modificar l'script perquè coincideixi amb la ruta on has guardat l'script `subset_font`. Les rutes de configuració i font haurien de funcionar correctament amb la configuració predeterminada de tabi. Ara, cada vegada que facis canvis al teu projecte de Git i facis commit, el ganxo pre-commit verificarà les modificacions al fitxer `config.toml` i executarà automàticament l'script `subset_font` per actualitzar el fitxer `custom_subset.css`. Per cert, si t'interessa una forma d'actualitzar automàticament la data de les teves publicacions a Zola o comprimir automàticament els teus fitxers PNG, fes un cop d'ull a [aquesta publicació](https://osc.garden/ca/blog/zola-date-git-hook/). Si desitges utilitzar tots els scripts alhora (compressió de fitxers PNG, actualització de la data i creació del subconjunt de fonts), combina el seu codi en un sol fitxer `.git/hooks/pre-commit`.