• Chrome高性能的秘密:Chrome的网络模块

    怎样才算”够快”?
    服务器君一共花费 7.468 ms 进行了 4 次数据库查询,努力地为您提供了这个页面。
    广告很萌的

    前面小节已经提到,打开一个网页,其中 80% 的时间被网络延迟占去了。

    怎样才算”够快”?

    前面可以看到服务器响应时间仅是总延迟时间的 20%,其它都被 DNS,握手等操作占用了。过去用户体验研究( user experience research )表明用户对延迟时间的不同反应:

    • 0 – 100ms 迅速
    • 100 – 300ms 有点慢
    • 300 – 1000ms 机器还在运行
    • 1s+ 想想别的事……
    • 10s+ 我一会再来看看吧…

    上表同样适用于页面的性能表现:渲染页面,至少要在 250ms 内给个回应来吸引住用户。这就是简单地针对速度。从 Google, Amazon, Microsoft,以及其它数千个站点来看,额外的延迟直接影响页面表现:流畅的页面会吸引更多的浏览、以及更强的用户吸引力(engagement) 和页面转换率(conversion rates).

    现在我们知道了理想的延迟时间是 250ms,而前面的示例告诉我们,DNS Lookup, TCP 和 SSL 握手,以及 request 的准备时间花去了 370ms, 即便不考虑服务器处理时间,我们也超出了 50%。

    对于绝大多数的用户和网页开发者来说,DNS, TCP,以及 SSL 延迟都是透明,很少有人会想到它。这也就是为什么 Chrome 的网络模块那么的复杂。

    我们已经识别出了问题,下面让我们深入一下实现的细节。

    深入 Chrome 的网络模块

    关于多进程架构

    Chrome 的多进程架构为浏览器的网络请求处理带来了重要意义,它目前支持四种不同的执行模式( four different execution models ).

    默认情况下,桌面的 Chrome 浏览器使用 process- per-site 模式, 将不同的网站页面隔离起来, 相同网站的页面组织在一起。举个简单的例子: 每个 tab 独立一个进程。从网络性能的角度上说,并没什么本质上的不同,只是 process-per- tabl 模式更易于理解。

    每一个 tab 有一个渲染进程(render process),其中包括了用于解析页面(interpreting)和排版(layout out)的 WebKit 的排版引擎(layout engine), 即上图中的 HTML Render。还有 V8 引擎和两者之间的 DOM Bindings,如果你对这部分很好奇,可以看这里( great introduction to the plumbing )。

    每一个这样的渲染进程被运行在一个沙箱环境中,只会对用户的电脑环境做极有限的访问–包括网络。而使用这些资源,每一个渲染进程必须和浏览内核 进程(browser[kernel] process)沟通,以管理每个渲染进程的安全性和访问策略(access policies)。

    进程间通讯(IPC)和多进程资源加载

    渲染进程和内核进程之间的通讯是通过 IPC 完成的。在 Linux 和 Mac OS 上,使用了一个提供异步命名管道通讯方式的 socketpair ()。每一个渲染进程的消息会被序列化地到一个专用的I/O线程中,然后再由它发到内核进程。在接收端,内核进程提供一个过滤接口(filter interface)用于解析资源相关的 IPC 请求( ResourceMessageFilter ), 这部分就是网络模块负责的。

    这样做其中一个好处是所有的资源请求都由I/O进程处理,无论是 UI 产生的活动,或者网络事件触发的交互。在内核进程(browser/kernel process)的I/O线程解析资源请求消息,将转发到一个 ResourceDispatcherHost 的单例(singleton)对象中处理。

    这个单例接口允许浏览器控制每个渲染进程对网络的访问,也能达到有效和一致的资源共享:

    • Socket pool 和 connection limits:浏览器可以限定每一个 profile 打开 256 个 sockets, 每个 proxy 打开 32 个 sockets, 而每一组{scheme, host, port}可以打开 6 个。注意同时针对一组{host,port}最多允计打开 6 个 HTTP 和 6 个 HTTPS 连接。
    • Socket reuse:在 Socket Pool 中提供持久可用的 TCP connections,以供复用。这样可以为新的连接避免额外建立 DNS、TCP 和 SSL (如果需要的话)所花费的时间。
    • Socket late-binding (延迟绑定):网络请求总是当 Scoket 准备好发送数据时才与一个 TCP 连接关连起来,所以首先有机会做到对请求有效分级(prioritization),比如,在 socket 连接过程中可能会到达到一个更高优先级的请求。同时也可以有更好的吞吐率(throughput),比如,在连接打开过程中,去复用一个刚好可用的 socket, 就可以使用到一个完全可用的 TCP 连接。其实传统的 TCP pre-connect (预连接)及其它大量的优化方法也是这个效果。
    • Consistent session state (一致的会话状态): 授权、cookies 及缓存数据会在所有渲染进程间共享。
    • Global resource and network optimizations (全局资源和网络优化):浏览器能够在所有渲染进程和未处理的请求间做更优的决策。比如给当前 tab 对应的请求以更好的优先级。
    • Predictive optimizations (预测优化):通过监控网络活动,Chrome 会建立并持续改善预测模型来提升性能。

    项目还在增加中。

    单就一个渲染进程而言,透过 IPC 发送资源请求很容易,只要告诉浏览器内核进程一个唯一 ID,后面就交给内核进程处理了。

更多 推荐条目

Welcome to NowaMagic Academy!

现代魔法 推荐于 2013-02-27 10:23   

本章最新发布
随机专题
  1. [PHP程序设计] 声明式编程范式 12 个条目
  2. [PHP程序设计] PHP里的布尔类型 3 个条目
  3. [智力开发与知识管理] 整体性学习步骤 9 个条目
  4. [运维管理] 路由器与交换机 4 个条目
  5. [PHP程序设计] 编程范式初探 3 个条目
  6. [移动开发] Layout_weight属性解析 5 个条目
  7. [PHP程序设计] PHP与Stream流 5 个条目
  8. [移动开发] Android Studio的使用技巧 4 个条目
  9. [Python程序设计] Tornado源码解析 23 个条目
  10. [PHP程序设计] Nginx基本操作释疑 7 个条目
  11. [移动开发] 从代码角度去认识 Activity 4 个条目
  12. [Python程序设计] urls.py设置技巧 8 个条目
窗口 -- [资讯]