欢迎光临
我们一直在努力

高性能的秘密:预连接、预加载与预渲染 预下载与预渲染

高性能的秘密:预连接、预加载与预渲染 预下载与预渲染
对于页面来说,其实没什么预下载,预预渲,浏览器都是分析页面代码,然后向服务器读取相关图片、文件等等。所谓的预下载预渲染,要么用ajax方式异步读取异步刷新,要么就是页面在前部先显示一个信息,在尾部再用相关内容替换掉预显示的信息。所有的技术手段是让浏览者的体验好点而已。
所以具体那个url是预下载、预渲染,只要你分析下页面代码以及抓一下url获取顺序,大概就知道了。
运行在渲染进程中的 WebKit 文档解析器(document parser), 会为当前页面上所有的链接提供一个主机名(hostname)列表,Chrome 可以选择是否提前解析。 当用户要打开页面时,渲染进程先会触发一个鼠标悬停(hover)或按键(button down)事件。

Omnibox 可能会针对一个高可能性的建议页面发起解析请求。

Chrome Predictor 会基于过往浏览记录和资源请求数据发起主机解析请求。(下面会详细解释。)

页面本身会显式地要求 Chrome 对某些主机名称进行预解析。

上述各项对于 Chrome 都只是一个线索。 Chrome 并不保证预解析一定会被执行,所有的线索会由 Predictor 进行评估,以决定后续的操作。最坏的情况下,可能无法及时解析主机名,用户就必须等待一个 DNS 解析时间,然后是 TCP 连接时间,最后是资源加载时间。Predictor 会记下这个场景,在未来决策时相应地加以参考。总之,一定是越用越快。

之前提过到 Chrome 可以记住每个页面的拓扑(topology),并可以基于这个信息进行加速。还记得吧,平均每个页面带有 88 个资源,分别来自于 30 多个独立的主机。每打开这个页面,Chrome 会记下资源中比较常用的主机名,在后续的浏览过程中,Chrome 就会发起针对某些主机或者全部主机的 DNS 解析,甚至是 TCP 预连接。

除了内部事件通知外,页面设计者可以在页面中嵌入如下的语句请求浏览器进行预解析:

之所以有这个需求,一个典型的例子是重定向(redirects)。Chrome 本身没办法判断出这种模式,通过这种方式则可以让浏览器提前进行解析。

具体的实现也是因版本而有所差异,总体而言,Chrome 中的 DNS 处理有两个主要的实现:

基于历史数据(historically), 通过调用平台无关的 getaddrinfo ()系统函数实现。
代理操作系统的 DNS 处理方法,这种方法正在被 Chrome 自行实现的一套异步 DNS 解析机制(asynchronous DNS resolver)所取代。
依赖于系统的实现,代码少而且简单,但是 getaddrInfo()是一个阻塞式的系统调用,无法有效地并行多个查询操作。经验数据还显示,并行请求过多甚至会超出路由器的负额。 Chrome 为此设计了一个复杂的机制。对于其中带有 worker-pool 的预解析, Chrome 只是简单的发送 getaddrinfo() 调用, 同时阻塞 worker thread 直到收到响应数据。因为系统有 DNS 缓存的原因,针对解析过的主机,解析操作会立即返回。 这个过程简单,有效。

但还不够, getaddrinfo()隐藏了太多有用的信息,比如 Time-to-live (TTL)时间戳, DNS 缓存的状态等。于是 Chrome 决定自己实现一套跨平台的异步 DNS 解析器。
使用预渲染优化页面浏览
前面讨论的每个优化都用来帮助减少用户发起请求到看到页面内容的延迟时间。多快才能带来即时呈现的体验呢?基于用户体验数据,这个时间是 100 毫秒,根本没给网络延迟留什么空间。而在 100 毫秒内,又怎样渲染页面呢?

大家可能都有这样的体验:同时开多个页签时会明显快于在一个页签中等待。浏览器为此提供了一个实现方式:

这就是 Chrome 的预渲染(prerendering in Chrome)! 相对于只下载一个资源的“prefetch”, “prerender”会让 Chrome 在一个不可见的页签中渲染一个页面,包含了它所有的子资源。当用户要浏览它时,这个页签被切到前台,做到了即时的体验。

可以浏览 prerender-test.appspot.com 来体验一下效果,再通过 chrome://net-internals/#prerender 查看下历史记录和预连接页面的状态。

因为预渲染会同时消耗 CPU 和网络资源,因些一定要在确信预渲染页面会被使用到情况下才用。Google Search 就在它的搜索结果里加入 prerender, 因为第一个搜索结果很可能就是下一个页面(也叫作 Google Instant Pages)。

你可以使用预渲染特性,但以下限制项一定要牢记:

所有的进程中最多只能有一个预渲染页。 HTTPS 和带有 HTTP 认证的页面不可以预渲染。
如果请求资源需要发起非幂等(non-idempotent,idempotent request 的意义为发起多次,不会带来服务的负面响应的请求)的请求(只有 GET 请求)时,预渲染也不可用。
所有的资源的优先级都很低。
页面渲染进程的使用最低的 CPU 优先级。
如果需要超过 100MB 的内存,将无法使用预渲染。
不支持 HTML5 多媒体元素。
预渲染只能应用于确信安全的页面。另外 JavaScript 也最好在运行时使用 Page Visibility API 来判断一下当前页是否可见(参考 you should be doing anyway)。

赞(0)
未经允许不得转载:福利吧|福利社|fuliba » 高性能的秘密:预连接、预加载与预渲染 预下载与预渲染

相关推荐

  • 暂无文章