《Chromium内核原理之blink内核工作解密》
《Chromium内核原理之多进程架构》
《Chromium内核原理之进程间通信(IPC)》
《Chromium内核原理之网络栈》
《Chromium内核原理之网络栈HTTP Cache》
《Chromium内核原理之Preconnect》
《Chromium内核原理之Prerender》
《Chromium内核原理之cronet独立化》
1.概要
2.基础机制2.1 创建预渲染页面
2.2 使用预渲染页面
2.3 可见性API3.最大限度地减少资源争用
4.处理动态媒体4.1 插件延期
4.2 HTML5 media elements5.取消角球案件
6.共享本地存储的突变
7.最小化服务器端效应
8.重定向后
1.概要
预渲染是Chrome中的一项功能,可以改善用户可见的页面加载时间。预渲染由引用页面中的<link rel =“prerender”>元素触发。为预渲染的URL创建一个隐藏页面,该页面将完全加载所有相关资源,以及执行Javascript。如果用户导航到该页面,则隐藏页面将被交换到当前选项卡中并使其可见。
blink_prerender.jpg
尽管预渲染的核心是对Chrome的一个相当简单的改变,但是有许多问题会使实现变得更加复杂:
- 最大限度地减少资源争用。
- 处理动态媒体[视频,音频,插件,画布]
- 在某些角落案件中取消页面。
- 最小化服务器端效应。
- 共享本地存储的变异[cookies,sessionStorage等]
2.基础机制
2.1 创建预渲染页面
当页面包含<link rel =“prerender”>资源时,将启动Prerender。 ResourceDispatcherHost使用ResourceType :: Prerender接收资源请求 - 但此请求永远不会发送到网络。相反,它被用作创建PrerenderContents的信号,并且请求本身被取消。
PrerenderContents存储在PrerenderManager中,PrerenderManager维护由同一个配置文件创建的所有PrerenderContents的目录。允许少量最近创建的PrerenderContents。当前实现仅保留一页最多30秒,但这可能在将来发生变化。修剪较旧的页面,如果已达到容量,则使用最近最少创建的逐出算法。
2.2 使用预渲染页面
有两种情况可以使用预渲染页面而不是新页面加载:
- 在对TabContents :: NavigateToPending条目的调用中,该条目被触发,例如当用户键入要访问的新URL时。
- 在对TabContents :: DidNavigate的调用中,在用户单击当前页面上的链接时执行该操作。
在这两种情况下,都会检查当前配置文件的PrerenderManager以查看有效的PrerenderContents是否与目标URL匹配。如果找到匹配,则:
- PrerenderContents从PrerenderManager中删除,因此只能使用一次。
- PrerenderContents的TabContentsWrapper使用TabContents委托ReplaceAt机制交换现有的TabContentsWrapper。
- 旧的TabContentsWrapper保持活动状态,直到卸载处理程序完成运行,然后被销毁。
2.3 可见性API
添加了页面可见性API以公开网页的当前可见性状态,例如它是预呈现,隐藏还是可能可见。
有关建议的API,请参见http://w3c-test.org/webperf/specs/PageVisibility/。请注意,当前实现添加了webkit前缀,因为API可能仍会更改。
这可以用于各种目的,例如在游戏不可见时降低游戏的音量,或暂停一个简介序列,直到页面转换出预渲染状态。
3.最大限度地减少资源争用
由于资源争用,预渲染可能会对其他页面的页面加载时间产生负面影响。虽然其中一些问题也与现有的预取支持有关,但预渲染会使问题的可能性更加严重:将获取更多资源,因为还会检索子资源,而不仅仅是顶级页面;并且CPU和内存消耗可能会更高。
为了最小化网络争用,以最低优先级检索预渲染页面中的所有资源。目前,优先级仅用于为特定域订购待处理请求:如果根本没有活动网络请求,则调度可能需要针对此优先级进行更改以仅允许空闲请求。当更高优先级的请求出现时,目前无法取消活动连接 - 这可能是需要的,因此预先存在的长期推测请求不会阻止用户在同一域上主动访问的页面的请求。最后,在请求开始后无法更改资源优先级 - 在页面从预呈现转换为可见之后,可能需要提高请求的优先级。
通过将预渲染页面的数量限制为仅3(每页最多2个)来处理内存利用率,并且如果在预渲染时系统上没有足够的可用RAM,则会限制内存利用率。此外,如果页面的内存超过150 MiB,则取消预渲染并将内存返回给系统。
通过降低包含预渲染页面的渲染过程的优先级来处理CPU利用率。仅当可以将预呈现页面分配给唯一进程时,才会创建预呈现页面,这样可以最大限度地降低包含活动选项卡的渲染进程优先级降低的可能性。
目前尚未处理最小化GPU利用率。一个问题是GPU使用是根据渲染过程而不是每个RenderView来测量的。
目前尚未处理最小化磁盘缓存利用率。磁盘缓存当前不是基于优先级的。此外,由于插入了更多未使用的资源,对于启用了预渲染的用户,缓存命中率可能会随着时间的推移而降低。磁盘高速缓存的逐出算法也可能需要改变以更积极地逐出推测性地检索但从未使用过的资源。
如果预渲染页面试图预渲染另一个页面,则所请求的预渲染将被推迟,直到并且除非第一个预渲染器导航到。
如果在5分钟内不使用,预毁器将被销毁。如果需要,源页面可以提前取消预渲染。
4.处理动态媒体
4.1 插件延期
当页面处于预呈现状态时,插件实例化(和加载)将被延迟,直到页面被激活。主要原理是在用户实际查看页面之前阻止音频或视频媒体播放,以及最小化可能的漏洞利用表面。
为原始页面上的每个插件元素创建一个BlockedPlugin实例。这与“即点即用”功能使用的实例相同。它在原始预期插件的位置放置了一个简单的填充插件,并保留了正确创建和初始化原始插件所需的参数。当页面转换出预呈现状态时,为预呈现目的而创建的所有BlockedPlugin实例将交换最初预期的插件。
4.2 HTML5 media elements
页面完成后播放延迟,类似于插件。
5.取消角球案件
如果发生任何情况,页面将被取消:
- 顶级页面不是HTTP / HTTPS方案,无论是在初始链接上还是在任何服务器端或客户端重定向期间。例如,两个ftp都被取消。允许内容脚本在预呈现的页面上运行。
- 页面导航到时,window.opener将为非null。
- 下载被触发。下载在开始之前被取消。
- 发出的请求不是GET,HEAD,POST,OPTIONS或TRACE。
- 将出现身份验证提示。
- 请求SSL客户端证书,并要求用户选择证书。
- 脚本尝试打开一个新窗口。
- 调用alert()。
- window.print()被调用。
- 页面上的任何资源都被安全浏览标记为恶意软件或网络钓鱼。
- 页面上的片段与导航到的位置不匹配。
当检测到问题时,同步完成取消,并且通常停止违规行为。例如,XmlHttpRequest PUT将在它通过网络之前取消请求,并阻止页面被交换。由于RenderView取消的异步性质,预渲染页面可能会存在一段时间,但它不会互换了。
附加行为可能导致将来取消,并且将来可能放松一些现有的取消原因。
6.共享本地存储的突变
共享本地存储(如DOM存储,IndexedDB和HTTP cookie)对预呈现提出了挑战。理想情况下,在用户激活页面之前,预渲染页面所做的突变不应对其他选项卡可见。其他页面所做的突变应反映在预呈现页面中,该页面可能已在其他页面进行更改之前从本地存储中读取。
一种选择是不要担心这些问题。由于预渲染页面仅在创建后的短时间内保留,因此类似竞赛条件的窗口相当短。但是,这可能会导致用户混淆(例如,如果为页面启动预渲染,则用户在主页面上注销,然后使用用户的旧凭据将预渲染页面变为活动状态)。此外,Visibility API提供了页面在页面变为可见之后推迟任何变异行为的方法。这是Chrome目前采用的方法。
第二种选择是在访问本地存储时取消预渲染。这可能适用于更新版本的本地存储[例如IndexedDB],但不适用于更常见的方案,尤其是HTTP cookie。长期来看,取消预渲染方法也会导致采用新形式的本地存储的阻力。
第三种选择是在页面预呈现时拥有本地存储沙箱,并在页面激活时尝试以事务方式将更改提交到共享本地存储。有关如何为Cookie执行此操作的一些想法,请参阅https://sites.google.com/a/chromium.org/dev/developers/design-documents/cookies-and-prerender。
7.最小化服务器端效应
只有在使用GET检索顶级页面时才会触发预呈现,并且假定它是幂等的。此外,来自XmlHttpRequests的任何非GET,HEAD,TRACE,POST或OPTIONS请求都不会通过网络发送,并且页面将被取消。
8.重定向后
如果服务器发送了一个子资源的重定向响应,其中包含“Follow-Only-Pre-Prerender-Shown:1”标题,则Chrome将暂停跟随重定向并获取相应的子资源,直到向用户显示预呈现。
网友评论