Webkit 改善字体加载
翻译自webkit.org
在网站里自定义网页字体以及变得越来越流行。通过使用自己站点的资源,开发者以及可以使用特殊的字体。浏览器会在字体加载完成时使用它们,但不幸的并不是所有的字体都可以瞬间下载完成,这意味着字体的下载过程中浏览器已经显示了页面。大部分字体体积都有一点大,浏览器使用它们时会有一个延迟。WebKit用两个方式改善了这个问题:改善了字体下载策略,使字体下载更快。
默认字体下载策略
浏览器尝试用最快得方式显示页面,可能尽管字体正在下载还不能使用。WebKit总是会在字体下载完成后显示它们,使用这些字体时,WebKit在下载延迟的过程中仍然显示文字元素。但老版本的WebKit会在字体下载完成前不显示这些文字。相应的,新版本的WebKit会保留最大3秒的文字隐藏时间,之后会使用本地字体显示文字,直到字体下载完成时会被新的字体替换显示。
此处有视频 请阅读原文观看
得幸于文字快速下载,这个新的策略使降级兼容(fallback)文字最小的闪现,避免了不确定得长时下载造成的模糊。最棒的地方是页面不需要做任何改进来使用这个新代理,所有的字体下载讲被设置成默认。
CSS字体加载API
不同的网页开发者可能希望使用不同的策略,来改变标题字体或者全局字体。在新的WebKit中CSS font loading API使开发者可以彻底控制字体加载策略。
这个API暴露了两个主要的JS片段:FontFace
接口和FontFaceSet
接口。
FontFace
和CSS @font-face
的规则一样,所以它包含了字体的url、weight、unicode-range、family等。而FontFaceSet
包含了网页所有的字体是否可以被渲染。所有的document
都有自己的FontFaceSet
,可以在document.fonts
中查看。
使用这些对象去实行一个特别的字体加载策略变得十分直接,一旦FontFace
被构造,load()
方法就开始异步下载字体数据。当下载成功或因失败而时它会返回了一个Promise
。用过链式调用返回的promise,JS就可以处理它了。因此一个网站可以实行这样的策略:在不超时的情况下立即使用降级兼容字体。
<div id="target" style="font-family: MyFallbackFont;">hamburgefonstiv</div>
let fontFace = new FontFace("MyWebFont", "url('MyWebFont.woff2') format('woff2'),
url('MyWebFont.woff') format('woff')");
fontFace.load().then(function(loadedFontFace) {
document.fonts.add(loadedFontFace);
document.getElementById("target").style.fontFamily = "MyWebFont";
});
在这个例子里,元素样式声明使用了MyFallbackFont
,然后JS运行并开始请求MyWebFont
。如果文字加载成功,新加载的字体被添加进document的FontFaceSet
中并且元素的样式也被新的字体所取代。
WOFF2
不用担心哪些字体不能使用加载策略,字体加载飞快时,用户的体验将会很好。在macOS Sierra、iOS 10、GTK中WebKit已经支持一个全新的、体积更小的字体格式“WOFF 2”。新的压缩算法Brotli使这个字体体积更小,这使得WOFF 2字体可以更加快速的被下载,要比WOFF、OpenType、TrueType还快。WebKit也承认CSS@font-face
中scr属性里format("woff2")
的标识。因为目前不是所有的浏览器都支持WOFF 2,所以请优雅降级兼容其他的格式。
@font-face {
font-family: MyWebFont;
src: url("MyWebFont.woff2") format("woff2"),
url("MyWebFont.woff") format("woff");
}
这个例子里,浏览器会选择它们所能支持的字体格式。因为浏览器优先加载列表中考前的字体,所以如果浏览器支持WOFF 2,它会被优先加载。
unicode-range
流量是十分珍贵的资源(尤其是在移动设备上),所以最小化或排除没用字体变得极其有价值。WebKit现在支持unicode-range
CSS属性。
@font-face {
font-family: MyWebFont;
src: url("MyWebFont-extended.woff2") format("woff2"),
url("MyWebFont-extended.woff") format("woff");
unicode-range: U+110-24F;
}
@font-face {
font-family: MyWebFont;
src: url("MyWebFont.woff2") format("woff2"),
url("MyWebFont.woff") format("woff");
unicode-range: U+0-FF;
}
<div style="font-family: MyWebFont;">hamburgefonstiv</div>
在这个例子里,没有一个字符属于MyWebFont
中第一个CSS@font-face
规定的unicode-range
中,这意味着没有下载第一个@font-face中得任何字体。有一点很重要,最后一个@font-face
会被下载。因此最通用的CSS@font-face
规则应该放在列表的最后。使用unicode-range去分割字体可以避免下载全部的字体,让你拯救用户的流量和电量。