宏观视角下的浏览器

272 阅读7分钟

线程和进程

  • 线程VS进程

    线程是不能单独存在的,它是由进程来管理和启动的。一个进程就是一个程序的运行实例。【启动一个程序的时候,操作系统会为该程序创建一块内存用来存放代码,运行中的数据和一个执行任务的主线程,我们把这样的一个运行环境叫进程】

    image.png

  • 线程和进程的关系

    1. 进程中任意一线程执行出错,都会导致整个进程的崩溃
    2. 线程之间共享进程中的数据
    3. 当一个进程关闭的时候,操作系统会回收进程所占用的内存
    4. 进程之间的内容互相隔离
  • 最新的Chrome浏览器【多线程架构】

    1. 1个浏览器(Browser)主进程:主要负责界面显示、用户交互、子进程管理同时提供存储等功能
    2. 1个GPU进程:实现初衷为了实现3DCSS,所以现在提倡先开GPU
    3. 1个网络(NetWork)进程:主要负责页面的网络资源加载
    4. 多个渲染进程:核心任务是将HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎Blink和JavaScript引擎都是运行在该进程中,默认情况下Chrome会为每个Tab标签创建一个渲染进程,出于安全考虑渲染进程都是运行在沙箱模式下。
    5. 多个插件进程:主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响。

image.png

  • 页面崩溃的原因

    1. 一些第三方插件注入浏览器或页面进程,拦截了网页的一些正常操作而导致页面或者浏览器崩溃,如一些杀毒软件等
    2. 插件,虽然容易崩溃,但是通常情况下只会影响到自身的进程,不过我们以前的统计数据来看,也会小概率地影响到页面的崩溃,不过整体数据来看还好了。另外一个方向来看,插件的使用率已经越来越低了,所以插件不是个大问题
    3. 浏览器的一些bug,如渲染引擎,JavaScript引擎等,不过从统计数据来看,这类因素导致的崩溃也是越来越低的了,而且随着浏览器的更新升级,引起问题的因素也是在不断变化的
  • UA 【UserAgent】

    1. UA是浏览器的身份证,通常,在发送HTTP请求时,UA会附带在HTTP的请求头中user-agent字段中,这样服务器就会知道浏览器的基础信息,然后服务器会根据不同的UA返回不同的页面内容,比如手机上返回手机的样式,PC就返回PC的样式。
    2. 查看UA使用window.navigator.userAgent查看当前浏览器UA信息
    3. UA改写一般是对接原生,原生同学写入我们获取,web端不修改UA

TCP协议(如何保证页面文件能被完整送达浏览器?)

  • IP:把数据包送达目的主机

  • TCP: 把数据完整地送达应用程序

    一个完整的TCP连接生命周期包括“建立连接“,”传输数据“,”断开链接“。TCP为了保证数据传输的可靠性,牺牲了数据包的传输速度吗,因为“三次握手”和“数据包校验机制”等把传输过程中的数据包的数量提高了一倍

  • DNS IP地址是数字标识,比如39.106.233.176难以记忆,所以基于这个需求又出现了一个服务,负责把域名和IP地址做一一映射关系,这套域名映射为 IP 的系统叫做“域名系统”为DNS

HTTP请求流程

  • 浏览器发起HTTP请求流程

    1、构建请求 2、查找缓存 3、准备IP地址和端口 4、等待TCP队列 5、建立TCP连接 6、发送HTTP请求

  • 服务端处理HTTP请求流程

    1、返回请求 2、断开连接 3、重定向

  • 为什么很多站点第二次打开速度会更快

    主要是DNS缓存和页面资源缓存,具体的浏览器缓存如下

下载.png

  • HTTP请求示意图

下载 (1).png

从输入URL到页面展示,这中间发生了什么?

  • 用户输入

    当用户在地址栏输入一个查询关键字,地址栏会判断输入的关键字是搜索内容,还是请求的URL。 如果是搜索内容,地址栏会使用浏览器默认的搜索引擎,来合成新的带搜索内容的url,如果判断输入的内容符合URL规则,比如输入的是time.geekbang.org,那么地址栏会根据规则,把这段内容加上协议,合成完整的url,当浏览器开始加载一个地址之后,标签页上的图标便进入了加载状态。

  • URL 请求过程

    1. 查找缓存:网络进程会查找本地缓存是否缓存了该资源,如果有缓存资源,直接返回资源给浏览器进程,如果没有查到资源,那么直接进入网络请求流程
    2. DNS解析:通过DNS的一一映射关系,查找IP地址
    3. 重定向:在接收到服务器的响应头后,网络进程开始解析响应头,如果发现状态码是301,302,网络进程会从响应头的Location字段里读取重定向地址,发起新的http或者https的请求,重头开始
    4. 响应数据类型处理:浏览器通过响应头中的Content-Type字段来区分是下载类型还是html页面
  • 准备渲染流程

    默认情况下,Chrome会为每个页面分配一个渲染进程,打开新的页面都会使用单独的渲染进程,如果从A页面打开B页面,并且A和B属于同一站点,那么B会复用A的渲染进程,如果其他情况,浏览器会为B创建一个新的渲染进程

  • 提交文档(文档是指URL请求的响应体数据)

    “提交文档”的信息是由浏览器进程发出的,渲染进程接收到“提交文档”的信息后,会和网络进程建立传输数据的“管道”,等文档数据传输完成后,渲染进程会返回“确认提交”的信息给浏览器进程,浏览器进程接收到信息后,会更新浏览器界面状态,包括安全状态,地址栏url,前进后退的历史状态,并且更新web页面

  • 渲染阶段

    1. 构建DOM树(二叉树):DOM是保存在内存中的树状结构,可以通过JS来查询和修改其内容 下载 (1).png

    2. 样式计算:先把css转化为浏览器能理解的结构即样式表(document.styleSheets 来查看样式表);转化样式表的属性值让其标准化(把em,bold,blue等转化);计算dom树中每个节点的具体样式(css的继承规则和层叠规则)这个阶段最终输出的内容是每个 DOM 节点的样式,并被保存在 ComputedStyle 的结构内。

    3. 布局阶段: 创建布局树 下载 (2).png

    4. 分层: 渲染引擎为特定的节点生成专用的图层,并生成一颗对应的图层树(3D变换,页面滚动,z-index的层级)可以在谷歌浏览器中Layers标签中查看

    5. 图层绘制(Paint)

    6. 栅格化操作(生成视口可见的位图) 下载 (3).png

    7. 合成和显示(提交命令给浏览器进程)

    8. 渲染总结总图

下载 (4).png

  1. 渲染进程将 HTML 内容转换为能够读懂的DOM 树结构。
  2. 渲染引擎将 CSS 样式表转化为浏览器可以理解的styleSheets,计算出 DOM 节点的样式。
  3. 创建布局树,并计算元素的布局信息。
  4. 对布局树进行分层,并生成分层树
  5. 为每个图层生成绘制列表,并将其提交到合成线程。
  6. 合成线程将图层分成图块,并在光栅化线程池中将图块转换成位图。
  7. 合成线程发送绘制图块命令DrawQuad给浏览器进程。
  8. 浏览器进程根据 DrawQuad 消息生成页面,并显示到显示器上。