前端页面性能优化 - 字体加载优化

2023-11-14

相比于英文的字库来说,中文字库的体积非常之大,小则1M,动辄几十 M 的体积非常常见。所以在前端页面性能优化中,字体加载的优化就显得尤为重要。阅读了相关的知识和文章,在研究了市面上字体加载方案之后,我总结出了目前可行的方案。

1、font-spider

字蛛是一款可以压缩字体文件的小工具,其主要的原理就是,通过html页面获得文字以及对应的字体文件,然后把已经使用文字保留,没有的文字去除,生成一个新的字体文件。
安装
在这里插入图片描述
使用:
在这里插入图片描述
命令执行完会在原字体处生成一个新的字体文件,而旧的文件会保存在font-spider文件夹下,新生成的就是压缩后的字体文件。至此,工具的使用方法介绍完了。
压缩之前
压缩之后

字蛛工具的优点和缺点都十分的明显。
优点:能够把没有使用的字符丢弃,只保留使用到的字符,这对于字体文件的体积优化是非常大的。
缺点:不够灵活,每次有内容更新都需要跑一遍脚本,而且致命的缺点是只能够识别html文件中的文字,后端返回的文字并不能被识别。所以不能适应于一般的框架项目。当然,如果你愿意再入口文件把你所有用的文字都放进去,然后再压缩,我也没有意见。

2、加载完成前使用降级字体

目前浏览器对于自定义字体不存在时的解决方案有两种:

  • 加载完成前隐藏(FOIT, Flash Of Invisible Text)

  • 加载完成前使用降级字体(FOUT, Flash Of Unstyled Text)。
    很显然,如果选择FOIT的显示方式的话,如果我们的自定义字体没有加载出来的话,那么我们的页面就一直显示的是空白的页面,这对于用户体验来说是致命的。所以,FOUT这个方式才是更合适的解决方案。
    提到FOUT,不得不提到一个 @font-face 指令的描述符: font-display

    @font-face {
      font-family: "sans-medium";
      src: url(./font/NotoSansSC-Medium.otf);
      font-display: swap;
    }
    
  • block:表示文档会block一段时间(阻塞期大概3s)来等待远程字体文件的下载,该时间内字体如没有完成下载,使用备选字体,等远程字体下载完毕后再进行替换。

  • swap:表示文档不会block(极短的阻塞期< 1s),直接使用备选字体,远程字体下载完毕后再进行替换。

  • fallback:表示文档不会block(极短的阻塞期<1s),直接使用备选字体,并且在交换期(大概是2s)内下载完毕则进行字体替换,否则放弃使用远程字体。

  • optional:表示文档不会block(极短的阻塞期< 1s),这么短时间内字体完成加载则使用字体否则放弃使用。

  • auto:自动模式,由浏览器决定(chrome下行为跟swap类似)

那么在了解 font-display 之后,那么我们应该不难看出来,对于大部分情况应该把它的值设置为 swap ,这样在加载网络字体期间,使用后备字体进行渲染,加载完成之后在替换为指定的网络字体。

优点:在自定义字体没有加载出来之前,能够正常的显示页面,只不过字体是降级字体。不会因为加载字体文件而导致页面阻塞。
缺点:在自定义文字和默认文字存在较大视觉差异时,会影响用户视觉体验!

3、网络字体

很多公司都会把自己的静态资源放在CDN上,从而增加资源获取速度。字体也不意外,完全可以放在CDN上,增加加载的速度。同时也可以使用第三方字库,如 google fontweb font等第三方字库,他们会对字体文件进行自己的优化和处理,能够很大程度的提高加载速度。
优点:加载速度快。
缺点:增加不必要的外链,影响安全性,受制于第三方库

4、字库切分

这个方案,完美的解决了以上3中方案中存在的不足,可以说是目前为止,最为完美的解决方案。
字库切分,顾名思义是把一个字库切分成多个小的字体,减少单个字体文件的大小,从而减少字体阻塞的情况发生。可以在 mdn 关于 unicode-range - CSS: Cascading Style Sheets | MDN (mozilla.org) 的介绍中看到:
在这里插入图片描述
浏览器只会在页面使用了该范围中的字符时才会加载对应的字体“分片”。也就是说页面初始化时给浏览器一个目录,在页面要渲染字体时再去根据目录加载所需的字体文件。这不就是字体文件的按需加载
谷歌字体也采用了这一方案,通过机器学习,把一些可能出现在同一个页面的上字符组成一个字体片段,一个中文字体库分割成数百个字体片段,然后通过css的方式进行引入。参考sans字体css
我们就以谷歌的这个字体为例,只需要把这个css引入到我们的项目之中,然后我们在页面上使用这个字体。
当然,你可以把谷歌的css以及对应的字体切片的文件下载下来,放在项目本地。可以用到一个小工具
google-font-splitter - 一个用于下载谷歌分割字体的命令行工具把我们需要的资源下载下来。
部分css代码:

@font-face {
  font-family: "sans-regular";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(s/notosanssc/v26/k3kXo84MPvpLmixcA63oeALhLOCT-xWNm8Hqd37g1OkDRZe7lR4sg1IzSy-MNbE9VH8V.4.woff2)format("woff2");
  unicode-range: U+1f1e9-1f1f5, U+1f1f7-1f1ff, U+1f21a, U+1f232, U+1f234-1f237, U+1f250-1f251, U+1f300, U+1f302-1f308, U+1f30a-1f311, U+1f315, U+1f319-1f320, U+1f324, U+1f327, U+1f32a, U+1f32c-1f32d, U+1f330-1f357, U+1f359-1f37e
}

@font-face {
  font-family: "sans-regular";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(s/notosanssc/v26/k3kXo84MPvpLmixcA63oeALhLOCT-xWNm8Hqd37g1OkDRZe7lR4sg1IzSy-MNbE9VH8V.5.woff2)format("woff2");
  unicode-range: U+fee3, U+fef3, U+ff03-ff04, U+ff07, U+ff0a, U+ff17-ff19, U+ff1c-ff1d, U+ff20-ff3a, U+ff3c, U+ff3e-ff5b, U+ff5d, U+ff61-ff65, U+ff67-ff6a, U+ff6c, U+ff6f-ff78, U+ff7a-ff7d, U+ff80-ff84, U+ff86, U+ff89-ff8e, U+ff92, U+ff97-ff9b, U+ff9d-ff9f, U+ffe0-ffe4, U+ffe6, U+ffe9, U+ffeb, U+ffed, U+fffc, U+1f004, U+1f170-1f171, U+1f192-1f195, U+1f198-1f19a, U+1f1e6-1f1e8
}
<div class="medium">
    <span class="bold">HTML、CSS、JavaScript</span>这三个是前端开发中最基本也是最必须的三个技能。前端的开发中,在页面的布局时,
    HTML指的是超文本标记语言 (<span class="regular"> Hyper Text Markup Language</span>),这个也是我们网页最常用普通的语言了,
    CSS级联样式表(<span class="regular">Cascading Style Sheet</span>)简称“CSS”,通常又称为“风格样式表(<span class="regular">Style Sheet</span>)",它是用来进行网页风格设计的。比如,如果想让链接字未点击时是蓝色的,当鼠标移上去后字变成红色的且有下划线,这就是一种风格。通过设立样式表,可以统一地控制HTML中各标志的显示属性。级联样式表可以使人更能有效地控制网页外观。使用级联样式表,可以扩充精确指定网页元素位置,外观以及创建特殊效果的能力。
    JavaScript是一种由Netscape的LiveScript发展而来的原型化继承的面向对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如Perl,遗留的速度问题,为客户提供更流畅的浏览效果。当时服务端需要对数据进行验证,由于网络速度相当缓慢,只有28.8kbps,验证步骤浪费的时间太多。于是Netscape的浏览器Navigator加入了Javascript,提供了数据验证的基本功能。
  </div>

在我们正常加载这三种字体时的效果:
完全加载:
通过字体切分之后的效果
在这里插入图片描述
由此看见,提升的效果还是非常明显的。
优点:

  1. 比起加载完整字体文件来讲,每个字体片段更小,
  2. 可以在添加font-display来进行字体降级,从而让用户体验更加友好。
  3. 按需加载,不需要把所有的字体片段都加载进来。

缺点:对于字体库切片,可能谷歌上的可选字体比较少,如果碰巧你的自定义字体,在谷歌字体上没有找到,那就pass了。或者你有能力进行字体分割,那更好!

5、和产品辨雄雌

优点:全是优点。
缺点:容易被打。

以上就是我整理的字体优化相关的5种方案,总的来说,我个人觉得第五种是最完美的,其次就是第四种。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

前端页面性能优化 - 字体加载优化 的相关文章

  • 创建一个简单的 10 秒倒计时

    我想要一行这样写的 Your download will begin in 10 9 8 etc Beginning on page load seconds 我已经设置了 10 秒下载文本 并且我还查看了其他 stackoverflow
  • 如何在 font Awesome 图标链接下方添加添加文本?

    我正在尝试在我的 Blogger 模板中的 font awesome Icons 下添加一些文本 这是我想要实现的目标的图像 我想要实现的外观图片 https i stack imgur com BVYlh png 但到目前为止我已经做到了
  • Chromium 嵌入式框架支持 HTML5 音频吗?

    我一直在玩 CefSharp 但似乎无法播放任何音频 我可以让音频控件出现 但它们保持冻结状态 这些是我使用的版本 Chromium 21 0 1180 0 CEF r728 CefSharp 0 12 4596 50 我先尝试了 mp3
  • 如何适应特定子元素的宽度?

    problem 我正在尝试创建一个技能表 我无法问下一个问题为什么 所以我创建了一个新帐户并询问 当前状态 我想将元素的宽度与 meter 也就是说 如何设定区块的标准 meter 子元素 在上面的 gif 中 img meter 我想要保
  • IE 中的 HR 标签 - 删除边框

    在除 IE7 及更低版本之外的其他浏览器中 hr 在 hr 标签周围显示边框 但我不希望它出现 我已经尝试过这个解决方案 但它周围似乎仍然有边框 它看起来像这样 我该如何摆脱它 See http webdesign about com od
  • Jquery 在 DIV 中进行多重加载

    这是我的代码 right load textes html nicolas right load textes html antoine 问题是内容divantoine覆盖了右边div nicolas加载的内容div div right l
  • 获取点击的的DOM路径

    HTML div class lol a class rightArrow href a div 伪代码 rightArrow click function rightArrowParents this dom dom is the pse
  • 如何在php中使用preg添加html属性

    我正在寻找在 php 中编写一个脚本来扫描 html 文档并根据它找到的内容向元素添加新标记 更具体地说 我是扫描文档并为每个元素搜索CSS标记 float right left 如果找到它 它会添加align right left 基于它
  • 从 html 属性中删除单引号和双引号,并且除 href 和 src 之外的所有属性上都没有空格

    我正在尝试从 html 属性中删除单引号和双引号 这些属性是没有空格的单个单词 我写了这个有效的正则表达式 type title data toggle colspan scope role media name rel id class
  • 使用绝对定位时文本被破坏

    我有一个小挑战 我在 Stack Overflow 上没有找到任何解决方案 这就是我得到的 这就是我想要的 为了产生这个标题效果 我使用绝对位置 我什至不知道我的标题的宽度和高度 因此 使用此解决方案时 大文本会中断 My HTML div
  • 在iOS上,“添加到主页”缓存保存在哪里,如何清除它?

    我正在 iPad iOS v7 上制作一个 html5 游戏 当我将其添加到主页时 它非常顽固地释放缓存 如果我在 Safari 中查看它 这会按照您所期望的方式工作 如果我刷新一次或两次 页面就会以最新状态缓存 但在主页上却是另一回事 它
  • 在随机位置启动 HTML5

    我有一个大约 2 小时长的音轨 我想在我的网站上使用它 我希望它在页面加载时在随机位置开始播放曲目 使用 HTML5 可以吗 我知道您可以使用 element currentTime 函数来获取当前位置 但是如何在完全下载之前获取曲目的总时
  • 水平滚动的表格上的“粘性”标题......完全不可能?

    经过过去几个小时的研究后 我开始认为这是不可能的 即使在最新的浏览器上也是如此 HTML table具有水平滚动的元素 带有 粘性 thead在顶部 作为垂直滚动的周围网页的一部分 这是我的尝试 a height 100px backgro
  • 更改API数据输出的布局

    我是 API 集成和 PHP 的新手 我最近将 VIN 解码器集成到我的应用程序中 在输入框中输入车辆的 VIN 选择提交 然后就会显示 API 数据库中有关该车辆的所有信息 数据存储为关联数组 其中包含类别及其相应元素 例如 对于 VIN
  • 检索 css3 缩放元素的宽度/高度

    我正在与 offsetWidth 属性的奇怪之处 我认为 作斗争 这是场景 比方说 我有一个span标签 在我的js中 在某个时刻我执行css3转换 对于这个元素 例如 el set styles transform scale scale
  • 如何使跨度标签不可删除?

    我正在尝试使 contenteditable div 内的跨度标记不可删除 div Editable span Read Only span div 只读范围确实是只读的 但我可以通过单击删除键来删除整个范围 有没有一种属性方法可以告诉sp
  • 电话输入自动填充会删除国际前缀

    我有一个类型为 tel 的输入字段 并启用了自动完成功能
  • 将特定字形与网络字体一起使用

    使用网络字体 我想使用字体功能设置 CSS 中的选项以及跨度类HTML 中 以便使用字体集中的特定替代字形 我需要以正确的语法使用哪些值 GID Unicode 才能定位特定的目标glyph内glyph备择方案 这些功能使用 OpenTyp
  • 如何在画布上所有其他内容后面绘制图像? [复制]

    这个问题在这里已经有答案了 我有一块画布 我想用drawImage在画布上当前内容后面绘制图像 由于画布上已经有内容 我正在使用字面上的画布来创建包含图像的画布 因此我无法真正先绘制图像 所以我无法使用drawImage在我呈现其余内容之前
  • ng-include 和 ng-view 不同时加载

    下面是我的应用程序的结构 很简单 页眉和页脚是非常小的文件 而主页上的 ng view 要大得多 当我进入该页面时 我注意到了这一点 首先加载两个 ng include 然后 ng view 出现 页脚被推到底部 页脚闪烁大约 0 1 秒

随机推荐

  • jQuery获取格式化当前时间

    一 重构Date对象 对Date的扩展 将 Date 转化为指定格式的String 月 M 日 d 小时 h 分 m 秒 s 季度 q 可以用 1 2 个占位符 年 y 可以用 1 4 个占位符 毫秒 S 只能用 1 个占位符 是 1 3
  • 边缘计算服务器项目,什么是边缘计算?三分钟看懂

    什么是边缘计算呢 其实关于边缘计算的定义 目前国内还没有一个严格统一的定义 今天小编就给大家整理三个关于边缘计算的说法 帮助大家快速理解什么是边缘计算 1 维基百科说 维基百科上说 边缘计算是一种分散式运算的架构 将应用程序 数据资料与服务
  • 2019牛客国庆集训派对day1

    2019牛客国庆集训派对day1 2019 10 1 国庆练习赛 比赛链接 2019牛客国庆集训派对day1 虽然我国庆七天溜回家了 队友还是督促我好好打比赛 毕竟现场赛也没几天了 好好练习哈 A 全 1 子矩阵 题目大意 判断矩阵是否存在
  • 设计模式:中介模式

    中介模式听名字作为中介 在复杂的调用关系中做个中介传递 类似于在状态机中弄一个中心点 所有的关系状态转移交给中介来处理 同样也是一个重在实用意义 实现结构倒是不要求什么 实际上结构跟观察者比较像 Mediator Design Patter
  • 魔兽世界服务器列表显示不兼容,魔兽世界显示游戏设备驱动不兼容怎么解决_魔兽世界显示游戏设备驱动不兼容解决办法_牛游戏网...

    魔兽世界 显示游戏设备驱动不兼容怎么解决 在客户端更新晋级后登入游戏设备 其显现驱动不兼容 这是因为显卡驱动过期致使 若不挑选更新 亦可经过点击断定按钮越过该提示持续游戏 但每次登录都会呈现 这儿给咱们共享下 魔兽国际 登入显现游戏设备驱动
  • Altium Designer使用-----如果Bill of Materials卡住

    Altium Designer使用 如果Bill of Materials卡住 是没有安装office软件
  • 01背包问题

    01 背包问题 输入 n个商品组成集合O 每个商品有两个属性vi和pi 分别表示体积和价格 背包容量为C 输出 求解一个商品子集包含于O 令价格和最大 容量不超过C 直观上 价格高优先 体积小优先 性价比高优先 都不能得到最优解 解决方案一
  • JDK以及IDEA的安装和配置【JAVA学习--安装配置学习工具】

    目录 一 JDK的安装和环境配置 1 准备工作 2 配置JDK环境变量 3 验证环境配置是否成功 二 安装配置IDEA 创建项目 一 JDK的安装和环境配置 1 准备工作 在Oracal官方网站下载适合自己电脑版本的JDK 并进行安装 注意
  • Linux 查看操作系统

    转载 linux查看操作系统版本信息 这个常用 放在这里备忘 转载上面的链接 一 linux下如何查看已安装的centos版本信息 1 Linux查看当前操作系统版本信息 cat proc version Linux version 2 6
  • Oracle入门笔记(一)——环境配置及简单介绍

    Oracle环境配置及目录结构说明 1 引言 2 Oracle简介 3 Oracle版本迭代说明 4 Oracle的安装与配置 5 Oracle数据库目录介绍 6 Oracle用户说明 7 Oracle启动与关闭 8 参考文献 1 引言 害
  • 负载测试和压力测试的区别

    这两个测试都属于性能测试的一部分 我之前都一直有盲区 每次想起对于这两个概念都不是很清晰 在网上看了一篇文章后 终于有些理解了 特记录下来方便大家理解 这个是网上看到的一篇文章 如果大家还是有些不懂可以在参考一下这篇文章 我所理解的性能测试
  • tp6重定向

    引入 use think exception HttpResponseException 方法 public function redirect args throw new HttpResponseException redirect a
  • 计算机毕业设计-社区疫情防控管理系统springboot-小区疫情管理系统java代码

    计算机毕业设计 社区疫情防控管理系统springboot 小区疫情管理系统java代码 注意 该项目只展示部分功能 如需了解 评论区咨询即可 1 开发环境 开发语言 Java 架构 B S 框架 SpringBoot 前端 HTML CSS
  • Docker-容器

    容器 容器的状态用 docker contaier ls 启动容器 启动一个容器的终端 并允许交互 docker run it ubuntu 16 04 bin bash 当利用 docker run 来创建容器时 Docker 在后台运行
  • uvm message printing mechnism

    原文链接 http www sunburst design com papers CummingsSNUG2014AUS UVM Messages pdf 本文主要介绍了如何控制消息打印的等级 以及禁止消息打印等
  • 使用nginx+uwsgi+flask实现python服务的负载均衡---(2)uwsgi的安装

    0 安装uwsgi 转自官网 使用pip install uwsgi就可以 当然了也可以下载源码自己make 1 配置uwsgi uwsgi 有多种配置可用 1 ini 2 xml 3 json 4 yaml 这里我使用的ini 当然也可以
  • selenium-server-standalone selenium-server 和 selenium-java 的区别

    selenium1 0还是 seleniumRC的时候 需要启动selenium server standalone包 用来做server selenium RC通过server来给code和broswer建立通道 同时 该jar包包括我们
  • BATJ面试必会之Java IO 篇

    一 概览 二 磁盘操作 三 字节操作 实现文件复制 装饰者模式 四 字符操作 编码与解码 String 的编码方式 Reader 与 Writer 实现逐行输出文本文件的内容 五 对象操作 序列化 Serializable transien
  • DDL和DML常用语句总结

    DDL语句 常用来操作数据库 数据库表 用到的语句 create show alter drop 1 操作数据库 CRUD 1 C Create 创建 创建数据库 create database 数据库名称 创建数据库 判断不存在 再创建
  • 前端页面性能优化 - 字体加载优化

    相比于英文的字库来说 中文字库的体积非常之大 小则1M 动辄几十 M 的体积非常常见 所以在前端页面性能优化中 字体加载的优化就显得尤为重要 阅读了相关的知识和文章 在研究了市面上字体加载方案之后 我总结出了目前可行的方案 1 font s