WebFont 三宗罪之一:WebFont 与 FOUT
四赴T.I.T 创意园面试,所学甚多。这篇文章是昨天面试中探讨的一个问题所延伸而来,现在都说WebFont 怎么好怎么好,让我们逆向思维,揭底WebFont 的一些缺点(劣势)。本文综合多篇文章来探讨WebFont 与 FOUT。
首先,神马是 FOUT
FOUC,即无样式内容闪烁(Flash of Unstyled Content),指的是 Web 字体在下载并渲染之前,短暂显示无样式文本的情况。它会严重影响用户体验,尤其是当字体样式渲染前后有明显不同的时候。这个名词是09 年的时候由一个老外提出命名的(见参考来源1),没办法人家英文WebFont 早早就流行了。
按照许多旧文章的描述,FOUT 在IE 浏览器跟部分低版本Firefox 上会有,但Jeff 认为这是错误的——因为当我脑海中有写“WebFont 与 FOUT”的文章的想法,它就给我蹦出一个活生生的例子:大名鼎鼎的腾讯ISUX 官方博客。各位可以前往其官博浏览下,注意下文字的内容(比如首页瀑布流下的文章标题及内页标题)。就算你是用Chrome,照样有之。为了防止日后美观的ISUX 官方博客改版,先截个动图:
如果你没有类似gif 截图的效果,那么我只能想到一个理由:哥们你家网速真快。
装逼般深入解析
首先先说下,腾讯ISUX 官方博客是全站WebFont 的,看源码采用的是来自国内的一个中文WebFont 网站的商业解决方案,而且形式上有些不同是采用JavaScript 动态加载的方式。将ISUX 作为本文的例子仅为解释FOUT 之用,无其他恶意成分(事实上ISUX 官方博客真心做的不错无论是设计还是内容本身)。
那么为什么会产生FOUT 呢?
这得扯到WebFont 的实现原理之@font-face 了,详细原因么,鄙人不才,不好意思我是来搬砖的:请先看下国外的一篇《@font-face and performance 》(中文翻译见这)。
该文的几个要点:
1、字体文件的下载不会阻滞其他文件下载。
2、跟其他静态文件一样,字体文件依然受同一域名下载限制的影响。
2、FOUT 在IE 中相对而言比较严重,甚至会导致页面白屏。
看完本文,大概的话得出的结论大概是:字体文件大,连接速度慢。
所以兜兜转转,回归到性能优化上了。
FOUT 尽可能般的解决方案
针对FOUT,《Web 性能实践日志》提出了一些解决方案,在这里就直接援引之:
1、将字体文件(或者说援引的CSS)托管到CDN(内容分发网络)。
2、Gzip 压缩所有字体文件,除了 .woff 字体。
3、增加缓存过期头来缓存字体。
4、从字体文件移除多余的字符(换而言之:按需使用)。
5、确保@font-face 是样式表中的第一个样式表的第一条规则(代码靠前)。
6、适当采用JavaScript 动态加载的方式(Typekit 跟Google 有个类似的方案Webfont Loader)。
后记
本文多多少少有点标题党的嫌疑(不然怎么吸引你看到这里捏:-D),请勿喷。如果有错误,欢迎指出并一齐探讨。
本文参考来源:
1. http://www.paulirish.com/2009/fighting-the-font-face-fout/
2.《Web 性能实践日志》p160 ,人民邮电出版社
- GO语言并发编程之互斥锁、读写锁详解
- DBCA静默建库中的两个小问题 (r9笔记第28天)
- dataframe进行常用统计、分组统计平均绝对偏差等操作函数。
- Java案例-判断随机整数是否是素数
- Go语言实现猜数字小游戏的方法
- go lang连接mysql数据库
- Java案例-打印九宫格
- 【Go 语言社区】算法课程 第一季 第4节 100以内的素数
- Java案例-数组求余问题
- GO语言实现的端口扫描器分享
- Java案例-数组随机数
- Go语言图片处理和生成缩略图的方法
- Python3 怎么将Unicode转中文,以及GBK乱码ÖйúÉÙÊýÃñ×åÌØÉ«´åÕ¯
- 数据结构和算法——旋转打印链表
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Sentinel整合Apollo进行规则持久化(二)
- Sentinel整合Apollo进行规则持久化(三)
- BeesCMS的SQL注入漏洞
- 操作系统的演变及在云计算的应用
- 没root账号,如何安装perl包
- 从 BIO、NIO 聊到 Netty,还要手写一个 RPC 框架!毕设/项目经验稳了!
- 从100万条数据中找到极大值所在行
- 常考题 | IoU 计算
- 操作系统和并发的爱恨纠葛
- Vue Router详细教程
- C语言作图库(kplot)示例
- Linux文本处理详细教程
- 使用LDheatmap快速绘制SNP连锁不平衡图
- Ubuntu nfs配置
- window.showModalDialog()用法