Table des matières
新特性:图标字体库压缩
爬虫实现原理
虚拟浏览器技术
操作样式语法树
查找字体
面朝大海,春暖花开
查找字符
伪元素
Maison interface Web tutoriel HTML WebFont 智能压缩工具——字蛛 1.0.0 正式版发布_html/css_WEB-ITnose

WebFont 智能压缩工具——字蛛 1.0.0 正式版发布_html/css_WEB-ITnose

Jun 24, 2016 am 11:18 AM

字蛛是一个 WebFont 智能压缩工具,它能自动化分析页面中所使用的 WebFont 并进行按需压缩,通常好几 MB 的中文字体可以被压缩成几 KB 大小。

字蛛主页: http://font-spider.org

字蛛从 2014 年 7 月诞生以来,时隔近两年,终于发布了 v1.0.0 正式版本,改进如下:

  1. 支持绝大多数的中英文 Truetype 字体
  2. 支持开源图标字体库 (New: v1.0.0新特性)
  3. 支持 CSS 伪元素解析,支持 content: "string" 与 content: attr(value) 表达式
  4. 支持远程页面解析,并支持资源映射
  5. 支持四种样式规则:
  6. 支持四种调用方式:命令行、Gulp、Grunt、JS Api
  7. 性能、稳定性大幅提高

新特性:图标字体库压缩

得益于对 CSS 伪元素的支持,除了常规中英文字体压缩之外,v1.0.0 还带来了万众期待的——图标字体压缩支持,能够支持业界流行的开源图标字库。

以 Font Awesome 为例,它是一个典型的开源图标字体项目,目前包含有 628 个图标,并且还不断在添加中。虽然它已经做了很多优化,但字库的体积在移动端来说依然偏大,会影响页面载入速度。使用字蛛可以删除掉字体中没有用到的图标,将字体瘦身。例如一个使用 Font Awesome 的示例页面:

输入 font-spider 命令,启动字蛛进行字体压缩:

经过字蛛分析与压缩处理后, Font Awesome 字体中只保留了页面所用到的 20 个图标,ttf 格式字体体积由 142 KB 降为 6 KB,如果再配合使用 Webpack 等前端工具将字体 Base64 编码后内嵌到 CSS 中,载入速度可以进一步提升。

爬虫实现原理

为什么字蛛能够找到字体中没有使用的字形数据?这里就涉及到对 HTML 与 CSS 的静态分析。

虚拟浏览器技术

字蛛 v1.0.0 版本使用了虚拟浏览器技术来实现 HTML 与 CSS 加载与解析,爬虫模块所依赖的浏览器相关 API 均为它提供。

  • 处理 标签以及资源定位
  • 加载 标签或 @import 语句导入的 CSS 文件
  • 处理 CSS Unicode 字符
  • 管理网络请求,处理资源映射配置
  • 支持 CSS3 选择器、样式表树、文本节点读取

由于虚拟浏览器部分涉及到太多的东西且不是本文重点,所以本文将会略过这部分细节。这部分代码已经分离出来并开源,有兴趣可以去了解: https://github.com/aui/browser-x

操作样式语法树

字蛛是通过解析样式表语法树(CSSOM)来获得 WebFont 信息,在浏览器中可以通过 document.styleSheets 来访问 CSS 的语法树,遍历 CSS 规则的函数实现:

// 遍历 CSS 的规则var eachCssRuleList = (function() {    // 遍历 CSSRuleList    function cssRuleListFor(cssRuleList, callback) {        var index = -1;        var length = cssRuleList.length;        var cssRule, cssStyleSheet;        while (++index < length) {            cssRule = cssRuleList[index];            // 导入的样式规则            if (cssRule instanceof CSSImportRule) {                cssStyleSheet = cssRule.styleSheet;                cssRuleListFor(cssStyleSheet.cssRules || [], callback);            // CSS 媒体查询规则            } else if (cssRule instanceof CSSMediaRule) {                cssRuleListFor(cssRule.cssRules || [], callback);            // 普通的规则            } else {                callback(cssRule);            }        }    }    return function(callback) {        var index = -1;        var styleSheetList = document.styleSheets;        var length = styleSheetList.length;        var cssStyleSheet, cssRuleList;        // 遍历 StyleSheetList        while (++index < length) {            cssStyleSheet = styleSheetList[index];            cssRuleList = cssStyleSheet.cssRules || [];            cssRuleListFor(cssRuleList, callback);        }    };})();
Copier après la connexion

注:浏览器环境不允许访问跨域后的 CSSOM,但虚拟浏览器没有做此限制

查找字体

遍历样式表每一个规则,收集 CSSFontFaceRule 信息:

// 字体信息var webFonts = {};// 字体对应的元素列表var elements = {};// 找到 webFonteachCssRuleList(function(cssRule) {    if (cssRule instanceof CSSFontFaceRule) {        var style = cssRule.style;        var family = style['font-family'];        var src = style.src;        // 保存使用此字体的所有元素列表        elements[family] = [];        // 保存字体信息        webFonts[family] = {            family: family,            src: src,            chars: ''        };    }});
Copier après la connexion

以如下页面作为示例:

<!DOCTYPE html><html lang="zh-CN"><head>    <meta charset="UTF-8">    <title>font-spider</title>    <style>        @font-face {            font-family: 'demo-font';            src: url('./demo-font.ttf');        }        h1.title {            font-family: 'demo-font';        }        h1.title::after {            content: '——海子';        }    </style></head><body>    <h1 id="面朝大海-春暖花开">面朝大海,春暖花开</h1></body></html>
Copier après la connexion

得到 webFonts :

{    "demo-font": {        "family": "demo-font",        "src": "url(\"file:///Users/aui/Documents/demo-font.ttf\")",        "chars": ""    }}
Copier après la connexion

查找字符

利用 document.querySelectorAll() 来获取使用 WebFont 的字符:

// 获取当前节点所使用的 webFontfunction matchFontFamily(cssRule) {    var style = cssRule.style;    var family = style['font-family'];    return webFonts[family];}// 将 fontFace 与元素、字符关联起来eachCssRuleList(function(cssRule) {    if (cssRule instanceof CSSStyleRule) {        var selector = cssRule.selectorText;        var webfont = matchFontFamily(cssRule);        if (webfont) {            // 根据选择器来查找元素            var elems = document.querySelectorAll(selector);            Array.prototype.forEach.call(elems, function(element) {                // 获取元素的文本                webfont.chars += element.textContent;                // 将元素与字体关联起来                elements[webfont.family].push(element);            });        }    }});
Copier après la connexion

此时 webFonts :

{    "demo-font": {        "family": "demo-font",        "src": "url(\"file:///Users/aui/Documents/demo-font.ttf\")",        "chars": "面朝大海,春暖花开"    }}
Copier après la connexion

伪元素

// 处理伪元素,找到继承的 webFonteachCssRuleList(function(cssRule) {    if (cssRule instanceof CSSStyleRule) {        var selector = cssRule.selectorText;        var pseudoName = /\:\:?(?:before|after)$/i;        if (!pseudoName.test(selector)) {            return;        }        // 查找伪元素所在的节点        selector = selector.replace(pseudoName, '');        var elems = document.querySelectorAll(selector);        // 获取伪元素 content 值        var content = cssRule.style.content.replace(/^["']|["']$/g, '');        for (var i = 0; i < elems.length; i ++) {            var elem = elems[i];            for (var family in webFonts) {                // 从伪元素自身不断冒泡,直到找到继承的字体                while (elem) {                    if (elements[family].indexOf(elem) !== -1) {                        webFonts[family].chars += content;                        break;                    }                    elem = elem.parentNode;                }            }        }    }});
Copier après la connexion

此时 WebFont:

{    "demo-font": {        "family": "demo-font",        "src": "url(\"file:///Users/aui/Documents/demo-font.ttf\")",        "chars": "面朝大海,春暖花开————海子"    }}
Copier après la connexion

完整代码在线演示: https://jsfiddle.net/9ont96c4/2

至此,以上例子已经成功演示了字蛛爬虫查找字体、查找文本的工作原理。实际上 HTML 与 CSS 远比上面示例页面复杂,需要处理:

  1. 伪类选择器
  2. font 缩写
  3. 行内样式
  4. 完整的字体匹配算法

由于篇幅有限,上述细节部分可以参见 字蛛爬虫模块源码 。

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
2 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Repo: Comment relancer ses coéquipiers
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Difficulté à mettre à jour la mise en cache des pages Web officielles du compte: comment éviter l'ancien cache affectant l'expérience utilisateur après la mise à jour de la version? Difficulté à mettre à jour la mise en cache des pages Web officielles du compte: comment éviter l'ancien cache affectant l'expérience utilisateur après la mise à jour de la version? Mar 04, 2025 pm 12:32 PM

Le cache de mise à jour de la page Web du compte officiel, cette chose est simple et simple, et elle est suffisamment compliquée pour en boire un pot. Vous avez travaillé dur pour mettre à jour l'article officiel du compte, mais l'utilisateur a toujours ouvert l'ancienne version. Dans cet article, jetons un coup d'œil aux rebondissements derrière cela et comment résoudre ce problème gracieusement. Après l'avoir lu, vous pouvez facilement faire face à divers problèmes de mise en cache, permettant à vos utilisateurs de toujours ressentir le contenu le plus frais. Parlons d'abord des bases. Pour le dire franchement, afin d'améliorer la vitesse d'accès, le navigateur ou le serveur stocke des ressources statiques (telles que des images, CSS, JS) ou du contenu de la page. La prochaine fois que vous y accédez, vous pouvez le récupérer directement à partir du cache sans avoir à le télécharger à nouveau, et il est naturellement rapide. Mais cette chose est aussi une épée à double tranchant. La nouvelle version est en ligne,

Comment utiliser les attributs de validation du formulaire HTML5 pour valider l'entrée utilisateur? Comment utiliser les attributs de validation du formulaire HTML5 pour valider l'entrée utilisateur? Mar 17, 2025 pm 12:27 PM

L'article discute de l'utilisation des attributs de validation de formulaire HTML5 comme les limites requises, motifs, min, max et longueurs pour valider la saisie de l'utilisateur directement dans le navigateur.

Quelles sont les meilleures pratiques pour la compatibilité entre les navigateurs dans HTML5? Quelles sont les meilleures pratiques pour la compatibilité entre les navigateurs dans HTML5? Mar 17, 2025 pm 12:20 PM

L'article examine les meilleures pratiques pour assurer la compatibilité des navigateurs de HTML5, en se concentrant sur la détection des fonctionnalités, l'amélioration progressive et les méthodes de test.

Comment ajouter efficacement les effets de course aux images PNG sur les pages Web? Comment ajouter efficacement les effets de course aux images PNG sur les pages Web? Mar 04, 2025 pm 02:39 PM

Cet article démontre un ajout de bordure PNG efficace aux pages Web à l'aide de CSS. Il soutient que CSS offre des performances supérieures par rapport à JavaScript ou à des bibliothèques, détaillant comment ajuster la largeur, le style et la couleur des bordures pour un effet subtil ou proéminent

Quel est le but du & lt; datalist & gt; élément? Quel est le but du & lt; datalist & gt; élément? Mar 21, 2025 pm 12:33 PM

L'article traite du HTML & lt; Datalist & GT; élément, qui améliore les formulaires en fournissant des suggestions de saisie semi-automatique, en améliorant l'expérience utilisateur et en réduisant les erreurs. COMMANDE COMPRES: 159

Quel est le but du & lt; Progress & gt; élément? Quel est le but du & lt; Progress & gt; élément? Mar 21, 2025 pm 12:34 PM

L'article traite du HTML & lt; Progress & GT; élément, son but, son style et ses différences par rapport au & lt; mètre & gt; élément. L'objectif principal est de l'utiliser & lt; Progress & gt; pour l'achèvement des tâches et & lt; mètre & gt; pour stati

Comment utiliser le html5 & lt; time & gt; élément pour représenter les dates et les temps sémantiquement? Comment utiliser le html5 & lt; time & gt; élément pour représenter les dates et les temps sémantiquement? Mar 12, 2025 pm 04:05 PM

Cet article explique le html5 & lt; time & gt; élément de représentation sémantique de date / heure. Il souligne l'importance de l'attribut DateTime pour la lisibilité à la machine (format ISO 8601) à côté du texte lisible par l'homme, stimulant AccessIbilit

Quel est le but du & lt; mètre & gt; élément? Quel est le but du & lt; mètre & gt; élément? Mar 21, 2025 pm 12:35 PM

L'article traite du HTML & lt; mètre & gt; élément, utilisé pour afficher des valeurs scalaires ou fractionnaires dans une plage, et ses applications courantes dans le développement Web. Il différencie & lt; mètre & gt; De & lt; Progress & gt; et ex

See all articles