对@font-face的作用,也是今晚在看这篇博文《@font-face and performance》的时候,才知道使用它可以自定义显示字体。我想在浏览器中加入@font-face的功能是处于一定的情况的,比如使用特殊的字体来显示页面某部分的字体,从而避免采用图片的方式来显示特定字体。出发点是很好的,但是……
解析@font-face的机制在不同的浏览器下是不同的。
对于@font-face更多的叙述,在上面提到的那篇博文中有了详细的描述。但是对于它提出的说“IE doesn’t render anything in the page until the font file is done downloading if there is a SCRIPT tag above the @font-face declaration.”,说的是当在声明@font-face的前面如果存在script标签的时候,IE下不会渲染任何东西,页面一片空白,直到@font-face指定的字体加载完为止,这点经过测试,确实如此。
在声明@font-face的标签之前没有script标签的时候IE下并没有出现阻塞页面渲染的情况,但是如果前面有script标签的时候,不管是否是紧跟这script标签,只要在@font-face标签前面有script标签,就阻塞页面渲染:《没有script标签》,《紧跟script标签》,《不紧跟script标签》。
同时,我测试了@font-face是否会阻塞页面其他资源加载,测试发现并没有这个问题:《是否阻塞资源加载的测试》,而且在字体加载下来之前,忙指示器会一直处于等待状态。下面是各种浏览器对@font-face的测试比较结果,结果分为三类:IE,Firefox、Opera,Safari、Chrome。
- 在Firefox、Opera中,并不会阻塞页面其他资源的加载,也不会影响页面渲染,而且在字体加载下来之前,对想应用该字体的内容会使用默认的字体显示,直到字体加载下来之后再渲染为指定的字体。因此,这两个浏览器测试效果最佳。
- 在Safari、Chrome中,并不会阻塞页面其他资源加载,也不会影响页面渲染,但是在字体加载下来之前,对应用该字体的内容将会首先空白显示,但是内容尺寸是存在的,直到字体加载完成,才渲染字体样式。
- 在IE下就分不同的情况了,如上所述,前面是否有script标签的情况。
对于@font-face的杯具的性能问题,如果没有必要,就尽量避免使用。如果一定要使用的话,可以使用使用lazy load的方式来加载,例如博文中给出的例子:
[javascript]
function lazyload() {
var sRule1 =
"@font-face {" +
" font-family: ‘Yanone’;" +
" src: url(‘/bin/resource.cgi?type=font&sleep=6′);" +
" src: local(‘Yanone’), " +
"url(‘/bin/resource.cgi?type=font&sleep=6′) " +
"format(‘truetype’);" +
"}";
var style1 = document.styleSheets[0];
if ( "function" === typeof(style1.insertRule) ) {
// Firefox, Safari, Chrome
style1.insertRule(sRule1, 0);
}else if ( "string" === typeof(style1.cssText) ) {
// IE
style1.cssText = sRule1;
}
}
[/javascript]
将上面的lazyload函数添加到页面的onload事件中去执行,这样就保证了页面的正常渲染并且实现特定字体样式的功能:《lazy load测试》。这个主要是解决IE下@font-face前面有script标签的问题,在其他浏览器下显示的时候,也都还是会在应用该字体的内容中产生空白闪烁、或者是默认字体和指定字体之间的切换闪烁。也都还是在一定程度上影响了用户体验,感觉有些不爽。“Tradeoff is anywhere!!”
上面的三个测试都是使用内联CSS的方式,考虑到使用外联CSS样式表的情况,又对此做了一番测试,发现了不同的状况:
- 当link放在head时,IE6、8(没有IE7,测试不了)都是死心眼,偏执要阻塞整个页面的加载,在字体下载下来之前整个页面一片空白,其他浏览器跟内联CSS一样的显示:《外联CSS测试(在head内)》。
- 当link放到body中时,IE8还是阻塞整个页面的渲染,可是IE6就不同了,IE6会阻塞整个页面样式的渲染,但是不会阻塞link前面的内容的显示,而是阻塞了其后面的内容的显示了,直到字体加载下来之后才开始渲染页面样式和显示link后面的内容。其他浏览器跟内联CSS一样的显示:
《外联CSS测试(在body最底部)》,《外联CSS测试(在body中部)》 - 当link前面带有script标签的时候,因为外联在head头部的时候在IE各版本都阻塞了,所以这个条件link在页面的任何位置都无所谓,主要测试link前面带有script标签,那就把link放在body中来测试。这下IE6也杯具了,阻塞了整个页面的渲染,IE8照常阻止整个页面渲染,其他浏览器同上。《外联CSS测试(在body中部),前跟script标签》,将link放到body最底部也一样阻塞整个页面的渲染:《外联CSS测试(在body最底部),前跟script标签》,其他浏览器同上。
对于页面中同时有script和link、style标签是很正常的事情,但是当样式中有@font-face的时候,情况就复杂了。更多的测试条件大家可以自行测试。有错误的地方,请不吝留言交流。
拜读楼主的文章