@font-face字体的伪后台加载

@font-face规则允许网页使用客户端未安装的字体。本文探讨了@font-face对网页性能的影响及优化策略,包括字体文件的加载时机、Gzip压缩、多域名分散加载等,并介绍了一种伪后台加载方案以改善用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

@font-face用于自定义显示字体,在浏览器中加入@font-face的功能(比如使用特殊的字体来显示页面某部分的字体,甚至采用特别字体定义整站文字的以配合设计风格)从而避免采用图片的方式来显示特定字体。
中文互动百科中,@font-face定义如下:
语法:  
@font-face { font-family : name ; src : url ( url ) ; sRules }  
取值:  
name :  字体名称。任何可能的 font-family 属性的值  
url ( url ) :  使用绝对或相对 url 地址指定OpenType字体文件  
sRules :  样式表定义  

说明:  
设置嵌入HTML文档的字体。此规则无默认值。  
此规则使你能够在网页上使用客户端本地系统上可能没有的字体。 url 地址必须指向 OpenType 字体文件(.eot或.ote)。此文件包含可以转换为 TrueType 字体的压缩字体数据,可以用来提供HTML文档使用该字体,或取代客户端系统已有的同名字体。此文件可以使用 Microsoft WEFT 工具制作。  

示例:  
@font-face { font-family:comic;src:url(http://valid_url/some_font_file.eot); }  
@font-face { font-family: dreamy; font-weight: bold; src: url(http://www.example.com/font.eot); }
但由此带来了另一个问题是: 字体文件对web网页效率的影响。

Steve Souders在其博文《@font-face and performance》(查看CNBLOG中文翻译版)中对 @font-face 指向的字体大小不同而产生的性能问题的现象、原因作了比较详细深入的阐述,并提出以下建议:
  • 1.只在你确定你非常需要 @font-face的时候才使用他
  • 2.将你的@font-face定义在所有的SCRIPT标签前
  • 3.如果你有许多字体文件,考虑将它们分散到几个域名下。
  • 4.不要包含没有使用的 @font-face声明——IE将不分它使用与否,通通加载
  • 5.Gzip字体文件,同时给它们一个未来的过期头部声明
  • 6.考虑字体文件的后加载,起码对于IE。 
而西红柿爱番茄的博文《 @font-face的性能测试》进一步针对各种浏览器作了详细的测试并给出了分析报告:
下面是各种浏览器对@font-face的测试比较结果,结果分为三类:IE,Firefox、Opera,Safari、Chrome。
  1. 在Firefox、Opera中,并不会阻塞页面其他资源的加载,也不会影响页面渲染,而且在字体加载下来之前,对想应用该字体的内容会使用默认的字体显示,直到字体加载下来之后再渲染为指定的字体。因此,这两个浏览器测试效果最佳。
  2. 在Safari、Chrome中,并不会阻塞页面其他资源加载,也不会影响页面渲染,但是在字体加载下来之前,对应用该字体的内容将会首先空白显示,但是内容尺寸是存在的,直到字体加载完成,才渲染字体样式。
  3. 在IE下就分不同的情况了,如上所述,前面是否有script标签的情况。
当我们需要避免由于font-face字体读取带来的糟糕的用户体验时,相对于前面几篇文章中提到的 lazyload方案,根据其基本原理,其实存在另一种无缝切换的方案,姑且称之为“伪后台加载”,因为对用户而言,他们确实没有由于等待读取字体而看到空白的页面或者空白文字区域(Chrome、Safari),但页面实际并不是真的在后台去加载的字体文件。

方案如下:

大部分页面其实都存在Logo区域或者类似的图片链接区域,其定义可能如下
HTML
<a href="www.163.com" class="logolink" title="网易163">网易163</a>
CSS
.logolink{ 
  background: url(Logo图片地址) no-repeat left top; 
  height: 高度值; 
  width: 宽度值; 
  text-decoration: none; 
  display: block; 
  text-indent: -1000em; 
}

由text-indent将文字移出屏幕以实现图片链接,此时,如果我们设置该超链接的字体样式为font-face定义的样式,浏览器样式表仍然会为这些实际上不会显示的文字读取字体文件。而其他文字则统一使用默认的字体来显示,用户将在第一时间看到一个以默认字体显示页面。接下来,就是如何在自定义字体下载完成的时候将默认字体替换为自定义字体了。

在JQuery中,我们常常用到 $(document).ready(function(){……}) 语法来加载页面的一些初始动作,实际上该事件实在页面DOM解析完成时触发,因此如果在此进行字体切换,实际效果与我们在CSS中直接写入自定义字体一样,无法避免用户的不良体验。我们需要用到的是能够在页面完全加载后触发的事件: $(window).load(function(){........}),方案如下


HTML
<a href="www.163.com" class="logolink" title="网易163" style="font-family:自定义字体名称">网易163</a>
CSS
.logolink{
background: url(Logo图片地址) no-repeat left top;
height: 高度值;
width: 宽度值;
text-decoration: none;
display: block;
text-indent: -1000em;
}
Javascript(JQuery)
$(window).load(function(){
  //这里用了全选整个页面所有元素进行替换,也可以根据需要只替换部分
  $("body *").css("font-family","自定义字体名"); 
});


这时,整个页面将会有Javascript触发替换页面中需要替换的字体。整个页面的字体刷新完成。
该方案在Chrome/FF/Safari等标准浏览器下测试正常,IE没有进行测试。



帮我修复这段js代码 , 这是 uniapp 制作印章canvas 需要切换文字的字体的功能 , 需要支持小程序 h5, 字体文件都是在我的服务器上面, 字体都是 .ttf的字体 , 现在只有小程序模拟器好使 ios手机小程序好使 , 安卓系统不好使 nginx也增加过同源方案 小程序域名也配置过下载地址允许白名单内的 , 使用的方法目前是 这样的代码 ,代码里面的base64 目前路径是这样的(https://aaaa.com/xcx/font/kaiti.ttf) : // 平台环境判断 const isH5 = process.env.VUE_APP_PLATFORM === 'h5' const isMP = typeof wx !== 'undefined' && wx.canIUse('loadFontFace') // 字体缓存池 const loadedFonts = new Set() // 统一字体加载方法 export const loadFont = (fontName, base64Data) => { return new Promise((resolve, reject) => { // 检查是否已加载 if (loadedFonts.has(fontName)) { console.log(`字体 ${fontName} 已加载,使用缓存`); resolve(true); return; } // 平台判断 if (isH5) { // H5字体加载 // const style = document.createElement('style'); // style.innerHTML = `@font-face { // font-family: "${fontName}"; // src: url('${base64Data}'); // }`; // document.head.appendChild(style); // loadedFonts.add(fontName); // console.log(`H5字体 ${fontName} 加载成功`); // resolve(true); try { const style = document.createElement('style'); style.type = 'text/css'; // 显式声明样式类型:ml-citation{ref="4" data="citationList"} style.textContent = `@font-face { font-family: ${JSON.stringify(fontName)}; // 安全转义字体名 src: url('${base64Data.replace(/'/g, "\\'")}'); // 处理特殊字符 }`; document.head.appendChild(style); loadedFonts.add(fontName); resolve(true); } catch (e) { reject(new Error(`字体样式注入失败: ${e.message}`)); } } else if (isMP) { // 小程序字体加载 // wx.loadFontFace({ // family: fontName, // source: `url("${base64Data}")`, // success: () => { // loadedFonts.add(fontName); // console.log(`小程序字体 ${fontName} 加载成功`); // resolve(true); // }, // fail: (err) => { // console.error(`字体加载失败: ${fontName}`, err); // reject(new Error(`字体加载失败: ${fontName}`)); // } // }); const start = Date.now() //old // wx.loadFontFace({ // family: fontName, // source: `url("${base64Data}")`, // global: true, // success: () => { // loadedFonts.add(fontName) // console.log(`加载耗时: ${Date.now()-start}ms`) // // setTimeout(resolve(true), 300) // 增加延迟确保生效 // setTimeout(() => resolve(true), 300) // }, // fail: () => resolve(false) // }) //new uni.loadFontFace({ global: true, // 是否全局生效 family: fontName, // 定义的字体名称 source: `url("${base64Data}")`, // 字体资源的地址。建议格式为 TTF 和 WOFF,WOFF2 在低版本的iOS上会不兼容。 success() { loadedFonts.add(fontName) console.log(`加载耗时: ${Date.now()-start}ms`) // setTimeout(resolve(true), 300) // 增加延迟确保生效 setTimeout(() => resolve(true), 300) }, fail(e){ console.log(e,'失败的回调函数') }, complete(){ //console.log('接口调用结束的回调函数(调用成功、失败都会执行)') }, scopes: ["webview", "native"], }) } else { reject(new Error('不支持的平台')); } }); } // 导出常用方法 export { isH5, isMP, loadedFonts };
最新发布
07-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值