前一篇博文已经介绍通过prefetch预先加载网页的资源来提升网页加载速度,下面我们一起来看一下网页加速之chromium prerendering.在介绍prerendering之前,先介绍两个概念:
1.PLT(page load time) :用户浏览网页触发浏览器内核 onPageStarted 到onPageFinished即网页开始到完成的时间。
2.PPLT(perceived page load time):用户可感知的网页加载时间,从用户发起页面加载请求到页面呈现。
背景:
什么是prerendering ?
有时候网站会预测用户下一步会点哪个链接, 比如用户在阅读有几页新闻,那用户阅读完当前的页面很有可能会点击下一页继续新闻阅读.浏览器如果能提前获取下一页资源或者准好下一页所有资源那么当用户点击下一页时页面能立即呈现到用户面前,这是个相当酷的体验。 用户的下一页能立即显示就是通过prerendering技术实现的。prerendering
扩展prefetching概念, 不仅仅预先获取顶层的资源, prerendering 会预先在后台准备下一个页面所需要的所有资源。Prerending的行为有点像我们open behind(后台打开页面) ,当我们把后台页面切换到前台时能立即显示网页。"background tab" 用户是完全不可见的, 当用户要切换到这个background 页面时, 后面的background tab 会被swap到前段, 这样用户能立即看到网页信息。
在chrome 17版本开始支持prerendering, 网页前端开发者可以使用prerendering来提升页面体验. chrome本身自己会在地址栏上智能prerendering.
触发prerendering语法
<span style="font-size:14px;"><link rel="prerender" href="http://www.cmcm.com"> prerendercmcm </link></span>
prerendering 触发方式很像firefox的prefetching 也是一个HTML中得<link> tag,但是chrome的 prerendering 不支持 meta-http和 hettp header触发。
当chrome邂逅这个标记时,它会记录这个页面,并在特定时机生成后台页面.
浏览器如何prerendering & prerendering时机
prerendering和prefetching有一点很大不同的是,prerendering如果你网页不想触发,chrome浏览器也会帮你在合适的时机触发,比如chrome的智能地址栏. 支持prerendering浏览器会在HTML parse阶段当发现tag包含"prerender" 则会创建PrerenderHandler,并添加任务到PrerenderDispatcher中,PrerenderDispatcher会发送一个消息到主进程把任务加到prerender任务列表中。
使用prerendering 限制与开关
为了防止过期数据以及资源浪费,chrome对prerender的页面设置有效期,当后台页面被创建出来后,30ms内没被使用,则会丢弃这个后台页面,这个有效期在后面的chrome版本有可能会变化。
下面是一些prerendering不能触发的场景:
1) 初始化下载
2) 视频、音频页面
3) XMLPHTTPRequests 的 post,put,delete
4) HTTP 认证
5) HTTPS 页面
6) Pop window
7) 大页面需要加载很多资源
8) 开发中模式下
前面提到chrome会在地址栏上进行prerender, chrome也提供开关,让用户选择是否开启这个功能。关闭这个功能可以从地址栏上输入--prerender-from-omnibox=disabled
.
探测一个网页是否正在被prerender
1)打开Chrome Task Manager(Chrome浏览器右上角三个点工具栏--->工具--->任务管理器)
2)加载一个包含prerender的页面
3)在Chrome Task Manager中如果看到prerender打头的任务,说明你的页面正在被prerender。
Prerender性能测试
测试环境:
小米2
Android 4.1.1
chrome 浏览器
site/page load time |
enable prerendering |
none prerendering |
improve(%) |
www.cmcm.com |
instant page |
9470 |
100 |
www.taobao.com |
instant page |
1112 |
100 |
Prerender 在chromium中的实现
Prerendering 在解析网页过程中包含<link rel="prerender"> elements 则会触发prerendering。后台页面会被创建用来prerendered url,这个后台页面会加载所有资源,包含可执行的javascript。当用户访问prerendered页面时, 后台页面会被swap到前台。下面我们看一下chromium prerender过程。
内核解析HTML过程中会触发HTMLLinkElement 的parseAttribute方法, 如果页面中包含<link rel="prerender"> 会记录状态,在process()方法中调用LinkLoad--->loadLink方法 创建PrerenderHandle的对象,在chromium当中这些都是在渲染进程中完成,chromium的prerender 管理是在主进程中,这时PrerenderHandle对象会向主进程发送一个请求PrerenderHostMsg_AddLinkRelPrerender,把这个link相关的信息发送到主进程加入到prerenderManager管理列表中。
当chromium主进程收到PrerenderHostMsg_AddLinkRelPrerender时,会检测当前是否有过多的渲染进程,如果已经有相同的任务在进行则不做处理,反之就会对接收到的url进行prerender,在android上由于有限的资源限制会重用prerendering使用的process,
为了回收资源chromium会在此启动一个计时器来销毁未被使用的prerender 后台页面。在chromium35版本中定时器时间是1000毫秒(ms) 在早期的chromium实现当中是30ms,当然这个数值未来还会发生变化。
相关代码路径:
third_party/WebKit/Source/core/html/LinkRelAttribute.cpp : 负责解析网页的tags 并设置属性状态,"prerender“ 在此解析
./third_party/WebKit/Source/core/loader/LinkLoader.cpp :负责管理连接资源加载,创建维护prerenderHandle对象
third_party/WebKit/Source/core/html/HTMLLinkElement.cpp : 负责解析HTML链接信息
chrome/browser/prerender/prerender_manager.cc : 负责管理prerender, 触发开始,结束,丢弃,取消
chrome/browser/prerender/prerender_message_filter.cc :负责prerender相关消息的调度处理
third_party/WebKit/Source/core/loader/PrerenderHandle.cpp :负责Prerender的处理基础单元,维护一个prerender task的基础信息包含url, detach状态
参考资料地址:
http://www.chromium.org/developers/design-documents/prerender
https://developers.google.com/chrome/whitepapers/prerender?hl=zh-CN
转载请说明出处, 谢谢! 欢迎共同探讨.
http://blog.csdn.net/typename/article/details/38536167 powered by miechal zhao.
网页加速之Chromium 预加载 Prerendering,布布扣,bubuko.com
网页加速之Chromium 预加载 Prerendering
原文:http://blog.csdn.net/typename/article/details/38536167