对于我正在构建的网站,我试图通过在头部加载一些内联字体/异步 JS 来获得绝对最佳的性能。为了解决 Typekit 字体加载所需的额外 http 请求和延迟加载,我选择在我的 LESS / CSS 中对我的 woff / woff2 字体(FontAwesome、Lato、Lato Bold)进行 base 64 编码。在本地运行时,我的 DOMContentLoaded(蓝条)降低到 30 毫秒,但它出现的字体内联导致我的实际加载时间(红条)为 280 毫秒。
索引.html
<!DOCTYPE html>
<html lang="en" xmlns:ng="http://angularjs.org" ng-app="tix.app" ng-strict-di ng-cloak class="wf-loading">
<head>
<base href="/">
<!-- blocks to hide FOUT -->
<style>.wf-loading [class^="icon-"], .wf-loading [class*=" icon-"], .wf-loading h1, .wf-loading h2, .wf-loading h3, .wf-loading h4, .wf-loading div, .wf-loading p, .wf-loading span, .wf-loading a, .wf-loading ul, .wf-loading li .wf-loading i { visibility: hidden !important; }</style>
<!-- starts download of dependent libraries (angular / d3 / jquery..) -->
<script src="/app/depends.js.gz" async defer></script>
<!-- starts download of angular app, has a check to ensure depends is downloaded first -->
<script src="/app/tix.js.gz" async defer></script>
<meta charset="utf-8"/>
<title>Angular SPA</title>
<link rel="icon" href="/favicon.ico" type="image/x-icon">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- blocks to download inline base64 fonts and bootstrap based styles -->
<link href="/assets/css/tix.min.css.gz" rel="stylesheet" />
<!-- script to tell the page that CSS has finished loading so show text (wf-active) -->
<script src="/app/tix.fast.js.gz" async defer></script>
</head>
<body>
<angular-stuff></angular-stuff>
</body>
</html>
依赖.js
'use strict';
module.exports = require('angular');
require('./d3.min');
require('./jquery-1.9.1.min');
require('./jquery.signalR-2.2.0.min');
require('./socket.io-1.3.4.js');
require('./ui-bootstrap-tpls.js');
require('angular-route');
require('angular-bootstrap');
require('angular-animate');
require('angular-loading-bar');
require('./ngStorage');
window.dependsLoaded = window.dependsLoaded || function () {};
window.dependsLoaded();
tix.js
window.isDependsLoaded = false;
function dependsLoaded() {
// App code
}
window.dependsLoaded = dependsLoaded;
// If angular already exists and the dependencies haven't been loaded, depends.js must have finished loading first -> manually initialize
if(window.angular && !window.isDependsLoaded) {
window.dependsLoaded();
}
tix.fast.js
(function (d) {
d.documentElement.className = "wf-active";
}(document));
tix.less (tix.css) 像这样通过@font-face 导入所有字体 -
@font-face {
font-family: 'Lato';
src: url(data:application/font-woff2;charset=utf-8;base64,......) format('woff2'),
url(data:application/font-woff;charset=utf-8;base64,......) format('woff');
font-weight: normal;
font-style: normal;
}
如您所见,我使用我的内联 CSS 和 html 元素上的手动“wf-inactive”类隐藏了所有文本元素。然后我在加载我的 CSS 字体之前异步加载我的主脚本(这样下载将在 css 阻塞之前开始)。depends.js 拥有我所依赖的所有外部库(AngularJS、jquery、signalr 等)。tix.js 包含我所有的应用程序逻辑(实际的 Angular 应用程序,比depends.js 小得多,但会更频繁地更新,因此我将它们拆分以从depends.js 缓存中受益)。在异步脚本之后,我加载了我的 css 文件(所有样式捆绑在一个 CSS 文件中,包括我的内联 base 64 字体),它会阻塞,在完成加载之后,我然后加载 tix.fast.js,它只是将 html 类更新为“wf-active”,将页面文本设置为可见(模拟 Typekit)。
我基本上看到网络选项卡中内联的每种字体都有额外的网络延迟。这让我感到困惑有几个原因:
为什么这些内联字体首先被视为网络请求?他们使用 url(data....) 标签,但内联它们的重点是避免网络请求,所以这里发生了什么?对我来说,网络请求正在下载它们嵌入的文件,但加载字体时可能需要更多的跃点?
我试图尽量减少 http 调用的数量,因为 chrome 只允许同时进行 6 个。这就是我的字体挂掉的原因吗?是不是因为 DOM 直到接近红色加载点才尝试访问它们,而 @font-face 那时只是延迟加载它们?我最好的选择是什么?