深入理解CSS @font-face性能优化
本文重要介绍字体加载优化的常用策略,大部分内容为引用和翻译。
一、 font-face基本用法
font-face的基本用法想必大家都是知道的,基本上就是类似如许:
@font-face { font-family: Lato; src: url('font-lato/lato-regular-webfont.woff2') format('woff2'), url('font-lato/lato-regular-webfont.woff') format('woff'), url(font-lato/lato-regular-webfont.ttf) format("opentype"); } p { font-family: Lato, serif; }
如许就可以使我们的页面用上自定义字体了。 除了font-family 和 src属性之外,还拥有font-style以及font-weight属性。 src可以指定多种字体,会按顺序依次适用,比如上面的示例中会先加载woff2字体,假如失败再加载woff字体,否则加载opentype字体。 src所支持的字体可以有以下类型:
src参数带不带引号都可以,参数的格式不同含义也不尽雷同,比如下面:
src: url(fonts/simple.woff); /* 加载simple.woff,地址相对于样式表的地址 */ src: url(/fonts/simple.woff); /* 加载simple.woff,地址是网站的绝对地址 */ src: url(fonts/coll.otc#foo); /* 从coll.otc字符集中加载foo字体 */ src: url(fonts/coll.woff2#foo); /* 从coll.woff2字符集中加载foo字体 */ src: url(fonts.svg#simple); /* 加载id 为'simple'的SVG字体 */
src中加载的字体地址受跨域的束缚,假如想跨域加载字体,必要设置CORS。
这就是font-face的最基础的用法。 接下来我们会进一步分析font-face的用法,并尽可能的找出优化策略。
二、 什么时候会下载字体?
上面讲了字体的基本知识,那你有没有想过,字体是在什么时候下载的呢?当我们仅仅在CSS中定义如下样式的时候, 网页加载,字领会主动下载吗?
@font-face { font-family: Lato; src: url('font-lato/lato-regular-webfont.woff2') format('woff2'), url('font-lato/lato-regular-webfont.woff') format('woff'), url(font-lato/lato-regular-webfont.ttf) format("opentype"); }
很遗憾,字体并不会下载。 通常情况 下,只有当我们的网页元素用到了font-face中定义的字体的情况下,才会下载对应的字体。
细致: 这里我们说了是通常情况,这是由于,IE8在只要是定义了font-face,即使网页元素没有使用对应的字体,也会下载。
在其它欣赏器中也不尽雷同,
比如在 Firefox 和 IE 9+ 中,碰到如下情况也会下载字体:
html
<div id="test"></div>
css
#test { font-family: Lato; }
有什么分外之处呢? 你可能细致到了,这个元素虽然使用到了font-family: Lato样式,但是这个元素并没有任何文本啊!!!。 按照我们的理想情况,应该是,只有有笔墨内容才会去下载字体嘛。 而这就是Chrome, Safari (WebKit/Blink 等)欣赏器的举动。
Chrome, Safari (WebKit/Blink 等)欣赏器只有在如下类似情况才会去下载字体:
html
<div id="test">这里是有文本的哦</div>
css
#test { font-family: Lato; }
所以总结一下,不同欣赏器下载字体的策略:
IE8 只要定义了font-face,就会去下载字体,不论现实有没有应用该字体。
Firefox, IE 9+ 只有定义了font-face 并且网页有元素应用了该字体,就会去下载,不论该元素是否有文本内容。
Chrome, Safari 只有定义了font-face 并且网页有元素应用了该字体,并且该元素有文本内容,才会去下载字体。
那你可能会问了,假如我们的DOM元素是通过动态插入的呢?比如:
var el = document.createElement('div'); el.style.fontFamily = 'open_sansregular'; document.body.appendChild(el); el.innerHTML = 'Content.';
答案是一样的,它的下载策略如下:
var el = document.createElement('div'); el.style.fontFamily = 'open_sansregular'; /* 到这里,IE8就会开始下载字体 */ document.body.appendChild(el); /* 只有到这里,Firefox, IE 9+ 才会开始下载字体 */ el.innerHTML = 'Content.'; /* 只有到这里,Chrome, Safari 才会开始下载字体 */
三、 FOIT(Flash of Invisible Text)
FOIT是欣赏器在加载字体的时候的默认体现情势,也就是在字体加载过程中,网页是看不到文本内容的。在当代欣赏器中,FOIT会导致这种征象出现至多3秒。FOIT会导致很差的用户体验,这是我们必要尽量去避免的。
四、 FOUT(Flash of Unstyled Text) 与 font-display属性
FOUT意思是在字体加载过程中使用默认的体系字体,字体加载完后表现加载的字体,假如超过了FOIT(3s)字体还没加载,则继承使用默认的体系字体。
IE欣赏器和Edge不会等待FOIT超时才表现默认字体,会立即表现默认字体。FOUT比FOIT好,但是必要细致它引起的reflow.
那么要想使欣赏器有FOUT举动,我们必要在设置@font-face的时候给它加一个属性:font-display。 font-display默认是auto, 可选属性与含义如下:
auto. The font display policy is user-agent-defined.
block. Gives the font face a short block period (3s is recommended in most cases) and an infinite swap period.
swap. Gives the font face an extremely small block period (100ms or less is recommended in most cases) and an infinite swap period.
fallback. Gives the font face an extremely small block period (100ms or less is recommended in most cases) and a short swap period (3s is recommended in most cases).
optional. Gives the font face an extremely small block period (100ms or less is recommended in most cases) and a 0s swap period.
一样平常设置成fallback和optional即可。
五、 preload
在网页加入下面这个代码以便更快的加载字体:
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>
通常和最基本的字体用法配合使用
六、 字体转 BASE64URI
这种方法就是将@font-face中定义字体时的路径直接改为字体的base64编码。
好处: 这种做法的好处是不会产生FOIT和FOUT。所以也不会有reflow和repaint. 瑕玷: 字体转成base64也会很大,会影响网页首次加载速度。不支持逗号分隔的情势加载多种格式的字体,只能加载一种格式字体。这导致你为了尽可能保证所有欣赏器都可以兼容,通常会指定为woff格式,由于woff格式兼容性好,但是却没法使用更小体积的woff2格式,由于woff2格式兼容性差点。
七、异步加载BASE64格式URI字体
这种方法就是通过异步的体例插入带有BASE64格式URI字体的CSS链接。
八、使用Font Load API + FOUT + class切换
这种体例是期初并不使用用到@font-face的class,然后用Font Load API加载我们想用的字体,然后切换响应的CSS即可。Font Load API是原生的API:
document.fonts.load('1em open_sansregular') .then(function() { var docEl = document.documentElement; docEl.className += ' open-sans-loaded'; }); .open-sans-loaded h1 { font-family: open_sansregular; }
当然这种方法必要考虑欣赏器兼容性的题目。
九、 FOFT(Flash of Faux Text)
FOFT会把字体的加载分成多个部分,首先加载罗马网络字体,然后会在加载真实的粗体和斜体的时候立即使用font-synthesis属性渲染粗体和斜体的变体。
这种方法是基于[ 使用Font Load API + FOUT + class切换
]这种体例的,特别很是适合加载统一种字体但是不同粗细,字形的场景,比如罗马、粗体、斜体、粗斜体等。我们将这些字体分成2阶段: 第一阶段是罗马字体,然后立即渲染人造粗体和斜体,最后(第二阶段)用真实字体替换。这里面还可以使用sessionStorage优化访问重复视图的场景。
十、CRITICAL FOFT
CRITICAL FOFT和标准的FOFI的唯一区别就在于第一阶段罗马字体的加载,CRITICAL FOFT不会加载罗马字体的全集,只会加载它的一个子集(比如A-Za-z0-9),全集会在第二阶段加载。
十一、CRITICAL FOFT WITH DATA URI
这个和CRITICAL FOFT的唯一区别就是罗马子集字体的加载体例,前面是用Font Load API完成了,这里会将马子集字体硬编码成BASE64 URI的情势加载。
以上就是本文的悉数内容,盼望对大家的学习有所帮助,也盼望大家多多支持图趣网。
本文地址:http://www.tuquu.com/tutorial/wd491.html