一、DNS预取
如果你像我一样想在网站上有一个Twitter小程序,还有网站分析,再也许一些网页字体,那么你必须要链接到一些其它域名,这意味着你将不得不引发DNS查询。我的建议通常是,不要还没有先适当的考虑性能影响就使用某个或任何一个小程序,但对于你认为确实需要的,下面的将很有用……
因为这些东西都存在于其它域名,比方说这就意味着你的网站字体CSS将会同你自己的CSS并行下载,从某种意义上说是一种好处,但是脚本将仍会阻塞(除非它们是异步的)
事实上,这里的问题是DNS查询牵涉到了第三方域名。幸运的是,有一个相当快又简单的办法来加速这个过程:DNS预取。
DNS预取所做的恰恰就是凭证领餐(on the tin),它不能被简单实现。比方说,如果你需要请求来自widget.foo.com的资源,那么你可以通过简单的在页面的<head>里先增加下面这个来预取那个主机的DNS:
<link href="//my.domain.com" rel="dns-prefetch" />
<link href="http://my.domain.com/" rel="prefetch" /> <!– IE9+ –>
那行简单的内容将会告诉支持的浏览器去开始预取那个域名的DNS,这要稍稍早于它实际需要的时刻。它意味着DNS查询过程,在浏览器<script>元素真正请求小程序的时候就已经在进行中了。这仅仅给浏览器增加了一个很小的开头。
这种简单的链接元素(就是我在CSS魔法上用到的)完全后向兼容,而且不会忽略性能影响。将它看作是性能提升增强吧!
二、资源预取
和DNS预取一样,也可对站点需要的其它资源进行预取。为了弄清楚我们想要预取哪些资源, 首先我们需要了解浏览器通常会在什么时候以什么方式对资源发出请求。
CSS中引用的Web字体和图片表现基本相同;浏览器在碰到需要它们的HTML时开始对它们进行下载。就和我在前面提到那样,浏览器非常聪明,这又是一个例证。想象一下,浏览器一看到下面的CSS声明就开始下载其中所引用的图片:
.page--home { background-image:url(home.jpg); }
.page--about { background-image:url(about.jpg); }
.page--portfolio { background-image:url(portfolio.jpg); }
.page--contact { background-image:url(contact.jpg); }
如果浏览器不是等碰到需要这些图片的HTML再下载它们,那么访问主页就会立即下载所有这四个图片。这会造成浪费,所以浏览器一定会确保在需要这些图片时才会开始下载它们。所以,这里有个问题在于,图片下载直到很晚才会开始。
如果我们可以完全确认某个CSS图片肯定会在每个页面都会用到的话,我们就可以用个小把戏让浏览器早早下载好这个图片,无需等到让浏览器碰到需要使用该图片的HTML才开始下载。想做到这一点也非常简单,但所用的方法可能会有点糙,就看你怎么弄了。
比较糙的方法和大多数笨拙的万全之法类似,就是在每个页面放置一个隐藏的<div>,在该div中使用带有空的alt属性的<img>标签。我在CSS Wizardry项目中的精灵中就是这么干的;因为我知道,每个页面都要使用该精灵,所以我就通过在HTML中对其进行引用对它进行预取。浏览器处理内联(inline)<img>的方式非常好,浏览器会早早地对它们进行预取,所以通过让浏览器将我的精灵作为HTML中的<img>进行载入,浏览器就可以在使用需要精灵的CSS之前将其下载好。通过首先在我的HTML中引用该精灵(隐藏起来的),我就能够抢先把精灵下载好。
还有第二种方法比较“优雅”,但会让人有些困惑。它和DNS预取的例子非常相似
<link rel="prefetch" href="sprite.png">
这会显式地告诉浏览器,马上开始预取我的精灵图片,而不要考虑在它处理CSS时可能会做的任何决定。
令人感到困惑之处在于有两篇文章似乎有不同的观点;基于来自MDN的这篇文章,貌似这种预取指令只是示意浏览器仅在它空闲时才有可能会对href所指的资源进行预取。然而,与此矛盾的是,来自Planet Performance的这篇文章貌似在说,如果浏览器支持rel="prefetch"的话,它就一定会预取href中所指的资源,并没有提及是否要在浏览器空闲时才进行预取。我在WebKit的Inpsector中的瀑布图中所看到的情况是后者说得是对的,但是在打开Developer Tools的情况下(薛定谔测不准。。。)WebKit的表现及其怪异,我就观察不到预取动作的情况了,这也就是我说,我无法100%保证我说的是对的。要是谁能解释清楚这方面的情况,我将不胜感激。
我在前面说过,字体和图片表现非常相似,上面所说的规则同样也适用于字体文件,但你无法使用隐藏的<div>载入字体文件(你需要使用预取link)。
<link rel="prefetch" href="webfont.woff">
所以,基本可以这么说,我们这里所作的一切,只能算是让浏览器提前下载资源的“小把戏”而已,耍了小把戏之后,在浏览器碰到要使用CSS的时候,其中所引用的资源就早已下载好了(或者至少已经在下载中了)。 漂亮极了!
三、页面预取
和资源预取非常类似,我们也可以进行页面预取。该功能是firefox首先实现的。
<linkrel="prefetch"href="/my-next-page.htm">
页面预取的时候浏览器不但下载新的页面,而且下载该新页面所需的所有资源,并同时开始渲染该新页面(渲染过程对用户不可见),以确保整个页面包括新页面对用户是连续性呈现。
对于Chrome,使用
<linkrel="prerender"href="http://mydomain.com/my-next-page.htm">
页面预取技术目前还是有争议的,很多人认为其中最大风险是,在转到下一个页面之前进行渲染的对该新页面是否信任的问题。