web安全字体

 

webfont解剖

  • Unicode字体可以包含数以千计字形
  • 有四个字体格式: WOFF2, WOFF, EOT, TTF
  • 一些字体格式需要使用GZIP压缩 

一个web字体是字形的集合,且每个字形是一个描述了一个字母亦或符号的矢量图。

所以,一个字体文件的大小由两个因素决定:每个字形矢量路径的复杂程度和每个字体所包含的字形数量。

例如,Open Sans, 最流行的web字体之一, 包含了897个字形,包含了拉丁,希腊和古代斯拉夫语字母。

Font glyph table

当选择一个字体的时候,重要的是考虑哪些字符集被支持。

例如, Google’s Noto font family 目标是支持世界上所有的语言. 但是,注意Noto的大小,因为包括了所有的语言,所以压缩后大小是130MB+。

Web字体格式

网上如今四个web字体格式: EOT, TTF, WOFF, 和 WOFF2.

不幸的是,虽然有很多的选择,但是没有一个字体是可以在旧的浏览器和新的浏览器上通用的:EOT只适用于IE,TTP部分被IE支持。WOFF享有最广泛的支持但是在老的浏览器中不必支持,并且对于很多新的浏览器真在添加对于WOFF 2.0的支持。

所以,这意味着我们需要使用多个字体格式来保持良好的用户体验:

  • 在支持WOFF 2.0的浏览器中使用WOFF 2.0 变体
  • 在大多数浏览器中使用WOFF字体
  • 在老的安卓(低于4.4)浏览器中使用TTF变体
  • 在老的IE(低于IE9)中使用EOT变体 

使用压缩来减少字体大小

A font is a collection of glyphs, each of which is a set of paths describing the letter form. The individual glyphs are, of course, different, but they nonetheless contain a lot of similar information that can be compressed with GZIP, or a compatible compressor:

  • EOT, 和 TTF 格式默认没有压缩:确保你的服务器使用了GZIP压缩 
  • WOFF 有内置的压缩 - 确保你的WOFF压缩器使用了最优化的设置。
  • WOFF2 使用了用户预定义和压缩算法来减少相对于其他字体格式约30%的文件大小

值得注意的是一些字体格式包括了额外的信息——比如font hitting和kerning信息,这些可能是不必要的,所以可以进行深入优化。

查看你的字体编译器可操作的选项,如果你可以优化上面的内容,进行优化,并在不同的浏览器中查看效果。

Note

  • 可以使用 Zopfli compression 来压缩EOT, TTF,和 WOFF 字体格式. Zopfli 是一个 zlib兼容的压缩器,压缩的内容比gzip压缩后还要小约5%。

使用 @font-face定义字体

  • 使用format()定义不同的字体格式
  • 使用大量的子集提高性能: 提供大量可选的子集可以让旧的浏览器兼容 
  • 减少样式化的字体变体来提高页面和文字渲染效果 

 css语句@font-face定义特殊的字体资源的位置,字体样式等。

字体样式选择

每个 @font-face 声明提供了font family的名字,字体属性的什么和特殊字体来源地址的声明。

@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('ttf'),url('/fonts/awesome.eot') format('eot');
}@font-face {font-family: 'Awesome Font';font-style: italic;font-weight: 400;src: local('Awesome Font Italic'),url('/fonts/awesome-i.woff2') format('woff2'), url('/fonts/awesome-i.woff') format('woff'),url('/fonts/awesome-i.ttf') format('ttf'),url('/fonts/awesome-i.eot') format('eot');
}

 

上面一个 Awesome Font 字体的两个表现形式类型:正常和斜体,每个都提供了一系列的不同字体资源设置。

每个src描述符包括了一个按照优先顺序排序的,用逗号进行分隔的资源列表:

  • local() 表明我们可以使用哪些本地的字体 
  • url() 指定我们加载哪些外部字体,允许我们使用format()来指代字体的格式 

Note

  • 除非你指向系统的默认资源,除非很少有本地的字体资源,特别是对手机设备而言,不可能在内部安装了额外的字体。所以,你总是需要提供一个额外的字体位置清单。

浏览器按照顺序执行,上例浏览器执行如下:

  1. 浏览器显示页面布局并决定哪个字体变形被需要来渲染指定的字体;
  2. 依次检查local()中的字体是否存在并可使用;  如果本地不存在,依次检查外部字体定义:
  • 如果字体格式存在,在初始化和下载字体之间检查浏览器是否支持,如果不支持,进入下一个外部字体选项检查 
  • 如果字体格式不存在,浏览器下载资源 

Note

  • 外部字体加载的顺序十分重要,因为浏览器是按照这个顺序依次执行的。

Unicode-range 子集

我们可以将一个大的字体设置成小的子集(例如拉丁,希腊和斯拉夫字母等),并且只是加载这个子集来渲染页面上的字体

 

这个 unicode-range descriptor 允许我们指定一个逗号隔开的数据集合, 数据可以是下面三种形式中的任何一种:

  • Single codepoint (e.g. U+416)
  • Interval range (e.g. U+400-4ff): indicates the start and end codepoints of a range
  • Wildcard range (e.g. U+4??): ‘?’ characters indicate any hexadecimal digit

例如我们可以将Awesome Font设置成拉丁和日本语的子集格式,它们只有在浏览器需要的时候才会加载 

@font-face {font-family: 'Awesome Font';font-style: normal;font-weight: 400;src: local('Awesome Font'),url('/fonts/awesome-l.woff2') format('woff2'), url('/fonts/awesome-l.woff') format('woff'),url('/fonts/awesome-l.ttf') format('ttf'),url('/fonts/awesome-l.eot') format('eot');unicode-range: U+000-5FF; /* Latin glyphs */
}@font-face {font-family: 'Awesome Font';font-style: normal;font-weight: 400;src: local('Awesome Font'),url('/fonts/awesome-jp.woff2') format('woff2'), url('/fonts/awesome-jp.woff') format('woff'),url('/fonts/awesome-jp.ttf') format('ttf'),url('/fonts/awesome-jp.eot') format('eot');unicode-range: U+3000-9FFF, U+ff??; /* Japanese glyphs */
}

Note

  • Unicode-range子集设置对于亚洲语言非常重要,因为亚洲语言的字形比西方语言要多得多,一个字形百万字节,而不是亚洲字符的千字节。

使用unicide range子集并将文件分成字体不同样式的变体让我们可以更加迅速和高效的下载——用户只需要下载子集和变体就可以,用户不需要下载永远不会用到的字体。

但是,不是所有的浏览器支持unicode-range字段。一些浏览器忽略了unicode-range字段,并且将下载所有的字体;另一些浏览器压根儿不会执行@font-face声明。所以,我们对于旧的浏览器需要“手动设置子集”。

因为旧的浏览器不够聪明来选择需要的字体子集并且不能合成一个合适的字体,所以我们必须回退来提供一个单一的字体资源,这个字体资源包括了所有必要的子集,并且对浏览器而言隐藏了其他的子集。

例如,如果网页只是使用拉丁文子集。我们可以剥夺其他的字形,并且将一个指定的子集设置成单独的资源。

  1. 我们怎样判断哪些字体子集是我们需要的?
    • 如果unicode-range子集是被浏览器支持的,那么浏览器就会在自动的选择合适的子集,页面只需要提供子集文件和在@font-face指定合适的unicode-ranges
    • 如果unicode-range不是浏览器支持那么页面需要隐藏所有不必要的子集——例如,开发者必须指定需要的子集。
  2. 我们在什么样的情况下创造子集?
    • 使用开源工具 pyftsubset tool 来设置和最优化你的子集.
    • 一些字体提供商允许你在用户自定义参数中手动设置字体子集,你可以通过这个方法来手动的为你的页面创建需要的字体——访问字体提供商的页面!

字体选择和合成

每个字体家族都是包含很多样式的字体变体(例如常规,加粗,斜体等等),并且每一种字体变体都有字体权重设置,所以,这将导致了很多不同的字形——例如,不同空格,字体大小都将导致同一个字形变得不同。

Font weights

例如,上面的图形展示了一个字体在三种不同的权重下的表现:400(普通),700(加粗),900(额外加粗)。

所有的在三个标准之间的权重(灰色显示的)将通过浏览器自动的适应最贴近的三种标准变体。


上述逻辑同样适用于斜体字体,但是要记住,字体变形数量使用越少越好!

@font-face {font-family: 'Awesome Font';font-style: normal;font-weight: 400;src: local('Awesome Font'),url('/fonts/awesome-l.woff2') format('woff2'), url('/fonts/awesome-l.woff') format('woff'),url('/fonts/awesome-l.ttf') format('ttf'),url('/fonts/awesome-l.eot') format('eot');unicode-range: U+000-5FF; /* Latin glyphs */
}@font-face {font-family: 'Awesome Font';font-style: normal;font-weight: 700;src: local('Awesome Font'),url('/fonts/awesome-l-700.woff2') format('woff2'), url('/fonts/awesome-l-700.woff') format('woff'),url('/fonts/awesome-l-700.ttf') format('ttf'),url('/fonts/awesome-l-700.eot') format('eot');unicode-range: U+000-5FF; /* Latin glyphs */
}

 

上面的例子声明了一个 Awesome Font 家族字体,包含了拉丁字形,但是拥有两种不一样的权重:normal(400)和blod(700)。字体不同的形式实现的原理是什么呢?

  • 如果给出的字体权重不是标准的(400,700和900),那么将随浏览器匹配最接近标准的字体形式。
  • 如果字体斜体匹配没有发现(例如,我们没有在上例中声明任何的斜体变形),那么浏览器近合成它的自有的字体变形。

Font synthesis

必须要知道的是,有些字体通过合成的方法合成的字体会十分难看(比如Cyrillic合成斜体),所以最好使用已经存在的斜体,而不是浏览器自动合成。

上面的例子解释了实际斜体和浏览器合成的斜体之间的不同(字体是Open-Sans字体)。

你可以在结果中看见显著的不同,不同的浏览器合成字体不同并且不同的字体之间合成的字体也不同。

Note

  • 为了最好的用户体验,我们应该尽量不要使用字形变体,我们最好指定字体的位置让页面来下载它们。总而言之,使用浏览器合成的变体必须非常小心。

优化下载和渲染

  • 字体加载请求会在渲染树(the render tree)被创建之后,这可能导致字体渲染被延迟。
  • 字体加载API同样也允许我们实现用户自定义的字体加载和渲染政策来重写和替代默认的字体延迟加载
  • Font inlining 允许我们在旧的浏览器中重新书写字体加载形式

一个完整的web字体包含了所有形式的变体,和所有的字形,但是有些字形和字体的变体我们可能不需要,导致下载完整的web字体需要多个百万字节。

所以使用@font-face是我们可以加载指定范围的web字体,使用unicode 子集,独特的字体变形等等。

给出这些申明后浏览器可以加载指定的字体来进行渲染,虽然很方便,但是如果我们不小心的话,会导致在渲染时产生障碍——这些是我们需要避免的!

web字体渲染方式

我们知道字体的渲染必须在浏览器创建了渲染树(就是DOM树和CSSOM树)之后,所以,也就是说字体渲染必须等到所有的资源都被抓取之后

Font critical rendering path

  1. 浏览器情趣HTML2文档
  2. 浏览器开始解析HTML响应和构造DOM
  3. 浏览器你发现CSS,JS和其他的资源并且分配请求  当所有的css内容都被接受并且将其和DOM树结合在一起之后构建CSSOM。
  • 当树DOM树被渲染的时候字体被请求,说明了字体变体被渲染到指定的文本上。
浏览器将布局展现在屏幕上面
  • 如果浏览器不可以获得字体吗,那么将不会渲染任何的文本像素
  • 一旦浏览器可以获得字体,浏览器将会渲染文本像素

不同的浏览器在渲染的时候执行的操作不一样:

  • Safari 在文本下载全部完成之后才进行文本渲染
  • Chrome 和 Firefox 在你使用一个回退字体时,进行三秒钟的字体渲染, 并且一旦字体下载完成,浏览器用刚下载的字体再次进行渲染
  • IE马上渲染回退字体如果请求的字体不可获得,并且一旦字体加载全部完成之后在进行再次渲染 。

不同的人有不同的喜好——有些人喜欢马上进行渲染有些人喜欢在回退字体加载后进行再次渲染——我们不做任何的评论,但是我们关注的是在布局加载时进行的字体渲染怎样才能进行优化?

使用字体下载API来优化字体渲染

Font Loading API 提供了一个编程脚本来定义和操作CSS字体,追踪字体的下载进程和重写字体的懒加载行为(懒加载是指在DOM树和CSSOM树加载完成之后才进行字体加载渲染的行为)。

例如,如果我们确保一个特殊的字体变形会被请求,我们可以定义它并且告诉浏览器来初始化即时加载字体资源行为:

var font = new FontFace("Awesome Font", "url(/fonts/awesome.woff2)", {style: 'normal', unicodeRange: 'U+000-5FF', weight: '400'
});font.load(); // don't wait for render tree, initiate immediate fetch!font.ready().then(function() {// apply the font (which may rerender text and cause a page reflow)// once the font has finished downloadingdocument.fonts.add(font);document.body.style.fontFamily = "Awesome Font, serif";// OR... by default content is hidden, and rendered once font is availablevar content = document.getElementById("content");content.style.visibility = "visible";// OR... apply own render strategy here... 
});

 

而且,因为我们可以检查字体的状态(font status)通过check()方法,并且追踪下载的速度,我们同样可以定义一个自定义的策略来在我们的页面上渲染文本,

  • 我们可以知道字体可以使用时才渲染所有文本 
  • 我们可以对于每一个字体设置定时器timeout 

我们可以在不同的页面上使用不同的策略。

Note

  • 字体加载API在某些浏览器中还尚在开发中,可考虑使用FontLoader polyfill, 或者 webfontloader library, 来产生相同的效果

使用inlining来优化渲染字体

  • 在构建CSSOM对象的时候,css样式中匹配设备的查询将作为首选自动加载 
  • 将字体数据嵌入css样式表中将强制浏览器来加载字体,并且以高优先级进行不用等到渲染树的完成

但是 inlining策略不够灵活并且不允许针对不同个页面我们来定义用户自定义的定时器和渲染策略。为了最好的效果,将你的嵌入字体数据的css独立成css文件,并且加载的时候设置max-age属性,这样当你更新css文件的时候不用强迫你的用于再次下载你的字体。

Note

  • 使用inlining策略! 记得上面说的懒加载么?浏览器通常都是在加载DOM和形成CSSOM对象之后,形成渲染树之后在渲染数据内容到屏幕上的!将字体数据放在CSS中,也就是放在CSSOM对象形成之时!

使用HTTP缓存优化你的字体再使用

字体资源是静止的资源,所以可以再次使用,使用http缓存,为字体设置较长时间的max-age。没有必要将字体存储在localStorage中,这会影响性能。

优化总结列表

使用web字体除了会进行下载和下载不必要的资源之外,不会影响页面的渲染和性能!所以放心大胆使用,下面是一些优化建议:

  1. 审查和监听你的字体: 每个网页中不要使用太多的字体,每个字体都要简化它们的变体数量。
  2. 使用字体资源中的子集: 没有必要下载整个字体资源,使用特定的字体子集。特别是对于亚裔字体而言,一定要加载子集。
  3. 对每个浏览器而言使用最优化的字体格式: 每个字体都应该提供 WOFF2, WOFF, EOT, 和 TTF的字体格式. 确保对 EOT 和 TTF进行GZIP压缩,因为默认它们是没有进行压缩的
  4. 使用缓存策略: 字体资源是静态的,所以记得使用max-age来设置http缓存
  5. 使用字体加载API来制定字体渲染方式: 默认的加载方式是字体最后渲染,字体加载API允许我们重写对于特定字体的渲染行为,对于不同的网页我们可以自定义渲染方式亦或设置一个定时器策略。对于旧的不支持字体加载API的浏览器,我们可以使用webfontloader的js库亦或使用css嵌入策略。
原文:https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/webfont-optimization?hl=en

转载于:https://www.cnblogs.com/RachelChen/p/5452870.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/403880.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设置Clover默认进入Windows,按快捷键F8可选择不同的引导

系统情况: Win7 Mac10.9.5 Clover 我要达到的目标是:默认进入Windows系统,如果有需要,可以选择进入其他系统,如Mac OS X 我原以为可以在clover中配置,达到这个目标,可是我经过多次实践&am…

js获取cookie获取不到问题 vue获取cookie以及获取不到问题

1.下载依赖包 npm i js-cookie -S2.在使用cookie的页面上进行引入 import Cookies from js-cookie3.使用 创建一个在整个网站上有效的CookieCookies.set(name, value);创建一个从现在起7天后过期的cookie,在整个站点上有效:Cookies.set(name, value, …

smarty二维foreach示例[顺代一维数组],再次加强版

2019独角兽企业重金招聘Python工程师标准>>> smarty二维foreach示例[顺代一维数组],再次加强版 WEB2.0 root 2009-4-9 10:46 评论(0) 阅读(682) 大 | 中 | 小 WEB2.0 | 评论(0) | 引用(0) | 阅读(682) view plain print ? {foreach itemrec from$result…

url的特殊字符编码 encodeURI编码

参考: 编码解码 前沿: 例如上传资源视频图片,针对一些特殊的字符!#¥%……&*()?《{[,./’~ 不做转码的时候url识别会错,图片就不会显示出来,这时候就需要对…

Linux设备驱动之Kobject、Kset

LDD3中说,Kobject的作用为:1、sysfs 表述:在 sysfs 中出现的每个对象都对应一个 kobject, 它和内核交互来创建它的可见表述。2、热插拔事件处理 :kobject 子系统将产生的热插拔事件通知用户空间。 3、数据结构关联:…

图片不显示问题 图片url监测改变问题

问题:点击按钮换一换的时候,后台返回的三张小图片的地址还是原来的地址,但是三张小图确实是变了;这时候如果一开始头图是图3,点击换一换后,三张小图变了,此时还是想选择图3为头图;却…

限定虚拟机可用的CPU利用率

Windows Server 2012姗姗来迟,最新的Hyper-V 3给我们带来更多的惊喜,后续三篇博文和大家共同学习虚拟机CPU竞争机制。 第一部分:分配给虚拟机的CPU资源 第二部分:限定虚拟机可用的CPU利用率 第三部分:争夺CPU资源优先级…

Windows 7 文件夹共享

今天搞了下windows 7下的文件共享,总是搞不定,虽然以前也偶尔有成功过,但未作记录,现在要搞一时搞不定,所以决定好好记录一下。 win7的文件夹共享搞得实在是太麻烦了(对于一般用户而言),为了权限控制&#…

1.the linux device model--kobject kset学习笔记

http://blog.chinaunix.net/uid-22547469-id-4590385.html?utm_sourcejiancool Linux设备模型就是一栋规模宏大的建筑,为了构建它,需要基本的建筑材料钢筋:kobject、若干钢筋组成的钢架结构:kset,还需要一种机制sysfs…

微信公众号开发笔记1-获取Access Token

获取你的Access Token a)可以采用网址的形式: 用appid和appsecert获得access token,接口为https://api.weixin.qq.com/cgi-bin/token?grant_typeclient_credential&appid你的APPID&secret你的APPSECRET 替换中间的你的APPID和APPSEC…

ant更改主题色报错Inline JavaScript is not enabled. Is it set in your options? vue ant主题色更改 vue-cli3

问题:使用vue-cli3更改ant的主题色时候报错:Inline JavaScript is not enabled. Is it set in your options? 原因:我的问题是less-loader依赖包的版本为5.0.0,而官方要求必须是6.0.0; ERROR Failed to compile …

ant中table表格的多选框如何清空

项目需求:表格前加一列多选框,可以做多选和提交,还可以在提交后、重置或者翻页后对多选框清空 使用的组件是ant中下的可操作选择的table;这样我们就知道复选框选中的那些数据id,其实就是selectedRowKeys数组里的id&am…

SCCM 2012系列1 服务器准备上

各位您好,今天我将开始给大家分享微软最新的SCCM 2012系列文章,让大家逐步了解在企业内如何搭建SCCM 2012的同时,了解各个功能模块,对应自己的企业环境来看,那些功能是您现在所需要的。当然还可以看看SCCM 2012比之前…

近期H5项目开发小结

前言:2016差不多又过了半啦,最近参与了公司好几个h5项目(严格来说,也只能算是推广页面活动)。主要是新品牌的推广需要,当然也有给公司以前老客户做的案例。今天主要总结下为新品牌开发的2个h5推广&#xff…

依赖包报错Invalid options object. Less Loader has been initialized using an options object that does not

1.问题:yarn安装依赖包,启动项目报错 error in ./node_modules/ant-design-vue/dist/antd.less Module build failed: ValidationError: Invalid options object. Less Loader has been initialized using an options object that does not match the A…

Asp.net页面和Html页面之间的关系

Asp.net页面显然要转化为普通的html页面才能在浏览器中显示,但是对于两者的关系,或者说从服务器在接受请求处理请求这段时间内对asp.net页面的操作一直不是很明白,下边的一段话可以让人豁然开朗,虽然并未谈论技术,但简…

vue-cli2定制ant-design-vue主题

本篇是vue-cli2定制主题,vue-cli3通过vue.config.js定制主题点击此处 1.引入less和less-loader(如果报错,请将less-loader版本更改到5.0.0) npm install less less-loader --save2.在 vue cli 2 中定制主题,修改build…

YUV视频格式分析

Andrew Huang <bluedrum163.com> 转载请注明作者及联络方式在摄像头之类编程经常是会碰到YUV格式,而非大家比较熟悉的RGB格式. 我们可以把YUV看成是一个RGB的变种来理解.YUV的原理是把亮度与色度分离&#xff0c;研究证明,人眼对亮度的敏感超过色度。利用这个原理&#x…

自定义ant中table表格的展开图标 修改ant-vue-design中嵌套表格table的expandIcon自定义图标

效果&#xff1a; 1. <a-table:expandIcon"expandIcon":loading"loading":columns"columns":data-source"data"class"components-table-demo-nested"change"onChangeTable":scroll"{x:1300,y:y}":p…

Foundationd和Application Kit的类层次

Foundationd类 Application Kit类 转载于:https://www.cnblogs.com/ikodota/archive/2012/08/01/2618590.html