Fase 4.1: Bootstrap Icons subset (94% reduccion)
Optimizacion PageSpeed: - Original: 211 KB (2050 iconos) - Subset: 13 KB (104 iconos usados) - Ahorro: 198 KB (94% reduccion) Cambios: - Creado script create-icons-subset.py para generar subsets - Generado bootstrap-icons-subset.min.css (4.5 KB) - Generado bootstrap-icons-subset.woff2 (8.7 KB) - Agregado font-display:swap (elimina bloqueo de 420ms) - Actualizado enqueue-scripts.php para usar subset 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
127
Assets/Vendor/bootstrap-icons-subset.css
vendored
Normal file
127
Assets/Vendor/bootstrap-icons-subset.css
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
/*!
|
||||
* Bootstrap Icons Subset - ROI Theme
|
||||
* 104 iconos de 2050 originales (5.1%)
|
||||
* Generado automaticamente - NO EDITAR
|
||||
*/
|
||||
@font-face{
|
||||
font-display:swap;
|
||||
font-family:bootstrap-icons;
|
||||
src:url("fonts/bootstrap-icons-subset.woff2") format("woff2"),
|
||||
url("fonts/bootstrap-icons-subset.woff") format("woff")
|
||||
}
|
||||
.bi::before,[class*=" bi-"]::before,[class^=bi-]::before{
|
||||
display:inline-block;
|
||||
font-family:bootstrap-icons!important;
|
||||
font-style:normal;
|
||||
font-weight:400!important;
|
||||
font-variant:normal;
|
||||
text-transform:none;
|
||||
line-height:1;
|
||||
vertical-align:-.125em;
|
||||
-webkit-font-smoothing:antialiased;
|
||||
-moz-osx-font-smoothing:grayscale
|
||||
}
|
||||
.bi-arrow-counterclockwise::before{content:"\f117"}
|
||||
.bi-arrow-down-circle::before{content:"\f119"}
|
||||
.bi-arrow-right::before{content:"\f138"}
|
||||
.bi-arrow-up::before{content:"\f148"}
|
||||
.bi-arrows-angle-expand::before{content:"\f14a"}
|
||||
.bi-arrows-expand::before{content:"\f14c"}
|
||||
.bi-arrows-fullscreen::before{content:"\f14d"}
|
||||
.bi-arrows-move::before{content:"\f14e"}
|
||||
.bi-arrows-vertical::before{content:"\f698"}
|
||||
.bi-aspect-ratio::before{content:"\f150"}
|
||||
.bi-badge-ad::before{content:"\f161"}
|
||||
.bi-bar-chart::before{content:"\f17e"}
|
||||
.bi-bootstrap::before{content:"\f1a8"}
|
||||
.bi-bounding-box::before{content:"\f1b6"}
|
||||
.bi-box-arrow-up-right::before{content:"\f1c5"}
|
||||
.bi-c-circle::before{content:"\f7db"}
|
||||
.bi-calendar-check::before{content:"\f1e2"}
|
||||
.bi-calendar3::before{content:"\f214"}
|
||||
.bi-card-image::before{content:"\f226"}
|
||||
.bi-card-text::before{content:"\f228"}
|
||||
.bi-chat-dots::before{content:"\f24a"}
|
||||
.bi-chat-dots-fill::before{content:"\f249"}
|
||||
.bi-chat-quote::before{content:"\f255"}
|
||||
.bi-chat-text::before{content:"\f267"}
|
||||
.bi-check-circle::before{content:"\f26b"}
|
||||
.bi-chevron-down::before{content:"\f282"}
|
||||
.bi-clock::before{content:"\f293"}
|
||||
.bi-code::before{content:"\f2c8"}
|
||||
.bi-code-slash::before{content:"\f2c6"}
|
||||
.bi-cursor::before{content:"\f2e3"}
|
||||
.bi-display::before{content:"\f302"}
|
||||
.bi-envelope::before{content:"\f32f"}
|
||||
.bi-envelope-fill::before{content:"\f32c"}
|
||||
.bi-envelope-paper::before{content:"\f73d"}
|
||||
.bi-exclamation-octagon::before{content:"\f337"}
|
||||
.bi-exclamation-triangle::before{content:"\f33b"}
|
||||
.bi-eye::before{content:"\f341"}
|
||||
.bi-facebook::before{content:"\f344"}
|
||||
.bi-file-earmark-text::before{content:"\f38b"}
|
||||
.bi-file-text::before{content:"\f3b9"}
|
||||
.bi-filetype-css::before{content:"\f742"}
|
||||
.bi-filetype-js::before{content:"\f74c"}
|
||||
.bi-folder-fill::before{content:"\f3d1"}
|
||||
.bi-fonts::before{content:"\f3da"}
|
||||
.bi-gear::before{content:"\f3e5"}
|
||||
.bi-geo-alt-fill::before{content:"\f3e7"}
|
||||
.bi-globe::before{content:"\f3ee"}
|
||||
.bi-graph-up::before{content:"\f3f2"}
|
||||
.bi-grid::before{content:"\f3fc"}
|
||||
.bi-grid-3x3-gap::before{content:"\f3f9"}
|
||||
.bi-hand-index::before{content:"\f403"}
|
||||
.bi-hourglass::before{content:"\f421"}
|
||||
.bi-hourglass-split::before{content:"\f41f"}
|
||||
.bi-image::before{content:"\f42a"}
|
||||
.bi-info-circle::before{content:"\f431"}
|
||||
.bi-input-cursor::before{content:"\f436"}
|
||||
.bi-input-cursor-text::before{content:"\f435"}
|
||||
.bi-instagram::before{content:"\f437"}
|
||||
.bi-key::before{content:"\f44f"}
|
||||
.bi-layout-sidebar::before{content:"\f45f"}
|
||||
.bi-layout-text-window-reverse::before{content:"\f463"}
|
||||
.bi-lightning::before{content:"\f46f"}
|
||||
.bi-lightning-charge-fill::before{content:"\f46c"}
|
||||
.bi-link::before{content:"\f471"}
|
||||
.bi-link-45deg::before{content:"\f470"}
|
||||
.bi-linkedin::before{content:"\f472"}
|
||||
.bi-list::before{content:"\f479"}
|
||||
.bi-list-nested::before{content:"\f474"}
|
||||
.bi-list-ol::before{content:"\f475"}
|
||||
.bi-list-ul::before{content:"\f478"}
|
||||
.bi-magic::before{content:"\f675"}
|
||||
.bi-megaphone::before{content:"\f484"}
|
||||
.bi-megaphone-fill::before{content:"\f483"}
|
||||
.bi-menu-button-wide::before{content:"\f489"}
|
||||
.bi-mouse::before{content:"\f499"}
|
||||
.bi-palette::before{content:"\f4b1"}
|
||||
.bi-person::before{content:"\f4e1"}
|
||||
.bi-person-lines-fill::before{content:"\f4db"}
|
||||
.bi-phone::before{content:"\f4e7"}
|
||||
.bi-pin::before{content:"\f4ed"}
|
||||
.bi-power::before{content:"\f4ff"}
|
||||
.bi-send-fill::before{content:"\f6b9"}
|
||||
.bi-share::before{content:"\f52e"}
|
||||
.bi-shield-check::before{content:"\f52f"}
|
||||
.bi-shield-lock::before{content:"\f538"}
|
||||
.bi-shield-x::before{content:"\f53e"}
|
||||
.bi-slash-circle::before{content:"\f567"}
|
||||
.bi-sliders::before{content:"\f56b"}
|
||||
.bi-square::before{content:"\f584"}
|
||||
.bi-star::before{content:"\f588"}
|
||||
.bi-star-fill::before{content:"\f586"}
|
||||
.bi-stars::before{content:"\f589"}
|
||||
.bi-tablet::before{content:"\f5ae"}
|
||||
.bi-tag::before{content:"\f5b0"}
|
||||
.bi-tags::before{content:"\f5b2"}
|
||||
.bi-telephone-fill::before{content:"\f5b4"}
|
||||
.bi-text-center::before{content:"\f5c4"}
|
||||
.bi-text-paragraph::before{content:"\f5c8"}
|
||||
.bi-three-dots::before{content:"\f5d4"}
|
||||
.bi-toggle-on::before{content:"\f5d6"}
|
||||
.bi-twitter-x::before{content:"\f8db"}
|
||||
.bi-type::before{content:"\f5f7"}
|
||||
.bi-whatsapp::before{content:"\f618"}
|
||||
.bi-x-circle::before{content:"\f623"}
|
||||
1
Assets/Vendor/bootstrap-icons-subset.min.css
vendored
Normal file
1
Assets/Vendor/bootstrap-icons-subset.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
@font-face{font-display:swap;font-family:bootstrap-icons;src:url("fonts/bootstrap-icons-subset.woff2") format("woff2"),url("fonts/bootstrap-icons-subset.woff") format("woff")}.bi::before,[class*=" bi-"]::before,[class^=bi-]::before{display:inline-block;font-family:bootstrap-icons!important;font-style:normal;font-weight:400!important;font-variant:normal;text-transform:none;line-height:1;vertical-align:-.125em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.bi-arrow-counterclockwise::before{content:"\f117"}.bi-arrow-down-circle::before{content:"\f119"}.bi-arrow-right::before{content:"\f138"}.bi-arrow-up::before{content:"\f148"}.bi-arrows-angle-expand::before{content:"\f14a"}.bi-arrows-expand::before{content:"\f14c"}.bi-arrows-fullscreen::before{content:"\f14d"}.bi-arrows-move::before{content:"\f14e"}.bi-arrows-vertical::before{content:"\f698"}.bi-aspect-ratio::before{content:"\f150"}.bi-badge-ad::before{content:"\f161"}.bi-bar-chart::before{content:"\f17e"}.bi-bootstrap::before{content:"\f1a8"}.bi-bounding-box::before{content:"\f1b6"}.bi-box-arrow-up-right::before{content:"\f1c5"}.bi-c-circle::before{content:"\f7db"}.bi-calendar-check::before{content:"\f1e2"}.bi-calendar3::before{content:"\f214"}.bi-card-image::before{content:"\f226"}.bi-card-text::before{content:"\f228"}.bi-chat-dots::before{content:"\f24a"}.bi-chat-dots-fill::before{content:"\f249"}.bi-chat-quote::before{content:"\f255"}.bi-chat-text::before{content:"\f267"}.bi-check-circle::before{content:"\f26b"}.bi-chevron-down::before{content:"\f282"}.bi-clock::before{content:"\f293"}.bi-code::before{content:"\f2c8"}.bi-code-slash::before{content:"\f2c6"}.bi-cursor::before{content:"\f2e3"}.bi-display::before{content:"\f302"}.bi-envelope::before{content:"\f32f"}.bi-envelope-fill::before{content:"\f32c"}.bi-envelope-paper::before{content:"\f73d"}.bi-exclamation-octagon::before{content:"\f337"}.bi-exclamation-triangle::before{content:"\f33b"}.bi-eye::before{content:"\f341"}.bi-facebook::before{content:"\f344"}.bi-file-earmark-text::before{content:"\f38b"}.bi-file-text::before{content:"\f3b9"}.bi-filetype-css::before{content:"\f742"}.bi-filetype-js::before{content:"\f74c"}.bi-folder-fill::before{content:"\f3d1"}.bi-fonts::before{content:"\f3da"}.bi-gear::before{content:"\f3e5"}.bi-geo-alt-fill::before{content:"\f3e7"}.bi-globe::before{content:"\f3ee"}.bi-graph-up::before{content:"\f3f2"}.bi-grid::before{content:"\f3fc"}.bi-grid-3x3-gap::before{content:"\f3f9"}.bi-hand-index::before{content:"\f403"}.bi-hourglass::before{content:"\f421"}.bi-hourglass-split::before{content:"\f41f"}.bi-image::before{content:"\f42a"}.bi-info-circle::before{content:"\f431"}.bi-input-cursor::before{content:"\f436"}.bi-input-cursor-text::before{content:"\f435"}.bi-instagram::before{content:"\f437"}.bi-key::before{content:"\f44f"}.bi-layout-sidebar::before{content:"\f45f"}.bi-layout-text-window-reverse::before{content:"\f463"}.bi-lightning::before{content:"\f46f"}.bi-lightning-charge-fill::before{content:"\f46c"}.bi-link::before{content:"\f471"}.bi-link-45deg::before{content:"\f470"}.bi-linkedin::before{content:"\f472"}.bi-list::before{content:"\f479"}.bi-list-nested::before{content:"\f474"}.bi-list-ol::before{content:"\f475"}.bi-list-ul::before{content:"\f478"}.bi-magic::before{content:"\f675"}.bi-megaphone::before{content:"\f484"}.bi-megaphone-fill::before{content:"\f483"}.bi-menu-button-wide::before{content:"\f489"}.bi-mouse::before{content:"\f499"}.bi-palette::before{content:"\f4b1"}.bi-person::before{content:"\f4e1"}.bi-person-lines-fill::before{content:"\f4db"}.bi-phone::before{content:"\f4e7"}.bi-pin::before{content:"\f4ed"}.bi-power::before{content:"\f4ff"}.bi-send-fill::before{content:"\f6b9"}.bi-share::before{content:"\f52e"}.bi-shield-check::before{content:"\f52f"}.bi-shield-lock::before{content:"\f538"}.bi-shield-x::before{content:"\f53e"}.bi-slash-circle::before{content:"\f567"}.bi-sliders::before{content:"\f56b"}.bi-square::before{content:"\f584"}.bi-star::before{content:"\f588"}.bi-star-fill::before{content:"\f586"}.bi-stars::before{content:"\f589"}.bi-tablet::before{content:"\f5ae"}.bi-tag::before{content:"\f5b0"}.bi-tags::before{content:"\f5b2"}.bi-telephone-fill::before{content:"\f5b4"}.bi-text-center::before{content:"\f5c4"}.bi-text-paragraph::before{content:"\f5c8"}.bi-three-dots::before{content:"\f5d4"}.bi-toggle-on::before{content:"\f5d6"}.bi-twitter-x::before{content:"\f8db"}.bi-type::before{content:"\f5f7"}.bi-whatsapp::before{content:"\f618"}.bi-x-circle::before{content:"\f623"}
|
||||
281
Assets/Vendor/create-icons-subset.py
vendored
Normal file
281
Assets/Vendor/create-icons-subset.py
vendored
Normal file
@@ -0,0 +1,281 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Bootstrap Icons Subset Generator
|
||||
Genera CSS y fuente optimizados solo con los iconos usados en roi-theme
|
||||
"""
|
||||
|
||||
import re
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
# Directorio base
|
||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
# Iconos usados en roi-theme (extraidos con grep)
|
||||
USED_ICONS = [
|
||||
"bi-arrow-counterclockwise",
|
||||
"bi-arrow-down-circle",
|
||||
"bi-arrow-right",
|
||||
"bi-arrows-angle-expand",
|
||||
"bi-arrows-expand",
|
||||
"bi-arrows-fullscreen",
|
||||
"bi-arrows-move",
|
||||
"bi-arrows-vertical",
|
||||
"bi-arrow-up",
|
||||
"bi-aspect-ratio",
|
||||
"bi-badge-ad",
|
||||
"bi-bar-chart",
|
||||
"bi-bootstrap",
|
||||
"bi-bounding-box",
|
||||
"bi-box-arrow-up-right",
|
||||
"bi-calendar3",
|
||||
"bi-calendar-check",
|
||||
"bi-card-image",
|
||||
"bi-card-text",
|
||||
"bi-c-circle",
|
||||
"bi-chat-dots",
|
||||
"bi-chat-dots-fill",
|
||||
"bi-chat-quote",
|
||||
"bi-chat-text",
|
||||
"bi-check-circle",
|
||||
"bi-chevron-down",
|
||||
"bi-clock",
|
||||
"bi-code",
|
||||
"bi-code-slash",
|
||||
"bi-cursor",
|
||||
"bi-display",
|
||||
"bi-envelope",
|
||||
"bi-envelope-fill",
|
||||
"bi-envelope-paper",
|
||||
"bi-exclamation-octagon",
|
||||
"bi-exclamation-triangle",
|
||||
"bi-eye",
|
||||
"bi-facebook",
|
||||
"bi-file-earmark-text",
|
||||
"bi-file-text",
|
||||
"bi-filetype-css",
|
||||
"bi-filetype-js",
|
||||
"bi-folder-fill",
|
||||
"bi-fonts",
|
||||
"bi-gear",
|
||||
"bi-geo-alt-fill",
|
||||
"bi-globe",
|
||||
"bi-graph-up",
|
||||
"bi-grid",
|
||||
"bi-grid-3x3-gap",
|
||||
"bi-hand-index",
|
||||
"bi-hourglass",
|
||||
"bi-hourglass-split",
|
||||
"bi-image",
|
||||
"bi-info-circle",
|
||||
"bi-input-cursor",
|
||||
"bi-input-cursor-text",
|
||||
"bi-instagram",
|
||||
"bi-key",
|
||||
"bi-layout-sidebar",
|
||||
"bi-layout-text-window-reverse",
|
||||
"bi-lightning",
|
||||
"bi-lightning-charge-fill",
|
||||
"bi-link",
|
||||
"bi-link-45deg",
|
||||
"bi-linkedin",
|
||||
"bi-list",
|
||||
"bi-list-nested",
|
||||
"bi-list-ol",
|
||||
"bi-list-ul",
|
||||
"bi-magic",
|
||||
"bi-megaphone",
|
||||
"bi-megaphone-fill",
|
||||
"bi-menu-button-wide",
|
||||
"bi-mouse",
|
||||
"bi-palette",
|
||||
"bi-person",
|
||||
"bi-person-lines-fill",
|
||||
"bi-phone",
|
||||
"bi-pin",
|
||||
"bi-power",
|
||||
"bi-send-fill",
|
||||
"bi-share",
|
||||
"bi-shield-check",
|
||||
"bi-shield-lock",
|
||||
"bi-shield-x",
|
||||
"bi-slash-circle",
|
||||
"bi-sliders",
|
||||
"bi-square",
|
||||
"bi-star",
|
||||
"bi-star-fill",
|
||||
"bi-stars",
|
||||
"bi-tablet",
|
||||
"bi-tag",
|
||||
"bi-tags",
|
||||
"bi-telephone-fill",
|
||||
"bi-text-center",
|
||||
"bi-text-paragraph",
|
||||
"bi-three-dots",
|
||||
"bi-toggle-on",
|
||||
"bi-twitter-x",
|
||||
"bi-type",
|
||||
"bi-whatsapp",
|
||||
"bi-x-circle",
|
||||
]
|
||||
|
||||
def read_original_css():
|
||||
"""Lee el CSS original de Bootstrap Icons"""
|
||||
css_path = os.path.join(BASE_DIR, "bootstrap-icons.min.css")
|
||||
with open(css_path, "r", encoding="utf-8") as f:
|
||||
return f.read()
|
||||
|
||||
def extract_unicode_codes(css_content, icons):
|
||||
"""Extrae los codigos unicode de los iconos usados"""
|
||||
codes = {}
|
||||
for icon in icons:
|
||||
# Buscar .bi-nombre::before{content:"\XXXX"}
|
||||
pattern = rf'\.{re.escape(icon)}::before\{{content:"\\([a-f0-9]+)"\}}'
|
||||
match = re.search(pattern, css_content, re.IGNORECASE)
|
||||
if match:
|
||||
codes[icon] = match.group(1)
|
||||
else:
|
||||
print(f"WARNING: No se encontro codigo para {icon}")
|
||||
return codes
|
||||
|
||||
def generate_subset_css(codes):
|
||||
"""Genera el CSS subset con solo los iconos usados"""
|
||||
css_lines = []
|
||||
|
||||
# Header
|
||||
css_lines.append("/*!")
|
||||
css_lines.append(" * Bootstrap Icons Subset - ROI Theme")
|
||||
css_lines.append(f" * {len(codes)} iconos de 2050 originales ({len(codes)/2050*100:.1f}%)")
|
||||
css_lines.append(" * Generado automaticamente - NO EDITAR")
|
||||
css_lines.append(" */")
|
||||
|
||||
# @font-face con font-display: swap
|
||||
css_lines.append('@font-face{')
|
||||
css_lines.append(' font-display:swap;')
|
||||
css_lines.append(' font-family:bootstrap-icons;')
|
||||
css_lines.append(' src:url("fonts/bootstrap-icons-subset.woff2") format("woff2"),')
|
||||
css_lines.append(' url("fonts/bootstrap-icons-subset.woff") format("woff")')
|
||||
css_lines.append('}')
|
||||
|
||||
# Estilos base para .bi
|
||||
css_lines.append('.bi::before,[class*=" bi-"]::before,[class^=bi-]::before{')
|
||||
css_lines.append(' display:inline-block;')
|
||||
css_lines.append(' font-family:bootstrap-icons!important;')
|
||||
css_lines.append(' font-style:normal;')
|
||||
css_lines.append(' font-weight:400!important;')
|
||||
css_lines.append(' font-variant:normal;')
|
||||
css_lines.append(' text-transform:none;')
|
||||
css_lines.append(' line-height:1;')
|
||||
css_lines.append(' vertical-align:-.125em;')
|
||||
css_lines.append(' -webkit-font-smoothing:antialiased;')
|
||||
css_lines.append(' -moz-osx-font-smoothing:grayscale')
|
||||
css_lines.append('}')
|
||||
|
||||
# Reglas para cada icono
|
||||
for icon, code in sorted(codes.items()):
|
||||
css_lines.append(f'.{icon}::before{{content:"\\{code}"}}')
|
||||
|
||||
return '\n'.join(css_lines)
|
||||
|
||||
def generate_minified_css(codes):
|
||||
"""Genera CSS minificado"""
|
||||
parts = []
|
||||
|
||||
# @font-face
|
||||
parts.append('@font-face{font-display:swap;font-family:bootstrap-icons;src:url("fonts/bootstrap-icons-subset.woff2") format("woff2"),url("fonts/bootstrap-icons-subset.woff") format("woff")}')
|
||||
|
||||
# Estilos base
|
||||
parts.append('.bi::before,[class*=" bi-"]::before,[class^=bi-]::before{display:inline-block;font-family:bootstrap-icons!important;font-style:normal;font-weight:400!important;font-variant:normal;text-transform:none;line-height:1;vertical-align:-.125em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}')
|
||||
|
||||
# Iconos
|
||||
icon_rules = [f'.{icon}::before{{content:"\\{code}"}}' for icon, code in sorted(codes.items())]
|
||||
parts.append(''.join(icon_rules))
|
||||
|
||||
return ''.join(parts)
|
||||
|
||||
def create_font_subset(codes):
|
||||
"""Crea subset de la fuente usando pyftsubset"""
|
||||
# Crear archivo con unicodes
|
||||
unicodes = ','.join([f'U+{code}' for code in codes.values()])
|
||||
|
||||
# Paths
|
||||
woff2_src = os.path.join(BASE_DIR, "fonts", "bootstrap-icons.woff2")
|
||||
woff2_dst = os.path.join(BASE_DIR, "fonts", "bootstrap-icons-subset.woff2")
|
||||
woff_src = os.path.join(BASE_DIR, "fonts", "bootstrap-icons.woff")
|
||||
woff_dst = os.path.join(BASE_DIR, "fonts", "bootstrap-icons-subset.woff")
|
||||
|
||||
# Crear subset woff2
|
||||
print(f"Creando subset woff2 con {len(codes)} glyphs...")
|
||||
cmd_woff2 = [
|
||||
"pyftsubset",
|
||||
woff2_src,
|
||||
f"--unicodes={unicodes}",
|
||||
f"--output-file={woff2_dst}",
|
||||
"--flavor=woff2"
|
||||
]
|
||||
subprocess.run(cmd_woff2, check=True)
|
||||
|
||||
# Crear subset woff
|
||||
print(f"Creando subset woff con {len(codes)} glyphs...")
|
||||
cmd_woff = [
|
||||
"pyftsubset",
|
||||
woff_src,
|
||||
f"--unicodes={unicodes}",
|
||||
f"--output-file={woff_dst}",
|
||||
"--flavor=woff"
|
||||
]
|
||||
subprocess.run(cmd_woff, check=True)
|
||||
|
||||
# Mostrar tamanos
|
||||
orig_size = os.path.getsize(woff2_src) / 1024
|
||||
new_size = os.path.getsize(woff2_dst) / 1024
|
||||
print(f"woff2: {orig_size:.1f} KB -> {new_size:.1f} KB ({(1-new_size/orig_size)*100:.1f}% reduccion)")
|
||||
|
||||
def main():
|
||||
print("=== Bootstrap Icons Subset Generator ===\n")
|
||||
|
||||
# 1. Leer CSS original
|
||||
print("1. Leyendo CSS original...")
|
||||
css_content = read_original_css()
|
||||
|
||||
# 2. Extraer codigos unicode
|
||||
print(f"2. Extrayendo codigos de {len(USED_ICONS)} iconos...")
|
||||
codes = extract_unicode_codes(css_content, USED_ICONS)
|
||||
print(f" Encontrados: {len(codes)} iconos")
|
||||
|
||||
# 3. Generar CSS subset
|
||||
print("3. Generando CSS subset...")
|
||||
subset_css = generate_subset_css(codes)
|
||||
css_path = os.path.join(BASE_DIR, "bootstrap-icons-subset.css")
|
||||
with open(css_path, "w", encoding="utf-8") as f:
|
||||
f.write(subset_css)
|
||||
print(f" Guardado: bootstrap-icons-subset.css")
|
||||
|
||||
# 4. Generar CSS minificado
|
||||
print("4. Generando CSS minificado...")
|
||||
min_css = generate_minified_css(codes)
|
||||
min_path = os.path.join(BASE_DIR, "bootstrap-icons-subset.min.css")
|
||||
with open(min_path, "w", encoding="utf-8") as f:
|
||||
f.write(min_css)
|
||||
orig_css_size = os.path.getsize(os.path.join(BASE_DIR, "bootstrap-icons.min.css")) / 1024
|
||||
new_css_size = os.path.getsize(min_path) / 1024
|
||||
print(f" CSS: {orig_css_size:.1f} KB -> {new_css_size:.1f} KB ({(1-new_css_size/orig_css_size)*100:.1f}% reduccion)")
|
||||
|
||||
# 5. Crear font subset
|
||||
print("5. Creando font subset...")
|
||||
try:
|
||||
create_font_subset(codes)
|
||||
except Exception as e:
|
||||
print(f" ERROR: {e}")
|
||||
print(" Intenta ejecutar: pip install fonttools brotli")
|
||||
return
|
||||
|
||||
print("\n=== COMPLETADO ===")
|
||||
print("Archivos generados:")
|
||||
print(" - bootstrap-icons-subset.css (legible)")
|
||||
print(" - bootstrap-icons-subset.min.css (minificado)")
|
||||
print(" - fonts/bootstrap-icons-subset.woff2")
|
||||
print(" - fonts/bootstrap-icons-subset.woff")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
BIN
Assets/Vendor/fonts/bootstrap-icons-subset.woff
vendored
Normal file
BIN
Assets/Vendor/fonts/bootstrap-icons-subset.woff
vendored
Normal file
Binary file not shown.
BIN
Assets/Vendor/fonts/bootstrap-icons-subset.woff2
vendored
Normal file
BIN
Assets/Vendor/fonts/bootstrap-icons-subset.woff2
vendored
Normal file
Binary file not shown.
Reference in New Issue
Block a user