现象
分析
WEB用到了自定义字体,DOM解析渲染时,字体还未加载完全,立即使用缺省字体显示,字体加载完成后,重新渲染替换
手段
明确了问题,就着手优化解决,改进点有以下几方面
样式抽离
当前WEB样式是打包进JS,每次是动态插入Style到header部分,所以较慢。另外JS变动实际上造成指纹【即内容hash】变化,样式就连代受影响,无法缓存,所以抽离还是有益于性能提升。
Webpack loader及plugins需要增加以下配置
1 |
|
1 | new MiniCssExtractPlugin({ |
预加载
注意
- 预加载,使字体不至于在CSS解析时才开始加载,提升字体资源加载的优先级
- 考虑当前开发的WEB,目标浏览器为Chrome,IE11+,Safari等,这里我只加载woff2,和woff,要知道体积大小上,woff2 < woff < tff,
- 因为
woff2
在IE下不支持,所以需要配置woff
贴下配置
1 |
|
1 | @font-face { |
注意如果字体加载跨域Link标签需要配置 crossorigin
,比如crossorigin=”anonymous”,否则预加载即使成功,但安全考虑因此字体并不会真正应用,因此最终字体会因为预加载及CSS中的font-face加载两次。
字体文件体积
如上预加载可以分离CSS的解析与字体资源的加载,但字体文件过大也是个问题,为此进行如上配置,优先下载woff2,对IE才会下载woff,ttf不考虑。
关于不同格式字体的体积差异,比如labo-regular
- woff-
309KB
- woff2-
183KB
- ttf-
608KB
此外,还有2个手段可进一步缩小字体体积
- base编码字体文件,也就是合并了字体与样式,减少请求。这里我并采用,但是个手段
- 采用子集内嵌,因为字体文件中包含的字符编码并不是都用的上
字体显示策略
假如字体文件加载耗时在3秒可接受范围内,浏览器在字体加载还没完成时,可以以缺省字体显示内容,也可以先隐藏,3秒后,字体文件如果下载完成,则自定义字体显示文本,如果没有则,使用后备字体显示,等字体文件下载完成,再交换。
字体切换会出现闪烁效果,所以这里我将显示策略改为auto,,即走默认策略,3秒内还没加载完字体,文本不可见。
如使用swap,则字体加载的同时,会立即以默认字体展示,进而会有可视化看到字体变化的效果,一开始的问题便是这个原因。
但并不是swap就一定不好,具体使用哪个策略,视情况而定。
auto,block确保了不会出现字体变化的问题,但文本不可见的时间越长体验越差,所以要持续优化加载体验,比如CDN等。
相关术语
在网页性能这块实际上也是个重要的课题,比如就有以下这样的术语
FOUC (flash of unstyled text)
网页渲染时,外部样式还没加载好,就以浏览器默认样式短暂地展示了部分内容,等到外部样式加载完成,又恢复正常的这个页面闪烁的过程
今天的WEB如果处理好资源加载顺序,这个问题是完全可以避免的。
浏览器加载HTML,CSS,JS顺序
如上一开始的问题直接原因只是字体的显示策略需要调整,同时提升字体下载速度,但背后却牵引出浏览器在加载资源时的流程处理,于是,这里梳理下。
这里以一个实际的SPA index页面为例,浏览器加载到解析渲染的流程如下
1 |
|
有错,欢迎指出
补充
浏览器对CSS阻塞渲染有两种处理方式,要么等css解析完一起渲染,Chrome就是这么做的,但是会造成白屏;要么先把无样式的dom渲染出来等css解析好了再渲染一次,Firefox就是这么做的,但是会造成无样式内容闪烁
写在最后
不得不说浏览器相关的知识点还是挺琐碎,复杂的。。。共勉。