[译]深入了解现代web浏览器(二)
本文是根据Mariko Kosaka在谷歌开发者网站上的系列文章https://developer.chrome.com/blog/inside-browser-part2/ 翻译而来,共有四篇,该篇是第二篇。对于其中一些直译出来不太好理解的句子,笔者做了加工处理和提炼。
在导航中发生了什么
在上一篇文章中,我们了解到了不同的进程和线程如何处理浏览器中的各个部分。在这篇文章中,我们将更深入探讨各个进程和线程如何通信以展示出一个网页来。
让我们来看一个简单的浏览网页的场景:当你输入URL后,浏览器从因特网中获取数据并把页面展示出来。在本文中,我们将重点关注用户请求站点和浏览器准备呈现页面的部分——也就是导航。
从浏览器进程开始
如我们在第一篇文章中https://www.cnblogs.com/geek1116/p/16419720.html所述,tab页之外的所有内容都是由浏览器进程处理的。浏览器进程具有诸如渲染按钮和输入框的UI线程、处理网络栈以从因特网中接收数据的网络线程,以及控制文件等内容访问的存储线程;当你向地址栏中输入URL时,就是由浏览器进程的UI线程来处理你的输入。
顶部的浏览器UI,底部是包含UI、网络和存储线程的浏览器进程
一个简单的导航
步骤1:处理输入
当用户在地址栏中输入的时候,UI线程首先需要考虑的是:“输入内容是一个搜索请求还是URL呢?”。在Chrome中,地址栏同时也是搜索输入域,因此UI线程需要解析并决定将输入内容发送到搜索引擎还是你想要请求的站点。
UI线程在判断输入内容是一个搜索请求还是URL
步骤2:开始导航
当用户敲击回车键后,UI线程发起一个网络调用来获取站点内容。在tab栏的一角会显示加载效果,网络线程会查找合适的协议做接下来的事 例如根据DNS查找域名、为请求建立TSL连接。
UI线程通知网络线程导航至mysite.com
此时,网络线程可能会收到HTTP 301
之类的服务重定向标头(header)。这种情况下,网络线程会告知UI线程该服务需要请求重定向。接着便会发起另一个URL请求。
步骤3:读取响应
一旦响应主体(有效负载)开始进入,网络线程会在有必要时检查流(stream)的前面几个字节。这是因为:响应头部的Content-Type字段会告知数据的类型,但它可能会丢失或者出错,所以在这里进行MIME 嗅探。如chromium源码注释中所说,这是一项“棘手的业务”;你可以阅读该处的注释并看到不同浏览器是如何处理content-type/payload的。
如果响应是一个HTML类型文件,则会将该数据传递给渲染进程;而如果是一个zip或其他类型文件的话,意味着这是一个下载请求所以需要将该数据传递给下载管理器。
网络线程检查响应数据是否是来自安全站点的HTML文件
↑这里也是进行安全浏览检查的地方。如果响应数据和对应的域(domain)与已知的恶意站点相匹配的话,网络线程会发出警告页面。此外,还会做的一项检查CROB——跨域源读阻止(注意是CROB不是CROS),确保跨域的敏感数据不会到达渲染进程。
步骤4:查找渲染进程
当所有的检查完成并且网络线程确信浏览器应该导航至请求站点后,就会告知UI线程数据已经准备就绪。然后UI线程找出一个渲染进程来进行网页的渲染:
由于网络请求可能需要花费数百毫秒之久来等待响应返回,所以一项加速此过程的优化手段应运而生:当UI线程在上述步骤2中向网络线程发送URL请求时,是已经知道它所要导航的站点的,此时它会在网络请求期间并行地查找或启动一个渲染进程。这样一来,如果一切按预期进行,当网络线程的数据到达时,渲染进程就已经处于就绪状态了。如果导航发生重定向是且跨站点的话,则可能不会使用该就绪进程,这种情况下需要使用另外的进程了。
步骤5:提交导航
现在数据和渲染进程都已经准备好了,浏览器进程会向渲染进程发送一个IPC(第一篇文章中提到的进程间通讯手段)来提交导航。该IPC也会被用来传递数据流(stream)以让渲染进程可以持续接收HTML数据。当浏览器进程收到渲染进程中对导航提交的确认,本次导航就结束了,接着开始HTML文档的加载阶段。
这时候地址栏就被更新了,安全指示器和站点设置UI(地址栏最左侧的图标)上会反映出新页面的站点信息。该tab页的会话历史将会被更新——因此可以让顶部的后退/前进按钮在曾经导航过的站点间逐次跳转。为了能够让你在关闭tab页/窗口后恢复tab页/会话,会话历史会被储存到磁盘上。
浏览器进程和渲染进程之间的IPC,请求渲染页面
额外步骤:初始化加载完成
导航提交后,渲染进程会继续加载资源和渲染页面。我们会在下一篇文章中详细此阶段完成的内容。当渲染进程“完成”渲染之后,会返回IPC给浏览器进程(这发生在页面以及所有内嵌iframe的onload
事件触发并执行完之后)。此时,UI线程会停止tab标签旁边的加载效果。
上面一段中的“完成”字样我特意用双引号括起来,这并不代表着真正的完成,因为在此之后Javascript仍然可以加载其他资源并渲染新的视图。
从渲染进程到浏览器进程的IPC来通知页面“已加载”
导航到其他站点
这个简单的导航过程就完成了!但是如果用户又在地址栏中输入一个不同URL的话会发生什么呢?好吧,浏览器进程将通过相同的步骤来达到新的站点。但在此之前,它需要检查下当前渲染的页面是否需要关注beforeunload
事件。
beforeunload
可以在你试图导航至别处或关闭tab页时创建“离开此站点?”的警告。tab中的所有东西包括你的Javascript代码都是渲染进程处理的,所以浏览器进程必须在新的导航请求到来时检查当前的渲染进程。
从浏览器进程到渲染进程的IPC,告知即将导航到新站点
如果导航是从渲染进程启动的(例如用户点击了一个链接或者客户端的Javascript运行了window.location="https://newsite.com"
),渲染进程会首先检查beforeunload
处理器。之后所经历的过程就和浏览器进程启动导航的一样了。唯一的区别在于导航请求是从渲染进程到浏览器进程中的。
当新导航指向的站点不同于当前渲染的站点时,会调用另一个单独的渲染进程来处理新导航,而当前的渲染进程会被保留以处理诸如unload
等事件。更多详情请参见页面生命周期状态概述以及如何使用页面生命周期API。
从浏览器进程到新渲染进程告知渲染页面和到旧渲染进程卸载的两个IPC
Service Worker
这个导航过程最近新引入的一个变化是service workder。service workder是一种在应用程序代码中编写网络代理的方法;允许Web开发人员更好地控制本地缓存的内容以及何时从网络获取新数据。如果service workder设置为从缓存中加载页面,则无需向网络请求数据。
需要记住的一个重点是,service workder是运行在渲染进程中的Javascript代码。但是当导航请求到来的时候,浏览器进程如何知道该站点有service workder呢?
当注册了一个service workder后,该service workder的作用域会被作为一个引用保存(你可以在这篇Service Worker生命周期中了解过于作用域的更多信息)。当一个新导航发生时,网络线程根据已注册的service worker作用域来检查新站点的域(domain),如果该域的URL有对应注册的service worker,UI线程会找到一个渲染进程以运行service worker代码。service worker能够从缓存中加载数据,这样就不用从网络上请求数据;或者它也可以从选择从网络上请求资源。
浏览器进程中的网络线程在查到service worker的作用域
浏览器进程中的UI线程启动了一个渲染进程来处理service worker;然后渲染进程中的worker线程从网络请求数据
导航预加载
你可以看到如果service worker最终决定从网络请求数据的话,在浏览器进程和渲染进程之间的这种往返会造成延迟。Navigation Preload是一种通过在service worker时并行加载资源来加速这一过程的机制。它会给这些请求的header中做标记以表示这是由Navigation Preload机制发出的请求,然后服务器可以决定对这些请求返回不同的内容;例如只更新部分数据而不是返回整个HTML文档。
浏览器进程中的UI线程在启动一个渲染进程来执行service worker的同时并行地发出网络请求
总结
在这篇文章中,我们研究了导航期间发生的事情以及你的web应用程序(例如响应header和客户端javascript)是如何与浏览器交互的。了解了浏览器从网络请求数据所经历的步骤,让我们更加明白了为什么要开发出类似Navigation Preload的这些APIs。在下篇文章,我们将深入探讨浏览器是如何解析我们的HTML/CSS/Javascript来渲染页面的。
[译]深入了解现代web浏览器(二)的更多相关文章
- [译]36 Days of Web Testing(二)
Day 7: Http 和 Https Why? 当在网络上传输一些私人,敏感信息时,应该采用加密的手段来保证这些信息在传输的过程中不被侦测到.Https协议正是这种实现机制. Https是一种广泛使 ...
- 第十一章:WEB浏览器中的javascript
客户端javascript涵盖在本系列的第二部分第10章,主要讲解javascript是如何在web浏览器中实现的,这些章节介绍了大量的脚本宿主对象,这些对象可以表示浏览器窗口.文档树的内容.这些章节 ...
- [C# 网络编程系列]专题四:自定义Web浏览器
转自:http://www.cnblogs.com/zhili/archive/2012/08/24/WebBrowser.html 前言: 前一个专题介绍了自定义的Web服务器,然而向Web服务器发 ...
- SeaJS:一个适用于 Web 浏览器端的模块加载器
什么是SeaJS?SeaJS是一款适用于Web浏览器端的模块加载器,它同时又与Node兼容.在SeaJS的世界里,一个文件就是一个模块,所有模块都遵循CMD(Common Module Definit ...
- 006-优化web请求二-应用缓存、异步调用【Future、ListenableFuture、CompletableFuture】、ETag、WebSocket【SockJS、Stomp】
四.应用缓存 使用spring应用缓存.使用方式:使用@EnableCache注解激活Spring的缓存功能,需要创建一个CacheManager来处理缓存.如使用一个内存缓存示例 package c ...
- 转:【专题四】自定义Web浏览器
前言: 前一个专题介绍了自定义的Web服务器,然而向Web服务器发出请求的正是本专题要介绍的Web浏览器,本专题通过简单自定义一个Web浏览器来简单介绍浏览器的工作原理,以及帮助一些初学者揭开浏览器这 ...
- WEB入门二 表格和表单
学习内容 Ø 表格的作用和制作 Ø 表单的制作 能力目标 Ø 掌握表格的创建 Ø 掌握设置表格的常用属性: Ø 理解表单的作用 Ø ...
- C#实现多级子目录Zip压缩解压实例 NET4.6下的UTC时间转换 [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了 asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程 asp.net core异步进行新增操作并且需要判断某些字段是否重复的三种解决方案 .NET Core开发日志
C#实现多级子目录Zip压缩解压实例 参考 https://blog.csdn.net/lki_suidongdong/article/details/20942977 重点: 实现多级子目录的压缩, ...
- 专题四:自定义Web浏览器
前言: 前一个专题介绍了自定义的Web服务器,然而向Web服务器发出请求的正是本专题要介绍的Web浏览器,本专题通过简单自定义一个Web浏览器来简单介绍浏览器的工作原理,以及帮助一些初学者揭开浏览器这 ...
- 前端Web浏览器基于Flash如何实时播放监控视频画面(前言)之流程介绍
[关键字:前端浏览器如何播放RTSP流画面.前端浏览器如何播放RTMP流画面] 本片文章只是起到抛砖引玉的作用,能从头到尾走通就行,并不做深入研究.为了让文章通俗易懂,尽量使用白话描述. 考虑到视频延 ...
随机推荐
- 混合编程:如何用pybind11调用C++
摘要:在实际开发过程中,免不了涉及到混合编程,比如,对于python这种脚本语言,性能还是有限的,在一些对性能要求高的情景下面,还是需要使用c/c++来完成. 本文分享自华为云社区<混合编程:如 ...
- 总结vue3 的一些知识点:MySQL NULL 值处理
MySQL NULL 值处理 我们已经知道 MySQL 使用 SQL SELECT 命令及 WHERE 子句来读取数据表中的数据,但是当提供的查询条件字段为 NULL 时,该命令可能就无法正常工作. ...
- MAC 转 Byte[] 数组
MAC 转 Byte[] 数组 /** * MAC 地址转 byte[] * 默认以小端序转换 * * @param macAddr "E4:54:E8:81:FC:FD" * @ ...
- 基于BaseHTTPRequestHandler的HTTP服务器基础实现
1. BaseHTTPRequestHandler介绍 BaseHTTPRequestHandler是Python中的一个基类,属于http.server模块,用于处理HTTP请求的基本功能.它提供了 ...
- 100天搞定机器学习|Day60 遇事不决,XGBoost
XGBoost 是一种集大成的机器学习算法,可用于回归,分类和排序等各种问题,在机器学习大赛及工业领域被广泛应用.成功案例包括:网页文本分类.顾客行为预测.情感挖掘.广告点击率预测.恶意软件分类.物品 ...
- AtCoder Beginner Contest 177 (个人题解,C后缀和,D并查集,E质因数分解)
补题链接:Here A - Don't be late 题意:高桥(Takahashi )现在要去距离家 \(D\) 米的地方面基,请问如果以最高速度 \(S\) 能否再 \(T\) 时刻准时到达? ...
- L3-020 至多删三个字符 (30分) (DP)
问题描述: 给定一个全部由小写英文字母组成的字符串,允许你至多删掉其中 3 个字符,结果可能有多少种不同的字符串? 输入格式: 输入在一行中给出全部由小写英文字母组成的.长度在区间 [4, 1e6] ...
- 处理uniapp(同理小程序)开发中使用rich-text富文本解析,图片未自适应宽度问题(图片显示不全)
https://www.cnblogs.com/luyaru/p/15538883.html
- vue-draggable 学习和使用
vue-draggable 学习和使用 https://www.jianshu.com/p/e8ff1e1cafb1
- 小白学标准库之 http
1. 前言 标准库是工具,是手段,是拿来用的.一味的学标准库就忽视了语言的内核,关键.语言层面的特性,内存管理,垃圾回收.数据结构,设计模式.这些是程序的内核,要熟练,乃至精通它们,而不是精通标准库. ...