月度归档:2013年01月

Prerender测试页面

prerender由页面中的<link rel=”prerender”>触发,如果您想体验一下prerender,并且使用的是chrome浏览器,那么您稍候两秒钟,再点击这个链接:Mogo浏览器,看是不是比点击别的链接要快一些。

如果要在wordpress中加入prerender,可以参考这篇文章:给WordPress加上Chrome的Prerender

科普贴:Chrome中的预渲染(Prerendering)

本文的内容主要来自Web developers’ guide to prerendering in Chrome,加入了自己的一些理解. 如果您认为本文理解有误,请以原文为准。

用户对体验的要求越来越高了,如果您点击一个链接,不用等待,内容立刻呈现在您眼前,这无疑会提升用户体验。所以从Chrome 13开始,引入了预渲染技术。但要体验这一技术,不光是浏览器方面的事情,网站也需要配合。

预读取(Prefetching)和预渲染(Prerendering)

由于Web是一个分布式系统,用户点击一个链接后,需要等待一段时间页面内容才能呈现出来。在页面中包含很多Javascript,插件,样式表等引用时,等待的时间会更长。

在某些情景下,其实可以预测到用户将会点击哪个链接。比如,您在阅读一篇分页的文章时,您很可能会点击“下一页”链接。这种情形下,在您点击链接之前浏览器就将内容加载了,无疑会让您体验到畅快的感觉。这就是预读取和预渲染的应用场景。预读取已经包含在HTML5规范中。

预读取特性已经在firefox实现(您可以从这里了解更多的firefox预读取特性)。网页开发者在HTML页面中包含<link>标签,指示浏览器获取给定的URL。浏览器读到这个标签后,获取该URL的顶层资源(一般是一个HTML页面)。然而,预读取技术有时并不能让您体验到速度大幅提升,原因在于网页内容一般还包含很多子资源,比如Javascript、CSS和媒体文件,仅仅预读取主页面是不够的。还有一种情况,网页内容是在页面加载过程中由Javascript动态插入的。

预渲染则更进一步,它不仅加载顶层资源,还做了显示页面内容的所有工作,除了把内容显示给您。简单说,预渲染就像您在后台tab页打开链接,然后切换到该tab页。不同的地方在于,预渲染中,“后台tab”并不可见,点击链接后无缝交换到当前Tab。这样给人感觉页面加载比以前快。

从Chrome17开始,Chrome还可以根据您在地址栏上的输入预测您要访问的内容,而提前加载。

触发预渲染

预渲染是否适用?

预渲染是一个非常先进的特性,但是不当的使用会导致体验下降,带来的问题有:流量增加、加载其它链接变慢、增加内存耗用。只有在您有很大把握确定用户下一步访问哪个链接,才考虑触发预渲染,比如文章中的下一页。对大多数网站而言和大多数场景下,启动预渲染并不合适。

触发预渲染的语法

在Chrome中,预渲染由HTML中的link标记触发,类似于firefox中预读取的触发。

预渲染链接元素的语法为:

<link rel="prerender" href="http://example.org/index.html">

需要注意的是,<link>标记仅仅是提示Chrome进行预渲染,但不能保证Chrome就一定会执行。以下原因会妨碍Chrome启动预渲染:

  • 您使用的Chrome版本默认没有开启预渲染
  • 您在设置中关闭了“预测网络操作,以提高网页载入速度”
  • 其它页面已经在预渲染了。
  • 页面上有多个预渲染的指示,这种情形下,哪个进行预渲染哪些被忽略是不确定的,取决于解析过程中先解析到哪个节点。
  • 您在隐身窗口中浏览网页
  • chrome检测到以下状况也会终止prerender:
    • URL指向下载文件
    • 页面中包含Audio或Video
    • POST, PUT, and DELETE XMLHTTPRequests
    • HTTP认证
    • HTTPS页面
    • 含有恶意程序的页面
    • 弹出窗口/开新窗口
    • 检查到存在高的资源消耗
    • 打开了开发者工具

看到这一串长长的清单,是否有些眩晕?在下一篇文章中,我将分析一下chrome中prerender的实现,您就会明白,看似简单的一项技术,实现起来有着诸多考虑,比如内存消耗、包含恶意网页怎么处理等等。

为了防止“脏”页面出现在用户面前,预渲染页面如果在30秒内还未被用户点击将被回收,这个时长将来也许会修改。

除非用户真正访问了预渲染页面,否则将不会出现在历史记录中,但是可缓存的资源会保留在缓存中。

调试预渲染

对于普通用户来说,并不会感知到预渲染的存在,只是感觉到点击链接的响应更快了,这是一种非常友好的用户体验。但对开发者来说,他需要知道预渲染是否在工作,下面就谈谈如何确定预渲染如预期一样工作。

检查是否在预渲染一个页面

1. 打开Chrome的任务管理器

2. 加载包含prerender标记的页面

3. 检查是否有以Prerender开头的一行,其图标也有别于其他的行的图标,如下图所示。如果找到这一行,恭喜您,prerender在工作了。

prerender_taskmanager

从Chrome 14开始,net-internals tab页包含了更多关于预渲染的信息,您可以在地址栏中输入:

chrome://net-internals/#prerender

为chromium android增加file:///android_asset/支持

出于测试的目的,我希望将一些测试页面打包到浏览器中。chromium中资源打包成pak文件,然后通过一些特殊的接口读取,而android程序则通常将资源放到assets下,通过AssetManager类来访问。在Android中提供的WebView API中,支持file:///android_asset/协议访问assets下的页面。但尝试了一下chromium for android,还没有提供,所以考虑为chromium android增加file:///android_asset支持。得益于chromium在设计上的灵活与可扩展性,增加file:///android_asset/协议支持比想象中要简单得多。

要增加新的协议支持,首先需要实现一个Interceptor(拦截器)的抽象类,该类定义于文件src/net/url_request/url_request_job_factory.h中,其中有一个重要的方法:

URLRequestJob* MaybeIntercept(URLRequest* request, NetworkDelegate* network_delegate);

实现了该抽象类后,还需要注册到URLRequestJobFactory中,注册方法为:

void AddInterceptor(Interceptor* interceptor);

让人感到更舒服的是,chromium中android_webview中已经有参考实现,所以只需把相关的实现(android_protocol_handler.cc, android_stream_reader_url_request_job.cc, AndroidProtocolHandler.java等文件)搬过来,然后在合适的位置注册到URLRequestJobFactory就可以了。