iidear / blog

blog
0 stars 0 forks source link

Inside Browser #1

Open iidear opened 5 years ago

iidear commented 5 years ago

Reading List

iidear commented 5 years ago

万维网最初的提案 https://www.w3.org/History/1989/proposal.html

介绍了万维网出现的背景以及基本的设计思路。

CERN(欧洲核研究组织)管理着多个大型的项目和试验。这些项目涉及的数据量大且不断在增加,很容易导致数据丢失。如何管理这些数据和信息成了一个很大的问题。基于此,Tim Berners-Lee 提出了一种基于分布式超文本系统的信息管理方案。

在数据量不断增长的情况下,把每份数据拆成独立的节点,然后通过连接把相关数据节点组织起来,是一种更合适的方式。树形结构是组织数据的一种方式,问题在于树无法对数据间的关系很好地建模,因为节点之间的连接关系是交错的。使用关键字(类似HashMap)也是一种方式,问题在于使用的人需要对系统和各个关键字都很熟悉。当时存在的超文本系统是一种可取的方案。

然后提案分析了 CERN 的需求

后面是一些概念图和排期。

从背景说明、问题分析、方案评估与选择、系统需求分析、系统基本模型、到任务排期。思路清晰完整。因为当时应用场景的限定,忽略了一些问题,导致一些缺陷到今天还被诟病(比如安全)。不过总的来说还是很棒。

用作者另一篇文章的话来说,

actually the inventing it was easy. ... the difficult bit was persuading people to join in.link

还有一个搞笑的,大概是因为发明了万维网。很多人收到垃圾邮件时给 Tim Berners-Lee 发邮件吐槽。在这里他呼吁人们不要给他发这些邮件了。

最早的浏览器

iidear commented 5 years ago

现代浏览器架构系列 Inside look at modern web browser

Part1 浏览器进程

介绍了CPU、GPU、进程、线程的基本概念,以及 Chrome 采用的架构。

基本的架构模型是 浏览器进程(Browser Process) 协调 渲染进程(Renderer Process)、GPU进程(GPU Process)、插件进程(Plugin Process)等其它进程进行工作。

不同的硬件设备会有不同的进程线程模型。高端设备会创建多进程以便利用多核CPU,低端设备可能会创建多线程以节省内存。如网络相关的部分可能实现为网络进程,也可能是浏览器进程中的一个线程。

之前的 Chrome 版本中,每个 tab 一个独立的进程。 Chrome 67 之后,每个跨站的 iframe 也会创建一个渲染进程。Site Isolation

Part2 Navigation

介绍从输入 URL 到获取到页面数据,中间经历了哪些过程。

浏览器进程的线程:

处理模型:

  1. UI thread 监控到用户的输入事件,检查输入,判断是搜索还是页面链接。用户回车后,UI thread 通知 network thread 进行网络请求。
  2. network thread 开始 DNS 解析, 建立 TLS、TCP 连接,发出请求,获取响应内容,读取响应内容,进行 MIME Type 嗅探,安全检查。通过之后,找到一个 renderer Process,将请求数据流转交给 renderer Process 进行处理。
  3. Renderer Process 进行渲染,完成后触发 onload 事件,通知浏览器进程停止 loading 动画。

Service Worker:

service worker is JavaScript code that runs in a renderer process.

当浏览器支持 Service Worker 时,在network thread 发起网络请求之前会检查该URL是否有注册 Service Worker。如果是,则找到一个 renderer Process 执行 Service Worker的代码。

iidear commented 5 years ago

Part3 渲染进程

介绍从解析 HTML、CSS、JavaScript 到渲染页面的过程。

渲染进程的线程:

基本流程:解析 HTML 生成DOM,遇到 script 等待 js 执行,解析 CSS。 匹配 DOM 和 CSS,生成 Layout Tree,Plaint,Composit。

Web Foundamental Performance 也有类似的介绍,性能优化上,可操作性更强。

pixel pipeline

一般场景:

  1. JS / CSS > Style > Layout > Paint > Composite

    JS或CSS 改变“layout” 的属性,比如元素的 width、height、定位元素的 left、top。

  2. JS / CSS > Style > Paint > Composite

    JS或CSS 改变“paint only”属性,比如background-image、color、shadow

  3. JS / CSS > Style > Composite

    animation 或 滚动

Web Foundamental Performance 系列下包含了在 chrome dev-tool 中分析绘制流程的方法,以及通用的优化手段。

Layout 是很耗时的一步,尽量减少。

iidear commented 5 years ago

Part4 事件处理

介绍用户触发的事件(click、keydown)是如何执行的。

基本处理流程:

  1. 浏览器进程监测到用户事件,将事件的类型和信息(如位置)传递给渲染进程

  2. 渲染进程中 compositor thread 会标记出一块可点击区域(Non-Fast Scrollable Region)。如果事件发生在区域外,compositor thread 直接生成新的 frame,如果事件发生在区域内,则将事件信息传递给 main thread.

  3. main thread 根据事件的位置,找到 event target, 然后执行事件回调 js.

一些技巧与API

iidear commented 5 years ago

Life of a pixel

https://docs.google.com/presentation/d/1boPxbgNrTU0ddsc144rcXayGA_WF53k96imRH8Mp34Y/edit#slide=id.p

介绍了从网页代码到屏幕渲染出像素,以及页面样式变动重新渲染的过程。即 HTML + CSS + JavaScript --> pixel.

首次渲染基本流程:

  1. parsing HTML 构建 DOM
  2. style css,解析 css 生成 styleRules
  3. 计算每个 DOM 节点的所有样式属性 ComputedStyle
  4. 生成 layout tree. (基本上每个 DOM 节点会对应一个 LayoutObject 对象, 计算每个 LayoutObject 的位置和大小). layout 计算过程很复杂。涉及 table布局, 文字换行, float, flex, 书写模式
  5. paint. 生成绘制操作的序列 displayItemList 需要根据 z 轴层级,多次遍历 layout tree,确定绘制指令的顺序。
  6. raster. 根据绘制指令调用操作系统底层图形库生成位图。

用户行为、动画、js等各种因素会触发页面内容的改变,或视窗内容的改变。此时需要重新渲染,为了提高性能,对 layout, paint, raster 等步骤做了更细的拆分和优化: