应该有很多前端开发人员都思考过这么一个问题:从输入 URL 到页面加载完成,中间都做发生了什么?

这个问题涉及的面非常广,每个涉及的点又很深入。从触屏/键盘如何到 CPU?CPU 如何到系统内核?如何从操作系统 GUI 到浏览器?浏览器如何向网卡发送数据?数据如何从本机网卡发送到服务器?服务器接收数据后如何处理?服务器返回数据后浏览器如何处理?浏览器如何将页面展现出来?等等等等,每一个过程都包含了大量且深入的知识体系,很难一以贯通。

但作为前端开发人员,浏览器是我们的主要工具之一,浏览器是如何将页面展现出来的则是我们更关注的部分。因此本文就从一些基本流程来简要描述这个过程。

从上面这个图中可以发现,虽然使用的 Javascript 是单线程语言,但浏览器本身是多进程的。

但是这并不是从一而终的状态,而是浏览器从早期的单进程结构逐渐发展发展而来。现代浏览器各进程根据负责的功能不同,分为浏览器进程、渲染器进程、网络进程、GPU 进程、缓存进程、插件进程等等。为了更好的理解浏览器页面的呈现过程,我们以最主流的 Chrome 为例,简要的说明一下各个进程的大致职能:

  • 浏览器进程: 负责控制界面展示、用户交互、子进程管理等功能。

  • 渲染器进程: 负责将 HTML\CSS\JS 转化为用户可以与之交互的网页。渲染引擎如 webkit、blink 和 JS 引擎 V8 都是在该进程之中。

  • GPU 进程: GPU 进程原本是为了实现 3D CSS 效果,但是随后页面、Chrome 的 UI 都采用 GPU 来绘制,是 GPU 成为了重要需求,于是增加了 GPU 进程。

  • 网络进程: 负责页面的网络资源加载。

  • 插件进程:负责插件的运行,由于插件可能崩溃,需要插件进程其他进程隔离。注意,插件并不是我们常用的浏览器拓展,plugin 和 extension 是不同的。

  • 缓存进程:负责处理页面资源缓存和清理。

我们本次需要重点关注的是渲染器进程。

回到问题,当我们在浏览器地址栏输入地址时,浏览器进程的 UI 线程会捕捉输入内容,如果访问的是网址,那么 UI 线程会启动一个网络线程来构建请求(这里我们暂时不考虑缓存,缓存又是另外一个故事了),它请求 DNS 进行域名解析然后连接服务器获取数据。如果我们输入的是关键词,浏览器则使用默认配置的搜索引擎来搜索。在获取到数据并通过安全校验后,网络线程会通知 UI 线程数据准备完毕,然后UI线程创建一个渲染器进程来进行页面的渲染,并将数据通过 IPC 管道传递给渲染器进程。

至此,我们的主角渲染器进程登场!

解析 HTML

渲染器进程接收到的是一个 HTML,需要把 HTML 解析成 DOM 数据结构。因为直接的 HTML 字节流是无法被渲染引擎所理解的,必须转化成可以理解的内部结构。这个内部结构就是 DOM,DOM 提供了对 HTML 文档的结构化表述。在渲染引擎中,DOM 有三个层面的作用:

  • 从页面角度:DOM 是生成页面的基础数据结构。

  • 从 js 角度:DOM 提供了 js 操作的接口。通过这套接口,js 可以对 DOM 接口进行访问,从而使开发者拥有改变文档结构、样式、内容的能力。

  • 从安全角度:DOM 是 HTML 经过解析的内部数据结构,它将 web 页面和 js 链接起来,并过滤了一些不安全的内容。

渲染器进程内部使用 HTML Parser 将 HTML 解析成 DOM 结构。需要注意的是,HTML 解析器不会等待整个 HTML 文档加载完毕再去解析,而是加载多少了多少 HTML,就解析多少。

那么 HTML 字节流是如何转换成 DOM 的呢?

其实和 V8 解析 js 类似,也是做词法分析,通过分词器将字节流成功成一个个 token,包括 Tag token 和文本 token。HTML 解析器维护了一个 token 栈结构,token 会按照对应顺序入栈出栈,然后将 token 解析成 DOM 节点,并将 DOM 节点添加进 DOM 树中。

前面提到生成 DOM 可以过滤一些不安全内容。这主要是渲染引擎中的一个名为XSSAuditor 安全检查模块实现的。它会监测词法安全,在分词器解析出 token 之后,检查这些模块是否引用了外部脚本,是否符合 CSP 规范,是否存在跨站点请求等。如果出现不符合规范的内容。XSSAuditor 会对该脚本或下载任务进行拦截。

DOM 树在构建过程中会创建 document 对象,然后以 document 为根节点的 DOM 树不断修改向其中添加新的元素。

解析 CSS

前面已经将 HTML 解析成 DOM 树了,但是光拥有 DOM 树还不足以让我们知道页面的样貌。因为我们肯定会为页面设置一些样式。因此主进程还会解析页面中的 CSS 从而确定每个 DOM 节点的计算样式(computed style)。

CSS 的样式来源主要有三个:

  • 通过 link 引用的外部 CSS 文件

  • 使用

简略图解:输入 url 到出现页面,浏览器做了什么?的更多相关文章

  1. 关于浏览器,从输入URL到呈现页面过程!(主讲TCP/IP协议)

    一.文本对话--从请求到响应 我们在浏览器中输入一个 URL,回车之后便会在浏览器中观察到页面内容.实际上这个过程是: (1)浏览器向网站所在的服务器发送了一个 Request(请求) (2)网站服务 ...

  2. 浏览器输入URL到响应页面的全过程

    B/S网络架构从前端到后端都得到了简化,都基于统一的应用层协议HTTP来交互数据,HTTP协议采用无状态的短链接的通信方式,通常情况下,一次请求就完成了一次数据交互,通常也对应一个业务逻辑,然后这次通 ...

  3. 计算机网络【6】—— 从浏览器输入URL到显示页面发生了什么

    当在浏览器地址栏输入网址,如:www.baidu.com后浏览器是怎么把最终的页面呈现出来的呢?这个过程可以大致分为两个部分:网络通信和页面渲染. 一.网络通信 互联网内各网络设备间的通信都遵循TCP ...

  4. 从浏览器地址栏输入url到显示页面的步骤

      在浏览器地址栏输入URL 浏览器查看缓存,如果请求资源在缓存中并且新鲜,跳转到转码步骤 HTTP1.0提供Expires,值为一个绝对时间表示缓存新鲜日期 HTTP1.1增加了Cache-Cont ...

  5. 从浏览器地址栏输入url到显示页面的步骤(以HTTP为例)

    在浏览器地址栏输入URL 浏览器查看缓存,如果请求资源在缓存中并且新鲜,跳转到转码步骤 如果资源未缓存,发起新请求 如果已缓存,检验是否足够新鲜,足够新鲜直接提供给客户端,否则与服务器进行验证. 检验 ...

  6. 输入URL到展现页面的全过程

    最近在看一本关于网络协议的书<图解HTTP> 当我们在浏览器的地址栏输入 http://www.pwstrick.com ,然后回车,回车这一瞬间到看到页面到底发生了什么呢? 1.  域名 ...

  7. 输入URL地址到页面加载完成 过程

    在浏览器的地址栏中输入URL地址"http://www.gacl.cn:8080/JavaWebDemo1/1.jsp"去访问服务器上的1.jsp这个web资源的过程 1.浏览器根 ...

  8. HTTP:地址栏输入url到显示页面的步骤

    在浏览器地址栏输入URL 浏览器查看缓存,如果请求资源在缓存中并且新鲜,跳转到转码步骤 如果资源未缓存,发起新请求 如果已缓存,检验是否足够新鲜,足够新鲜直接提供给客户端,否则与服务器进行验证. 检验 ...

  9. 用户在浏览器输入URL回车之后,浏览器都做了什么

    在直接列出执行的步骤之前先来普及几个知识,相信了解完这些知识之后会对前后端的交互有更深入的理解. 1.TCP连接 TCP:Transmission Control Protocol, 传输控制协议,是 ...

随机推荐

  1. 线程中sleep()方法和wait()方法的前生今世

    先看再点赞,给自己一点思考的时间,如果对自己有帮助,微信搜索[程序职场]关注这个执着的职场程序员.我有什么:职场规划指导,技能提升方法,讲不完的职场故事,个人成长经验. 不知道大家有没有这种感觉,在公 ...

  2. sscanf功能详解(转)

    #include <stdio.h> #include <stdlib.h> #include <string.h> static void sscanf_test ...

  3. 远程cmd操作

    <<PSTools.zip>><<Install_PowerCmd.exe>><<cmder_mini.zip>><< ...

  4. 安装GLPI

    Centos7安装GLPI资产管理软件 系统信息 环境说明 下面的命令可以查看系统的版本信息,本次使用的是centos7 cat /etc/redhat-release uname -a IP地址信息 ...

  5. Java中为什么notify()可能导致死锁,而notifyAll()则不会(针对生产者-消费者模式)

    1.先说两个概念:锁池 和 等待池 锁池:假设线程A已经拥有了某个对象(注意:不是类)的锁,而其它的线程想要调用这个对象的某个synchronized方法(或者synchronized块),由于这些线 ...

  6. 【有奖互动】HMS Core. Sparkle游戏应用创新沙龙,诚邀您参与

    活动简介 随着互联网基础设施的完善和"宅经济"效应凸显,游戏行业逆势上扬,迎来巨大消费市场.同时,用户需求愈加多样化,如何进一步创新和技术升级.提升核心竞争力已成为游戏开发与运营的 ...

  7. YsoSerial 工具常用Payload分析之URLDNS

    本文假设你对Java基本数据结构.Java反序列化.高级特性(反射.动态代理)等有一定的了解. 背景 YsoSerial是一款反序列化利用的便捷工具,可以很方便的生成基于多种环境的反序列化EXP.ja ...

  8. python开发,注意事项

    提高python代码运行效率 1.使用生成器,节约内存.[一边循环一边计算的机制,称为生成器:generator] 例: .如何创建生成器 1.只要把一个列表生成式的[]改成(),就创建了一个gene ...

  9. UIAutomator2 之 计算机积极拒绝

    启动 问题: Failed to establish a new connection 由于目标计算机积极拒绝,无法连接 原因: 电脑重启被IE主动开了本地代理 解决: 网络设置-关闭手动代理

  10. 【Web动画】科技感十足的暗黑字符雨动画

    本文将使用纯 CSS,带大家一步一步实现一个这样的科幻字符跳动背景动画.类似于这样的字符雨动画: 或者是类似于这样的: 运用在一些类似科技主题的背景之上,非常的添彩. 文字的竖排 首先第一步,就是需要 ...