- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
有时候前端开发需要使用到一些特殊字体,但宿主机上一般都没有安装相应的字体,所以需要将字体文件与前端代码一起打包以及用 CSS 定义使用。本文主要是想回答一个问题:在性能方面,我们可以怎么去优化前端需要加载的字体?
一般优化的思路主要是两方面:
字体文件一般都比较大,动不动就几兆、十几兆的,所以我们优化的第一步是想办法缩减字体文件的大小.
常见的字体格式有TTF(TrueType Font)、OTF(OpenType Font)、EOT(Embedded Open Type)、WOFF(Web Open Font Format)和WOFF2.
更详细的介绍字体的文章可以看: Web 字体简介: TTF, OTF, WOFF, EOT & SVG 。
简单来说,TTF和OTF都是没有压缩,所以这两个格式的字体文件会更大;EOT字体格式只有IE浏览器支持;SVG对文本的支持不够好…等等,因此 使用WOFF可以说是前端开发的最佳选择 了。(还有专家建议只用WOFF2字体,原文如下) 。
In fact, we think it is also time to proclaim: Use only WOFF2 and forget about everything else. This will simplify your CSS and workflow massively and also prevents any accidental double or incorrect font downloads. WOFF2 is now supported everywhere. So, unless you need to support really ancient browsers, just use WOFF2. If you can't, consider not serving any web fonts to those older browsers at all. This will not be a problem if you have a robust fallback strategy in place. Visitors on older browsers will simply see your fallback fonts. Bram Stein, from the 2022 Web Almanac 。
WOFF的优点主要有两个:
WOFF2是WOFF的升级版,压缩率在此基础上提高了30%.
有时候前端页面中需要使用特殊字体的文本是固定的,那么就可以利用 font-spider (同类开源库还有 fontmin 等)去将文本所对应的字体子集提取出来,生成一个新的子集包代替原本的全量字体包,这样即可大大减小字体文件,提高性能.
官方指南 。
font-spider 可以自动分析出页面中使用过的字体并进行按需压缩,也就是说,如果页面中的文本有改动就需要重新压缩。这种压缩方式比较 适合页面的文字一般不会改动的场景 .
下面是我对某个字体文件的提取对比,在这个情境中我的网站只有数字部分用到了这个字体,所以没必要把整个字体文件都打包进去,所以我使用了font-spider把字体文件中的数字部分提取出来了.
字体压缩前后的效果对比:
下图展示了浏览器绘制页面的过程:
从图片我们可以看出,浏览器从请求html文档到呈现文本,中间还有好几个步骤。因此字体的请求会比其他关键资源请求之后延迟很长时间,并且,在获取到字体资源前,浏览器处理文本的方式也各不相同.
在加载网页上的字体时,浏览器一般会有两种选择:
虽然在使用非默认系统字体时,用户一般不会在本地安装相应的文件,但是开发者仍然需要考虑到这种情况。在定义 font-face 时,可以使用 local() 先请求本地字体,示例代码如下:
@font-face {
font-family: 'Awesome Font';
font-style: normal;
font-weight: 400;
src: local('Awesome Font'),
url('/fonts/awesome.woff2') format('woff2'),
url('/fonts/awesome.woff') format('woff'),
url('/fonts/awesome.ttf') format('truetype'),
url('/fonts/awesome.eot') format('embedded-opentype');
}
对于这段代码,浏览器会按照下述顺序去请求资源:
url()
中定义的字体资源。
format
,那么浏览器在下载字体资源前会先检查自己支不支持该格式,如果不支持,则继续请求下一行代码定义的字体资源。 format
,则直接下载该资源。 虽然不同的浏览器会对字体加载有不同的处理方式,但是开发者可以用 font-display 去控制这个行为.
font-display 在 CSS 层面上提供了此类问题的解决方法,它提供了五个属性:
- auto:使用浏览器默认的行为;
- block:浏览器首先使用隐形文字替代页面上的文字,并等待字体加载完成再显示;
- swap:如果设定的字体还未可用,浏览器将首先使用备用字体显示,当设定的字体加载完成后替换备用字体;
- fallback:与
swap
属性值行为上大致相同,但浏览器会给设定的字体设定加载的时间限制,一旦加载所需的时长大于这个限制,设定的字体将不会替换备用字体进行显示。 Webkit 和 Firefox 中设定此时间为 3s;- optional:使用此属性值时,如果设定的字体没有在限制时间内加载完成,当前页面将会一直使用备用字体,并且设定字体继续在后台进行加载,以便下一次浏览时可以直接使用设定的字体。
NimitzDEV,《页面字体闪一下?这两个标准能帮到你》 采用什么样的加载策略取决于字体的重要性、个人审美以及性能考虑等等,因此在此不做推荐,以下是几种主要策略:
性能优先 | 速度优先 | 网络字体优先 | |
---|---|---|---|
推荐值 | optional | swap | block |
优点 | 非常高效,文本呈现时间短。 | 可以保证在使用网络字体的前提下尽早完成字体的渲染。 | 可以最大程度确保优先使用网络字体;尽管也会出现布局偏移,但是显示效果比swap的效果更平滑。 |
缺点 | 如果浏览器在限制时间内没有下载完字体,则不会加载网络字体。 | 如果字体请求过久,会导致页面出现FOUT闪烁。 | 这个策略推迟了文本的显示时间,导致FOIT闪烁。 |
综上所述,开发者可以根据实际情况选择不同的策略,例如 font-display: swap 用于品牌和其他视觉上与众不同的页面元素; font-display: optional 用于正文中使用的字体.
如果开发者希望自定义字体加载的方式,并且愿意承担额外的js开销,那么还有以下选择:
利用 字体加载API 去定义或者操作字体的加载行为(但是在旧浏览器中不可用) 。
例如,如果您确定需要特定的字体变体,您可以定义它并告诉浏览器立即启动字体资源的获取:
var font = new FontFace("Awesome Font", "url(/fonts/awesome.woff2)", { style: 'normal', unicodeRange: 'U+000-5FF', weight: '400' }); // don't wait for the render tree, initiate an immediate fetch! font.load().then(function() { // apply the font (which may re-render text and cause a page reflow) // after the font has finished downloading document.fonts.add(font); document.body.style.fontFamily = "Awesome Font, serif"; // OR... by default the content is hidden, // and it's rendered after the font is available var content = document.getElementById("content"); content.style.visibility = "visible"; // OR... apply your own render strategy here... });
此外,因为您可以检查字体状态(通过 check() )方法并跟踪其下载进度.
Ilya Grigorik, 《优化 WebFont 加载和呈现》 。
使用 Web Font Loader 只要在脚本中添加下列代码,即可使用它所提供的加载功能:
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
<script>
WebFont.load({
google: {
families: ['Droid Sans', 'Droid Serif']
}
});
</script>
它同时支持同步加载和异步加载,自由度较高.
其他方式 由于自定义的可能性实在是太多了,业内也有好几个开源库,因此在这里不穷举所有的实现方式。有兴趣的朋友可以阅读 A COMPREHENSIVE GUIDE TO FONT LOADING STRATEGIES , How We Load Web Fonts Progressively 以及 網頁加載字型Web Font FOIT& FOUT與效能測試 等文章.
上文提到了如何控制浏览器处理暂不可用的字体,除此之外,开发者还可以通过 preconnect 和 preload 加快字体资源加载的速度.
如果开发者选择在第三方站点上托管字体,那么可以用 preconnect 预先与第三方来源建立连接,示例:
<head>
<link rel="preconnect" href="https://fonts.com">
<link rel="preconnect" href="https://fonts.com" crossorigin>
</head>
使用 preload 可以让浏览器优先下载字体资源,从而加快网页显示文本的速度,示例:
<head>
<!-- ... -->
<link rel="preload" href="/assets/Pacifico-Bold.woff2" as="font" type="font/woff2" crossorigin>
</head>
但是如果使用不当,预加载可能会对未使用的资源发出不必要的请求,从而导致性能损耗.
最简单直接的优化方式就是只用系统字体(System Font)或者可变字体(Variable Font)来减少甚至清零所需要请求的网络字体的数量;如果不得不使用网络字体,可以试试上述方式去优化网页性能。这些优化手段可以互相组合去使用,取得1+1>2的效果.
本文只是一个粗略的介绍,对于细节问题没有过多涉及,欢迎在评论区补充更多信息.
前端网页字体优化指南 。
通过预加载 web 字体提高加载速度 。
页面字体闪一下?这两个标准能帮到你 。
快速加载 。
網頁加載字型Web Font FOIT& FOUT與效能測試 。
最后此篇关于如何提高前端性能——字体篇的文章就讲到这里了,如果你想了解更多关于如何提高前端性能——字体篇的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
在这段令人惊叹的视频 ( https://www.youtube.com/watch?v=udix3GZouik ) 中,Alex Blom 谈到了 Ember 在移动世界中的“黑客攻击”。 在 22
我们希望通过我们的应用收集使用情况统计信息。因此,我们希望在服务器端的某个地方跟踪用户操作。 就性能而言,哪个选项更合适: 在 App Engine 请求日志中跟踪用户操作。即为每个用户操作写入一个日
在针对对象集合的 LINQ 查询的幕后究竟发生了什么?它只是语法糖还是发生了其他事情使其更有效的查询? 最佳答案 您是指查询表达式,还是查询在幕后的作用? 查询表达式首先扩展为“普通”C#。例如: v
我正在构建一个简单的照片库应用程序,它在列表框中显示图像。 xaml 是:
对于基于 Web 的企业应用程序,使用“静态 Hashmap 存储对象” 和 apache java 缓存系统有何优缺点?哪一个最有利于性能并减少堆内存问题 例如: Map store=Applica
我想知道在性能方面存储类变量的最佳方式是什么。我的意思是,由于 Children() 函数,存储一个 div id 比查找所有其他类名更好。还是把类名写在变量里比较好? 例如这样: var $inne
我已经阅读了所有这些关于 cassandra 有多快的文章,例如单行读取可能需要大约 5 毫秒。 到目前为止,我不太关心我的网站速度,但是随着网站变得越来越大,一些页面开始需要相当多的查询,例如一个页
最近,我在缓存到内存缓存之前的查询一直需要很长时间才能处理!在这个例子中,它花费了 10 秒。在这种情况下,我要做的就是获得 10 个最近的点击。 我感觉它加载了所有 125,592 行然后只返回 1
我找了几篇文章(包括SA中的一些问题),试图找到基本操作的成本。 但是,我尝试制作自己的小程序,以便自己进行测试。在尝试测试加法和减法时,我遇到了一些问题,我用简单的代码向您展示了这一点
这个问题在这里已经有了答案: Will Java app slow down by presence of -Xdebug or only when stepping through code? (
我记得很久以前读过 with() 对 JavaScript 有一些严重的性能影响,因为它可能对范围堆栈进行非确定性更改。我很难找到最近对此的讨论。这仍然是真的吗? 最佳答案 与其说 with 对性能有
我们有一个数据仓库,其中包含非规范化表,行数从 50 万行到 6 多万行不等。我正在开发一个报告解决方案,因此出于性能原因我们正在使用数据库分页。我们的报告有搜索条件,并且我们已经创建了必要的索引,但
我有一条有效的 SQL 语句,但需要很长时间才能处理 我有一个 a_log 表和一个 people 表。我需要在 people 表中找到给定人员的每个 ID 的最后一个事件和关联的用户。 SELECT
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
通常当我建立一个站点时,我将所有的 CSS 放在一个文件中,并且一次性定义与一组元素相关的所有属性。像这样: #myElement { color: #fff; background-
两者之间是否存在任何性能差异: p { margin:0px; padding:0px; } 并省略最后的分号: p { margin:0px; padding:0px } 提前致谢!
我的应用程序 (PHP) 需要执行大量高精度数学运算(甚至可能出现一共100个数字) 通过这个论坛的最后几篇帖子,我发现我必须使用任何高精度库,如 BC Math 或 GMP,因为 float 类型不
我一直在使用 javamail 从 IMAP 服务器(目前是 GMail)检索邮件。 Javamail 非常快速地从服务器检索特定文件夹中的消息列表(仅 id),但是当我实际获取消息(仅包含甚至不包含
我非常渴望开发我的第一个 Ruby 应用程序,因为我的公司终于在内部批准了它的使用。 在我读到的关于 Ruby v1.8 之前的所有内容中,从来没有任何关于性能的正面评价,但我没有发现关于 1.9 版
我是 Redis 的新手,我有一个包含数百万个成员(member) ID、电子邮件和用户名的数据集,并且正在考虑将它们存储在例如列表结构中。我认为 list 和 sorted set 可能最适合我的情
我是一名优秀的程序员,十分优秀!