浏览器和内核

浏览器年表

日期 浏览器 描述 userAgent
1990年 Nexus 第一个浏览器(worldWidWeb,后改名为Nexu):不支持显示图片
1993年 Mosaic 第一个可以显示图片的浏览器

NCSA_Mosaic/2.0 (Windows 3.1)
(为了区分Nexus和Mosaic浏览器,userAgent诞生)
1994年 Netscape 即:Mozilla,支持了html框架显示,即table布局 Mozilla/1.0 (Win3.1)
1995年 IE 使用Trident内核 Mozilla/1.22 (compatible; MSIE 2.0; Windows 95)
(服务器只会给userAgent里有Mozilla字样的发送含框架的页面)

IE6:Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)
2002年 FireFox 使用Gecko引擎 Mozilla/5.0 (Windows; U; Windows NT 5.1; sv-SE; rv:1.7.5) Gecko/20041108 Firefox/1.0
2003年 Safari 使用webkit引擎
排版引擎webCore是KHTML衍生而来的
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; de-de) AppleWebKit/85.7 (KHTML, like Gecko) Safari/85.5
2008年 chrome 使用blink内核 Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13

浏览器的功能

  • 网络
  • 资源管理
  • 网页浏览
  • 多页面管理
  • 插件和扩展
  • 书签管理
  • 历史记录管理
  • 设置管理
  • 下载管理
  • 账户和同步
  • 安全机制
  • 隐私管理
  • 外观主题
  • 开发者工具

    HTML5的标准(10个大的类别)

  • 离线( offline)

  • 存储( storage)
  • 连接( connectiⅳity)
  • 文件访问( file access)
  • 语义( semantics)
  • 音频和视频( audio/video)
  • 3D和图形(3D/ graphics)
  • 展示( presentation)
  • 性能( performance)
  • 其他( Nuts and bolts) :::info http://html5test.com/index.html 提供了测试浏览器支持H5的情况 ::: image.png
    网页脚本语言:EMCAScript
    级联样式表: CSS( Cascading Style Sheet)
    传输协议:HTTP

    用户代理信息(User Agent)

    用户代理信息(User Agent)是浏览器向网站服务器发送HTTP请求消息头的时候加入的,这样,网站服务器就能很容易了解对方浏览器信息。

渲染引擎

渲染引擎模块及依赖模块

渲染:根据描述或者定乂构建数学模型,通过模型生成图像的过程。
浏览器的渲染引擎:能够将 HTML/CSS/ JavaScript文本及其相应的资源文件转换成图像结果的模块,如图1-3所示。
image.png

image.png
image.png

  • HTML解释器:解释HTML文本的解释器,主要作用是将HTML文本解释成DOM(文档对象模型)树,DOM是一种文档的表示方法。
  • CSS解释器:级联样式表的解释器,它的作用是为DOM中的各个元素对象计算出样式信息,从而为计算最后网页的布局提供基础设施
  • 布局:在DOM创建之后, Webkit需要将其中的元素对象同样式信息结合起来,计算它们的大小位置等布局信息,形成一个能够表示这所有信息的内部表示模型。
  • JavaScript引擎:使用 JavaScript代码可以修改网页的内容,也能修改CSS的信息, Javascript引擎能够解释 Javascript代码并通过DOM接口和 CSSOM接口来修改网页内容和样式信息,从而改变渲染的结果
  • 绘图:使用图形库将布局计算后的各个网页的节点绘制成图像结果

    渲染过程

    image.png
    在渲染完成之后,用户可能需要跟渲染的结果进行交互,或者网页自身有动画操作,一般而言,这需要持续的重复渲染过程。
    image.png

    源码地址

    webkit 源码:www.webkit.org
    chromium 源码:www.chromium.org

网页和结构

  1. <html>
  2. <head>
  3. <style type="text/css">
  4. video, div, canvas {
  5. -webkit-transform: rotateY(30deg) rotateX(-45deg);
  6. }
  7. </style>
  8. </head>
  9. <body>
  10. <video src="avideo.mp4"></video>
  11. <div>
  12. <canvas id="a2d"></canvas>
  13. <br>
  14. <canvas id="a3d"></canvas>
  15. </div>
  16. <script type="text/javascript">
  17. var size = 300:
  18. // canvas2D绘图
  19. var a2dCtx = document.getElementById('a2d').getContext('2d');
  20. a2dCtx.canvas.width = size;
  21. a2dCtx.canvas.height = size;
  22. a2dCtx.fi11sty1e="rgba(0,192,192,80)";
  23. a2dCtx.fi11Rect(0,0,200,200);
  24. var a3dCtx= document.getElementById('a3d').getContext('experimental-webgl');
  25. a3dCtx.canvas.width = size
  26. a3dCtx.canvas.height = size
  27. a3dCtx.clearCo1or(0.0, 192.0/255.0, 192.0/255.0, 80.0/255.0);
  28. a3dCtx.clear(a3dCtx.COLOR_BUFFER_BIT);
  29. </script>
  30. </body>
  31. </html>

分层

截屏2022-02-01 上午10.50.01.png
image.png
image.png
分层:对于需要复杂变换和处理的元素,它们需要新层,所以, WebKit为它们构建新层其实是为了渲染引擎在处理上的方便和高效。

  • 根层:html
  • 层1 video:创建一个新的层可以更有效地处理视频解码器和浏览器之间的交互和渲染问题
  • 层2 div: 需要进行3D变换
  • 层3 : 2dcanvas
  • 层4 : 3dcanvas

    渲染过程

    用户输入“URL”转变成可视化的图像包含两个过程:

  • 其一是网页加载过程, 就是从“URL”到构建 DOM 树;

  • 其二是网页渲染过程, 从 DOM 树到生成可视化图像。

其实, 这两个过程也会交叉, 很难给予明确的区分.

网页通常比我们的屏幕可视面积要大(在移动设备上尤其明显),而当前可见的区域,我们称为视图( viewport).

从网页 URL 到 DOM 树

image.png
1.当用户输入网页URL的时候, WebKit调用其资源加载器加载该URL对应的网页
2.加载器依赖网络模块建立连接,发送请求并接收答复。
3. WebKit接收到各种网页或者资源的数据,其中某些资源可能是同步或异步获取的。
4.网页被交给HTML解释器转变成一系列的词语( Token)。
5.解释器根据词语构建节点(Node),形成DOM树。
6.如果节点是 JavaScript代码的话,调用 JavaScript 引擎解释并执行
7. JavaScript 代码可能会修改 DOM 树的结构。
8.如果节点需要依赖其他资源,例如图片、CSS、视频等,调用资源加载器来加载它们,但是它们是异步的,不会阻碍当前DOM树的继续创建;如果是JavaScript资源URL(没有标记异步方式),则需要停止当前DOM树的创建,直到 JavaScript的资源加载并被 JavaScript引擎执行后才继续DOM树的创建

  • DOMConentLoaded事件: 分别在DOM树构建完之后
  • DOM的”onload”事件: DOM树建完并且网页所依赖的资源都加载完之后发生

利用 CSS 和 DOM 树构建 Renderobject 树直到绘图上下文

image.png
1.CsS文件被CSS解释器解释成内部表示结构。
2.CSS解释器工作完之后,在DOM树上附加解释后的样式信息,这就是Renderobject树。
3. Renderobject节点在创建的同时, WebKit 会根据网页的层次结构创建 Renderlayer树,同时构建一个虚拟的绘图上下文。

从绘制上下文到图像

image.png

1.绘图上下文是一个与平台无关的抽象类,它将每个绘图操作桥接到不同的具体实现类,也就是绘图具体实现类。
2.绘图实现类也可能有简单的实现,也可能有复杂的实现。在 Chromium 中,它的实现相当复杂,需要 Chromium 的合成器来完成复杂的多进程和 GPU 加速机制,
3.绘图实现类将 2D 图形库或者 3D 图形库绘制的结果保存下来,交给浏览器来同浏览器界面一起显示

架构和模块

webkit 架构

image.png

  • 虚线框表示该部分模块在不同浏览器使用的 WebKit 内核中的实现是不一样的,也就是它们不是普遍共享的
  • 实线框标记的模块表示它们基本上是共享的

image.png

image.png

Chromium 架构

image.png
image.png

多进程架构

多进程架构:在 WebKit 内核之上, Chromium 率先在 WebKit 之外引入了多进程模型。

  • 其一避免因单个页面的不响应或者崩溃而影响整个浏览器的稳定性,特别是对用户界面的影响;
  • 其二当第三方插件崩溃时不会影响页面或者浏览器的稳定性,这时因为第三方插件也被使用单独的进程来运行;
  • 其三它方便了安全模型的实施,也就是说沙箱模型是基于多进程架构的。其实,这很大程度上也是 WebKit2 产生的原因。 :::warning 打开activity monitor,搜索chrome,可以看到进程(打开/关闭chrome,新增/关闭tab,查看进程的变化)
    http://blog.csdn.net/miladonjuFiL
    http://www.webkit.org/blog-files/3d-transforms/morphing-cubes. html ::: image.png

方框代表进程,连接线代表IPC进程间通信。
image.png

  • Browser进程: 浏览器的主进程,负责浏览器界面的显示、各个页面的管理,是所有其他类型进程的祖先,负责它们的创建和销毁等工作,它有且仅有一个。
  • Renderer进程:网页的渲染进程,负责页面的渲染工作, Blink/Webkit的渲染工作主要在这个进程中完成,可能有多个,但是 Renderer进程的数量是否同用户打开的网页数量一致呢?答案是不一定。 Chromium设计了灵活的机制,允许用户配置,随后就作介绍。此外,在沙箱模型启动的情况下,该进程可能会发生一些改变。
  • NPAP插件进程:该进程是为 NPAPI类型的插件而创建的。其创建的基本原则是每种类型的插件只会被创建一次,而且仅当使用时才被创建。当有多个网页需要使用同一种类型的插件的时候,例如很多网页需要使用Fash插件, Flash插件的进程会为每个使用者创建一个实例,所以插件进程是被共享的。
  • Pepper插件进程:同 NPAPI插件进程,不同的是为 Pepper插件而创建的进程。
  • GPU进程:最多只有一个,当且仅当GPU硬件加速打开的时候才会被创建,主要用于对3D图形加速调用的实现。
  • 其他类型的进程:图中还有一些其他类型的进程没有描述出来,例如 Linux下的“ Zygote”进程, Renderer进程其实都是由它创建而来。
  • “ Sandbox”准备进程:这在安全机制中作进一步的介绍。

:::info 对于 Chromium的 Android版

  • 目前, Android版不支持插件,所以也就没有插件进程
  • 在 Android平台上,GPU进程演变成 Browser进程的一个线程,也就是GPU线程,这得益于其灵活的架构,主要目的之一是节省资源。
  • 另外一个就是 Renderer 进程, Renderer 也是独立的进程,但是会演变成 Android上的服务(service)进程。而且,由于 Android 系统的局限性, Renderer 进程的数目会被严格限制 :::

    从 webkit 接口层到用户界面的路径

    image.png

  • WebKit 黏附层:它的出现主要是因为 Chromium中的一些类型和 WebKit内部不一致,所以需

要一个简单的桥接层。

  • Renderer:它主要处理进程间通信,接受来自 Browser进程的请求,并调用相应的 WebKit接口层。同时,将 WebKit的处理结果发送回去。
  • Rendererhost:给 Renderer 进程发送请求并接收来自 Renderer进程的结果。
  • Web Contents: 网页的内容

多线程模型

  • Browser进程多线程:为了保持用户界面的高响应度,保证 UI 线程( Browser进程中的主线程)不会被任何其他费时的操作阻碍从而影响了对用户操作的响应。
    • 本地文件读写
    • socket读写
    • 数据库操作等
  • Renderer进程多线程:不让其他操作阻止渲染线程的快速执行。更甚者,为了利用多核的优势, Chromium将渲染过程管线化,这样可以让渲染的不同阶段在不同的线程执行 :::warning 使用htop工具(参考:https://cnbin.github.io/blog/2015/06/19/mac-xia-de-top-he-htop-zhi-ling/) ::: image.png

  • Browser进程收到用户的请求,首先由U线程处理,而且将相应的任务转给IO线程,它随即将该任务传递Renderer进程。

  • Renderer进程的IO线程经过简单解释后交给渲染线程。渲染线程接受请求、加载网页并渲染网页,这其中可能需要 Browser 进程获取资源和需要GPU 进程来帮助渲染。最后 Renderer 进程将结果由IO线程传递给Browser进程。
  • 最后, Browser进程接收到结果并将结果绘制出来。

content 接口

支持所有的 HIML5 功能、GPU 硬件加速功能和沙箱机制
image.png

WebKit2 架构

其主要思想和Chromium类似,将渲染过程放在单独的进程中来完成,独立于用户界面。
image.png

资源加载和网络栈

资源

image.png

资源缓存

内存缓存

webkit 标记资源唯一性:URL
image.png

资源加载器

image.png
image.png

  • 图片、css文件的资源获取是异步的不会阻碍主线程的渲染过程,但是JS会。
  • 当前的主线程被阻碍时, WebKit会启动另外一个线程去遍历后面的 HTML 网页,收集需要的资源 URL,然后发送请求,这样就可以避免被阻碍。与此同时, WebKit 能够并发下载这些资源,甚至并发下载 JavaScript 代码资源。

image.png

资源的生命周期

  • 资源池有容量限制,当资源被不断加入到资源池中,需要有资源替换的机制。资源池使用的机制是LRU(least Recent Used:最近最少使用)算法。
  • 刷新页面时,首先判断资源是否在资源池中,如果是,则发送一个HTTP请求给服务器,说明该资源在本地的一些信息,服务器根据该信息判断,无更新则返回304,有更新则发送最新的资源。

    多进程资源获取

    Renderer进程需要的资源实际上是通过进程间通信将任务交给Browser进程来完成的,Browser进程有权限从网络及本地获取资源。

  • 安全性:当沙箱模型打开时,Renderer进程没有获取资源的权限

  • 效率性:资源共享的问题
  • image.png
  • ResourceLoader类:Chromium浏览器实际的资源加载类,它负责管理向网络发起的请求、从网络接收过来的认证请求、请求的回复管理等工作
    • 资源请求有同步(SyncResourceHandle类)和异步(AsyncResourceHandle)两种方式

请求调度器 ResourceSchedule 根据 URLRequest 的标记和优先级来调度 URLRequest 对象。对于以下类型的请求立即被发出:

  • 高优先级的请求
  • 同步请求
  • 具有SPDY能力的服务器

网络栈

image.png

代理

image.png

DNS 域名解析

  • chrome://net-internals/#dns
  • 使用 HostCache 类来保存解析后的域名,可以手动清除 DNS 缓存
  • 单独的线程来解析域名(因为HostResolverImpl类具体调用的函数是getaddrinfo(),该函数是一个阻塞式的函数,所以调试Chromium进程时,会看到多个线程被创建然后又退出)

image.png

磁盘本地缓存

  • 磁盘空间不是无限大,要有相应的机制来移除合适的缓存资源,以便加入新的资源:LRU
  • 能确保浏览器崩溃的时候不破坏磁盘文件,至少能保护原先在磁盘中的数据
  • 能高效并快速的访问磁盘中现有的数据结构,支持同步和异步两种方式
  • 能避免同时存储两个相同的资源
  • 能方便的从磁盘删除一个项,同时可以在操作一个项的时候不受其他请求的影响
  • 磁盘不支持多线程访问,所以需要把所有磁盘缓存操作放入到一个单独的线程中
  • 升级版本时,如果磁盘缓存的内部存储结构发生改变,Chromium 仍然能够支持老版本的结构 :::info chrome://view-http-cache/ 已经在chrome66中被移除
    可以尝试采用用 Firefox 的 about:cache?storage=disk :::

  • BackEnd类:磁盘缓存

  • Entry类:表头

cookie

Cookie的时效性

  • 会话型cookie(Session Cookie):保存在内容中,浏览器退出时就被清除
  • 持续型Cookie(Persistent Cookie):浏览器退出的时候,仍然被保留

    Cookie管理器CookieMonster:

  • 实现 CookieStore的接口,它是对外的接口,调用者可以设置和获得 Cookie;

  • 报告各种 Cookie的事件,例如更新信息等,主要使用 Delegate 类;
  • Cookie对象的集合,也就是CanonicalCookie的集合,每个 CanonicalCookie对象表示一个域的 Cookie结合。
  • 持续型 Cookie的存储

image.png

高性能网络栈

  • DNS 预取
  • TCP 预连接
  • 搭建支持Http 管线化的服务器:将多个http请求填充到一个TCP数据包内,同时给到服务器,因此无需等待服务器的响应。管线化需要通过永久连接(Persistent Connection)来完成,并且只有GET和HEAD等请求可以进行管线化
  • 搭建支持SPDY的服务器: 为了解决网络延迟和安全性问题,其核心思想是多路复用。

image.png

高效的资源使用策略

DNS和TCP连接

Dns解析和tcp连接占用大量的时间,所以可以这样来优化网页

  • 减少链接的重定向:重定向会导致重新建立TCP连接、多次DNS解析
  • 利用DNS预取机制
  • 搭建支持SPDY协议的服务器
  • 避免错误的链接请求

    资源的数量

    减少网页中所需的资源数量来改善网页的加载

  • 在HTML网页中内嵌小型的资源(如:base64的图片)

  • 合并资源:将小图片合并成一张大图片(传说中的雪碧图)

    资源的数据量

    减少资源大小来提高网页的加载速度

  • 使用浏览器本地磁盘缓存机制

  • 启用资源的压缩技术

    HTML 解释器和模型

    image.png

    DOM

    字节流

  • 网络传输

  • 本地文件

DOM定义的是一组与平台、语言无关的接口,该接口允许编程语言动态访问和更改结构化文档。使用DOM表示的文档被描述成一个树形结构,使用DOM的接口可以对DOM树结构进行操作。
image.png
DOM 树

  • 文档节点
  • 元素节点
  • 属性节点

    HTML解释器

    将字节流解释成DOM树结构。
    image.png

    解码(字节流->字符流)

    解码过程就是根据网页中设置的编码格式(通常是:utf8)将字节流解析为字符流。

    词法分析器(字符流->Token)

    通过HTMLTokenizer类来完成词法分析,每次调用 nextToken 函数会输出一个词语(Token)
    image.png
    webkit中词语(Token)的类别有6种:
    image.png

    语法分析器(Token->Node)

    通过HTMLDocumentParser类调用HTMLTreeBuilder类来进行词法分析,将词语(Token)构建为节点。不同的类型的词语的构建过程不一样。
    image.png
    image.png

    节点到DOM树(Node->DOM)

    使用HTMLConstructionSite类来完成节点到DOM树的转化。
    HTMLElementStack类是一个保存元素节点的栈,转化过程就是对一个元素节点栈进行操作(pop/push)的过程。

    网页基础设施

    表示网页的类既提供了构建DOM树等这些操作,同时也提供了接口用于布局、渲染等操作。
    image.png
    右边的类的代码在core/page目录下:这部分blink和webkit的实现基本一致,提供了ChromeClient、Page、Frame等公共类。其中Chrome不是指Chrome浏览器,而是webkit的一个类,负责用户界面和渲染相关的需求,主要功能如下:

  • 重绘或者更新整个窗口、滚动窗口等

  • 窗口相关操作,如显示、隐藏窗口
  • 显示和隐藏窗口中的工具栏、状态栏、滚动条等
  • 显示JavaScript相关的窗口,例如JavaScript的alert、confirm等窗口

    image.png
    左边的代码在core/exported目录下:这部分不同的浏览器实现不一样,在Chromium里,提供了两个接口类WebView(表示网页)和WebFrame(表示网页框),分别对应两个实现类WebViewImpl和WebFrameImpl。

    线程化的解释器

    WebKit中,网络资源的字节流自IO线程传递给渲染线程(主线程)之后,后面的解释、布局和渲染等工作基本上都是由渲染线程来完成,因为DOM树只能在渲染线程上创建和访问。

Chromium中将字符串到词语的阶段单独交给解释器线程HTMLParser Thread,解释成Token后,再分批次将结果交给渲染线程。
image.png

JS的执行

WebKit将DOM树创建过程中需要执行的 JavaScript代码交由 HTMLScriptRunner 类来负责。因为JS代码可能会修改DOM结构,因此JSt代码的执行会阻碍后面节点的创建,同时当然也会阻碍后面的资源下载,因此建议如下:

  • 将“ script”元素加上“ async”属性,表明这是一个可以异步执行的 JavaScript代码,在 HTMLScriptRunner类中,读者也可以发现相应的函数执行异步的JavaScript代码;
  • 另外一种方法是将“ script”元素放在“body”元素的最后,这样它不会阻碍其他资源的并发下载. :::info 当DOM树构建完之后, WebKit触发“ DOMContentLoaded”事件,注册在该
    事件上的 JavaScript函数会被调用。当所有资源都被加载完之后, WebKit触发
    “ onload”事件 :::

DOM的事件机制

事件:

  • 事件本身(event)
  • 事件目标(EventTarget)。事件目标通过注册监听器(Event Listener)来监听事件。

image.png
DOM的事件处理机制有两种

  • 事件捕获(Event capture)
  • 事件冒泡(Event bubbling)

:::warning 当渲染引擎接收到一个事件的时候,它会通过 HitTest( WebKit中的一种检查触发事件在哪个区域的算法)检查哪个元素是直接的事件目标。 ::: 这里假设img是直接的事件目标:
image.png
可以通过 stopPropagation 来阻止事件向上向下传递。


webkit技术内幕 - 图49
image.png
当监听到事件发生时,事件本身绑定的默认行为也会被触发,比如 a 链接 click 的跳转,这时可以通过preventDefault来阻止其默认行为。
image.png

Shadow DOM

:::info 主要解决一个文档中可能需要大量交互的多个DOM树建立和维护各自的功能边界的问题。
其规范规定能够使得一些DOM节点在特定范围内可见,而在网页的DOM树中不可见,但是网页渲染的结果包含了这些节点,从而使得封装变得容易。 ::: image.png
JS代码只能通过特殊的接口方式访问到影子DOM子树中的节点,而不能直接访问。
如H5中的video就是shadow DOM。

shadow DOM 中事件的事件目标是包含影子DOM子树的节点对象。
事件捕获及事件冒泡没有变化,和正常DOM节点一样。

通过attachShadow接口来创建一个Shadow DOM

  1. <!DOCTYPE html>
  2. <html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>
  3. <body link="#0000cc" style="">
  4. <div id="div"></div>
  5. <script type="text/javascript">
  6. window.onload = function () {
  7. var adiv = document.getElementById('div');
  8. var root = adiv.attachShadow({mode: 'closed'});
  9. var shadowImg = document.createElement('img');
  10. root.appendChild(shadowImg);
  11. var shadowDiv = document.createElement('div');
  12. shadowDiv.innerHTML = 'Hello! shadow DOM';
  13. root.appendChild(shadowDiv);
  14. }
  15. </script>
  16. </body>
  17. </html>

image.png

CSS 解释器和样式布局

CSSDOM

webkit技术内幕 - 图54

:::info CSSDOM:CSS对象模型。它的思想是在DOM中一些节点接口中,加入获取或操作CSS属性或接口的JavaScript接口,因而JavaScript可以动态操作CSS样式。 :::

styleSheets

document.styleSheets
image.png

style Rule

样式规则的类型:

  • Stye:这个是基本类型,大多数规则属于这个类型。
  • import:是 Webkit中为了方便而引入的,其对应的是一个导入CSS文件的Style元素。
  • Meda:对应于CSS标准中的@meda类型。
  • Fontface:CSS3新引入的自定义字体的规则类型。
  • Page:对应于CSS标准中的@page类型
  • Keyframes:对应于 WebKit中的@- webkit-key-frames类型,可以用来定制特定帧的样式属性信息。
  • Region:对CSS标准正在进行中的 Regions的支持,这方便了开发者对页面进行分区域排版。

image.png

CSSOM View

添加新的属性到 Window、 Document、 Element、 HTMLElement和 Mouse event等接口,这些CSS的属性能够让 JavaScript获取视图信息,用于表示跟视图相关的特征。

  • 窗口大小
  • 网页滚动位移
  • 元素的框位置
  • 鼠标事件的坐标等信息。

image.png

解释过程

CSS解释过程:是指从CSS字符串经过CSS解释器处理后变成渲染引擎的内部规则表示的过程。
image.png

样式规则匹配

样式规则建立完成后,Webkit会将规则结果保存下来。当DOM的节点创建好之后,Webkit会为一些可视节点选择合适的样式信息。
image.png

样式布局

:::info WebKit根据框模型来计算它们的位置、大小等信息的过程称为布局计算 ::: image.png

layout

是一个递归过程,而每个node的布局都会经历以下过程:
image.png
触发重新布局的情况:

  • 网页首次被打开的时候,浏览器设置网页的可视区域( viewport),并调用计算布局的方法。这其实也描述了一种常见的情景,就是当可视区域发生变化的时候, WebKit都需要重新计算布局,这是因为网页的包含块的大小发生了改变。
  • 网页的动画会触发布局计算。当网页显示结束后,动画可能改变样式属性,那么 WebKit就需要重新计算。
  • JavaScript代码通过 CSSOM等直接修改样式信息,它们也会触发 Webkit重新计算布局。
  • 用户的交互也会触发布局计算,例如翻滚网页,这会触发新区域布局的计算。

    渲染基础

    :::info 渲染在图形学上的意义:就是把模型变成位图(Bitmap)的过程。
    浏览器中渲染过程就是把每个元素对应的盒变成位图. :::

可以分为两大类渲染:图形和文字

  • 盒的背景、边框、SVG元素、阴影等特性,都是需要绘制的图形类
  • 文字:像素字形、矢量字形

    RenderObject树

    RenderObject树是基于DOM树建立起来的一颗新树,是为了布局计算和渲染机制而构建的一种新的内部表示。

RenderObject树节点和Dom树节点不是一一对应关系,下列情况会创建RenderObject对象

  • DOM树的document节点
  • DOM树中的可视节点(如:html、body、div等),不可视节点(如:meta,head,script)不会创建RenderObject对象
  • 某些情况下Webkit需要建立匿名的RenderObject节点,该节点不对应于DOM树中的任何节点,而是Webkit处理上的需要(如:RenderBlock节点)
    • 因为 Render block的子女必须都是内嵌的元素或者都是非内嵌的元素。所以,当 Renderblock对象包含两种元素的时候, WebKit会为相邻的内嵌元素创建一个块节点,也就是 Renderblock对象,然后设置该对象为原先内嵌元素父亲的子女,最后设置这些内嵌元素为 Renderblock对象的子女。

image.png
image.png :::warning 可以看出, WebKit没有为 HTMLHeadElement 节点(非可视化元素)没有被创建 Renderobject 类的对象。 :::

RenderLayer树

:::info Renderlayer节点的使用可以有效地减小网页结构的复杂程度,并在很多情况下能够减少重新渲染的开销。 ::: RenderLayer树是基于RenderObject树建立起来的一棵新树。RenderLayer节点和RenderObject节点是一对多的关系,构建原则如下:

  • DOM树的Document节点对应的RenderView节点
  • DOM树中的Document的子女节点,也就是HTML节点对应的RenderBlock节点
  • 显式的指定CSS位置的RenderObject节点
  • 有透明效果的RenderObject节点
  • 节点有溢出(Overflow)、alpha或者反射等效果的RenderObject节点
  • 使用Canvas 2D和3D技术的RenderObject节点
  • Video节点对应的RenderObject节点

image.png
image.png

渲染方式

  • 如果绘图操作使用CPU来完成,那么称之为软件绘图。
  • 如果绘图操作由GPU来完成,称之为GPU硬件加速绘图。
  • 理想情况下,每个层都有个绘制的存储区域,这个存储区域用来保存绘图的结果。
  • 合成( Compositing):将这些层的内容合并到同一个图像之中,使用了合成技术的渲染称为合成化渲染。

对于常见的2D绘图操作,使用GPU来绘图不一定比使用CPU绘图在性能上有优势,例如绘制文字、点、线等,原因是CPU的使用缓存机制有效减少了重复绘制的开销而且不需要GPU并行性。其次,GPU的内存资源相对CPU的内存资源来说比较紧张,而且网页的分层使得GPU的内存使用相对比较多。

软件渲染过程

Renderobject对象绘制自己:

  • 绘制该层中所有块的背景和边框,
  • 绘制浮动内容,
  • 前景( Foreground),也就是内容部分、轮廓(它是CSS标准属性,绘制于元素周围的一条线,位于边框边缘的围)等部分。当然,每个阶段还可能会有一些子阶段。值得指出的是,内嵌元素的背景、边框、前景等都是在第三阶段中被绘制的,这是不同之处。

chrome://tracing/

硬件加速机制

具有以下特征的RenderLayer对象就是合成层:

  • Renderlayer 具有 CSS3D 属性或者 CSS 透视效果。
  • Renderlayer 包含的 Renderobject 节点表示的是使用硬件加速的视频解码术的HTML5“vdeo”元素。
  • Renderlayer 包含的 Renderobject 节点表示的是使用硬件加速的 Canvas2I元素或者 WebGL技术。
  • Renderlayer 使用了CSS透明效果的动画或者CSS变换的动画。
  • Renderlayer 使用了硬件加速的 CSS Filters技术
  • Renderlayer 使用了剪裁(Clip)或者反射( Reflection)属性,并且它的后代中包括一个合成层
  • Renderlayer 有一个Z坐标比自己小的兄弟节点,且该节点是一个合成层。

image.png
image.png
image.png
image.png

image.png
合成层瓦片化:

  • ContentLayer,它表示合成层使用Skia画布将内容绘制到结果中,对应到网页中就是常见的HTML元素,例如DOM树中的html、div等所在的层。
  • 图片元素,如果一个合成层仅仅包含一个图片,那么该图片也会使用该技术

为什么需要瓦片化的后端存储:

  • 其一,DOM树中的htm元素所在的层可能会比较大,因为网页的高度很大,如果只是使用一个后端存储的话,那么需要一个很大的纹理对象,但是实际的GPU硬件可能只支持非常有限的纹理大小;
  • 其二,在一个比较大的合成层中,可能只是其中一部分发生变化,根据之前的介绍,需要重新绘制整个层,这样必然产生额外的开销,使用瓦片化的后端存储,就只需要重绘一些存在更新的瓦片;
  • 其三,当层发生滚动的时候,一些瓦片可能不再需要,然后 Webkit需要些新的瓦片来绘制新的区域,这些大小相同的后端存储很容易重复利用,可以做到非常简洁漂亮。 :::info 调度器调度任务:任务的发起者是设置这些状态,它表示之后希望执行一些任务,而不是立即要求执行。状态机
    计算出下一个任务,调度器获得任务的类型并执行该任务,然后再接着计算下一个
    任务,如此循环,直到空闲为止。 :::

    JS 引擎

    JIT( Just-In-Time)技术

    :::info 解决解释性语言的性能问题,主要思想是当解释器将源代码解释成内部表示的时候(Java字节码就是一个典型例子), JavaScript的执行环境不仅是解释这些内部表示,而且将其中一些字节码(主要是使用率高的部分)转成本地代码(汇编代码),这样可以被CPU直接执行,而不是解释执行,从而极大地提高性能。 :::

引擎

  • 中间表示:可以跨平台使用的代码
  • 本地代码(汇编代码):可以被CPU直接执行的代码
  • 字节码:是跨平台的一种中间表示,不同于本地代码

image.png
image.png
image.png
image.png


:::info JavaScript引擎 : 能够将 JavaScript 代码处理并执行的运行环境。

  • 编译器: 主要工作是将源代码编译成抽象语法树,在某些引擎中还包含将抽象语法树转换成字节码。
  • 解释器: 在某些引擎中,解释器主要是接收字节码,解释执行这个字节码,同时也依赖垃圾回收机制等。
  • JIT工具: 一个能够JIT的工具,将字节码或者抽象语法树转换成本地代码,
  • 垃圾回收器和分析工具( Profiler):它们负责垃圾回收和收集引擎中的信息,帮助改善引擎的性能和功效。 ::: image.png

V8

V8 是 JS 引擎的其中一个实现。
image.png

API

  • 各种各样的基础类:
    • 对象引用类(如 Weak Reference Callbacks)、
    • 基本数据类型类(如Int32、 Integer、 Number、 String、 StringObject)
    • JavaScript对象( Object)。
    • 这些都是基础抽象类,没有包含实际的实现,真正的实现在“src”目录中的“ objects. h/cc”中。
  • va|ue: 所有 JavaScript数据和对象的基类,如上面的 Integer、 Number、 String等。
  • V8数据的句柄类:
    • 以上数据类型的对象在V8中有不同的生命周期,需要使用句柄来描述它们的生命周期,
    • 以及垃圾回收器如何使用句柄来管理这些数据,句柄类包括 Local、 Persistent和 Handle
  • Isolate:这个类表示的是一个V8引擎实例,包括相关状态信息、堆等,
    • 总之这是一个能够执行 JavaScript代码的类,
    • 它不能被多个线程同时访问,所以,如果非要这么做的话,需要使用锁。
    • V8使用者可以使用创建多个该类的实例,但是每个实例之间就像这个类的名字一样,都是孤立的。
  • Context:执行上下文,包含内置的对象和方法,如 print方法等,还包括 JavaScript内置的库,如math等。
  • Extension: V8的扩展类。用于扩展 JavaScript 接口,V8 使用者基于该类来实现相应接口,被V8引擎调用。
  • Handle:句柄类,主要用来管理基础数据和对象,以便被垃圾回收器操作主要有两个类型,
    • 一个是Loca(就是Loca类,继承自 Handle类):表示本地栈上的数据,所以量级比较轻,
    • 另一个是 Persistent( Persistent类,继承自 Handle类):表示函数间的数据和对象访问。
  • Script:用于表示被编译过的 JavaScript 源代码,V8的内部表示。
  • Handle Scope:包含一组 Handle的容器类,帮助一次性删除这些 Handle,避免重复调用。
  • Function Template:绑定 C++ 函数到 JavaScript,函数模板的一个例子就是将 JavaScript接口的C++实现绑定到 JavaScript 引擎。
  • Object Template:绑定 C++ 对象到 JavaScript,对象模板的典型应用是Chromium中将DOM节点通过该模板包装成 JavaScript对象。

:::warning V8的工作过程包括两个阶段,都是在用户使用它们时发生:

  • 编译
  • 运行 :::

image.png编译

  • Script:表示是 JavaScript代码,既包含源代码,又包含编译之后生成的本地代码,所以它既是编译入口,又是运行入口
  • Compiler:编译器类,辅助 Script类来编译生成代码,它主要起一个协调者的作用,会调用解释器( Parser)来生成抽象语法树和全代码生成器,来为抽象语法树生成本地代码
  • Parser:将源代码解释并构建成抽象语法树,使用 AstNode Factory类来创建它们,并使用Zone类来分配内存,这个在后面内存管理中介绍
  • Astnode:抽象语法树节点类,是其他所有节点的基类,它包含非常多的子类,后面会针对不同的子类生成不同的本地代码。
  • Astvisitor:抽象语法树的访问者类,基于著名的设计模式 Visitor来设计,主要用来遍历异构的抽象语法树
  • FullCode Generator: Ast visitor类的子类,通过遍历抽象语法树来为JS生成本地可执行的代码

image.png

运行

  • Script:包含编译之后生成的本地代码,运行代码的入口。
  • Execution:运行代码的辅助类包含一些重要的函数,例如“Cal”函数,它辅助进入和执行 Script中的本地代码
  • JSFunction:需要执行的 JavaScript函数表示类
  • Runtime:运行这些本地代码的辅助类,它的功能主要是提供运行时各种各样的辅助函数,包括但是不限于属性访问、类型转换、编译、算术、位操作、比较、正则表达式等。
  • Heap:运行本地代码需要使用内存堆,堆的内部构成和结构相当复杂,这个在后面的内存管理中会介绍。
  • Mark Compactcollector:垃圾回收机制的主要实现类,用来标记(Mark)、清除(Swep)和整理( Compact)等基本的垃圾回收过程。
  • Sweeper Thread:负责垃圾回收的线程。

image.png
image.png

内存管理

内存划分

对于内存的划分,首先看Zone类,它的特点主要是管理一系列的小块内存。如果用户想使用一系列的小内存,并且这些小内存的生命周期类似,这时可以使用一个Zone对象,这些小内存都是从Zone对象中申请的。Zone对象首先自己申请一块内存,然后管理和分配一些小内存。当一块小内存被分配之后,不能够被Zone回收,只能一次性回收Zone分配的所有小块内存。例如抽象语法树的内存分配和使用,在构建抽象语法树之后,会生成本地代码,然后抽象语法树的内存在这之后被一次性全部收回,效率非常高。但是,该机制有一个非常严重的缺陷,那就是假如这一个过程需要很多的内存,那么zone就需要为系统分配大量的内存,但是又不能够释放,所以这会导致系统出现需要过多的内存而导致内存不够的情况。

垃圾回收机制

image.png

  • 对于年轻分代,主要是为新创建的对象分配内存空间,因为年轻分代中的对象较容易被要求回收,为了方便垃圾回收,可以使用复制方式,将年轻分代分成两半,一半用来分配,另外一半在回收的时候负责将之前还需要保留的对象复制过来。对于年轻分代,经常需要进行垃圾回收。
  • 而对于年老分代,主要是根据需要将年老的对象、指针、代码等数据使用的内存较少地做垃圾回收。
  • 而对于大对象空间,主要是用来为那些需要使用较多内存的大对象分配内存,当然同样可能包含数据和代码等分配的内存,需要注意的是每个页面只分配一个对象。

渲染引擎和JS引擎的冲突

  • setTimeout和 setInterval从不考虑浏览器内部发生了其他什么事,它们只要求浏览器在某个时间之后来调用回调函数,无论浏览器很繁忙或者页面被隐藏(虽然某些浏览器做了这方面的优化,如 Chromium)
  • setTimeout和 setInterval只是要求浏览器做什么,而不管浏览器能不能做到(如主循环有很多事件需要处理),
  • setTimeout和 setInterval可能是出于编程风格方面的考虑。如果每一帧在不同的代码处需要设置回调函数,一个方法是将这些代码统一到一个地方,但是这有点勉为其难,另一个方法是分别用 setInterval设置它们,这个方法的问题是,浏览器可能需要计算更多次,刷新更多次的屏幕。

  • JavaScript调用 requestAnimation Frame,因而相应地, Webkit和 Chromium会调度一个需要绘制下一帧的事件,该事件会将 request Animation Frame的调用上下文和回调函数记录下来。

  • 上面的请求会触发 Chromium更新页面内容的事件,该事件被 mainloop调度处理后,会检查是否需要调用动画的相关处理,因为有动画需要处理,所以会依次调用那些回调函数, JavaScript引擎会更新相应的CSS属性或者DOM树修改。
  • Chromium触发重新计算布局,更新自己的 Renderer树,而后绘制,完成一帧的渲染

    插件和 JS 扩展

    多媒体

  • video:用于视频(当然也包括音频)的播放。

    • trace:WebVtt格式,每个“vdeo”元素可以有多个“ track”元素,每个“ track”元素可以用来表示一种语言。
  • audio:用于单纯的音频播放
  • Webaudio:可以将多个声音合成处理
  • Webrtc(网络实时通信):将照相机、麦克风功能与视频、音频和通信结合起来使用

视频

视频编码格式

  • Ogg是由xiph.org组织开发的一个开放标准,不需要任何授权费用,
    • Theora作为视频编码格式
    • Vorbis作为音频编码格式。
  • MPEG4是MPEG工作组开发的需要授权费用的标准,
    • H264作为视频编码格式
    • AAC作为音频编码式。
  • WebM是由 Google研发的标准,它也是完全免费自由使用的,
    • VP8作为视频编码格式
    • Vorbis作为音频编码格式

image.png
image.png
image.png
image.png

  • 桌面系统:FFmpeg多媒体库
  • 安卓系统:使用系统提供的音视频的渲染框架提供的android.media. MediaPlayer

JS API

  • MediaSource
  • SourceBuffer

音频

音频编码格式

  • Ogg
  • Mp3
  • Wav

Webaudio

  • Source节点: 有一个或多个输入源
  • 中间的所有点都可以看成各种处理过程,它们组成复杂的网。
  • 图中有一个最终节点称为“ Destination”,它可以表示实际的音频设备,每个图只能有一个该类型的节点。

image.png
OsicllatorNode类

  • 它需要对音频数据进行大量计算,包括向量的加法、乘法等。
  • 同时该节点类需要使用 Periodic Wave来计算周期性波形,这里面需要使用到FFT(快速傅立叶变换)算法,因为音频的及时性,网页对性能有非常高的要求。
    • 在 Windows和 Linux上使用 FFmpeg中的高性能算法,在
    • Android上使用 Open Max DL提供的接口来加速,
    • 而在Mac上又是不同的算法。 :::info MIDI是一个通信标准,它是电子乐器之间,以及电子乐器与电脑之间的统一交流协议,用以确定电脑音乐程序、合成器和其他电子音响设备互相交换信息与控制信号的方法。同其他的声音格式不同,MIDI不是记录采样信息,而是记录乐器的演奏指令。 ::: MIDI.js: 使用WebAudio技术和Audo元素来实现音乐的播放。

Web Speech

  • 语音识别技术( Speech-to-Text):SpeechRecognition
  • 合成语音技术( Text-to- Speech):SpeechSynthesis

:::warning 遗憾的是,目前 Chromium中对该规范的实现依赖于 Google API(也就是网络服务接口),这也意味着用户不能离线使用这些功能,因为语音的识别是需要服务器端提供的能力。同时还有一个问题,如果开发者希望自己在 Chromium中编译一个浏览器或者其他应用,可是这些功能是受限的,开发者必须向 Google申请一个称为“APIKeys”的密钥文件,也就是必须获得使用这些 Google API的授权。 :::

webRTC

过程

image.png

  • 音视频输入和输出设备:需要输入和输出设备(麦克风和摄像头)。
    • 输入使用 getUserMedia技术,
    • 输出,基本上可以采用音视频播放的基本框架,当然,需要一些额外的支持。
  • 网络连接的建立:因为通信需要不停地传送大量数据,所以需要建立一种可靠的网络连接来让各个参与方传输数据。
  • 数据捕获、编码和发送:当用户打开设备之后,需要捕获这些数据并对它们进行编码,因为原始数据的数据量太大,然后需要将编码后的数据通过连接传输出去。
  • 数据接收、解码和显示:接收来自其他方的数据流并进行解码,然后显示出来,这个需求跟播放媒体文件的需求比较类似。

    webRTC 开源项目

    http://www.webrtc.org/reference/architecture
    image.png
    开源 libjingle

  • libjingle提供了建立和管理连接的能力,支持透过NAT和防火墙设备、代理等建立连接。

  • ibjingle不仅支持点到点的连接,也支持多用户连接。
  • libjingle底层使用 WebRtc项目的音视频处理引擎。
  • libjingle向外暴露MediaStream接口

image.png

安全机制

网页安全机制

同源策略

网页的DOM对象、个人数据、ⅩMlhttprEqueSt等不支持跨域访问

XSS

HTML在构建DOM的过程中, WebKit使用一个叫做 XSSAuditor的类来做安全方面的检查,它的作用是防止XSS攻击。

:::info xss(Cross SIte Scripting): 执行跨域的JS. 主要原因是浏览器将用户数据变成了可执行的代码。
解决问题的办法就是不信任任何来自用户输入的数据,将可执行的代码字符进行转换。 :::

CSP:定义网页自身能够访问的某些域和资源。

CORS

通过HTTP请求头来允许跨域数据访问。
CORS定义一个网页如何才能访问被同源策略禁止的跨域资源,规定了两者交互的协议和方式。
image.png
image.png
image.png

Cross Document Messaging

Cross Document Messaging定义的是通过 window.postMessage 接口让 JavaScript 在不同域的文档中传递消息成为可能。

安全传输协议(https)

HTPS 是在 HTTP 协议之上使用 SSL(SecureSocketLayer) 技术来对传输的数据进行加密,从而保证了数据的安全性。

SSL 协议是构建在 TCP 协议之上、应用层协议 HTTP 之下的。

SSL 工作的主要流程是先进行服务器认证(认证服务器是安全可靠的),然后是用户认证。
SSL 协议主要是服务提供商对用户信息保密的承诺,这有利于提供商而不利于消费者。同时 SSL 还存在一些问题,例如,只能提供交易中客户与服务器间的双方认证,在涉及多方的电子交易中,SSL 协议并不能协调各方间的安全传输和信任关系。

TLS( Transport Layer Security)是在 SSL3.0 基础之上发展起来的,它使用了新的加密算法,所以它同 Https之间并不兼容。
TLS 用于两个通信应用程序之间,提供保密性和数据完整性,该协议是由两层子协议组成的,包括 TLS 记录协议(TLS
Record)和TLS握手协议( TLS Handshake)。较低的层为 TLS 记录协议,位于 TCP 协议之上。

沙箱模型

:::info 沙箱模型:将网页的运行限制在一个特定的环境中,也就是一个沙箱中,使它只能访问有限的功能。那么,即使网页工作的渲染引擎被攻击,它也不能够获取渲染引擎工作的主机系统中的任何权限的机制。 ::: image.png

沙箱模型是利用系统提供的安全技术,让网页在执行过程中不会修改操作系统或者是访问系统中的隐私数据,而需要访问系统资源或者说是系统调用的时候,通过一个代理机制来完成。

因为沙箱模型严重依赖操作系统提供的技术,即不同操作系统的沙箱模型实现是不一致的。但是都是在进程粒度下实现的,也就是说需要运行在沙箱下的操作都在一个单独的进程中。

所以,对于沙箱模型至少需要2个进程:
image.png

  • 目标进程,也就是需要在沙箱中运行的代码
  • 是代理进程:需要负责创建目标进程并为目标进程设置各种安全策略,同时建立IPC连接,接受目标进程的各种请求,因为目标进程是不能访问过多资源的。

浏览器安全

移动 webkit

HTML5 Touch Events

  • HTML5 Touch Events:定义如何将原始的触控事件以特定的方式传递给 JavaScript引擎,然后再传递给注册的事件响应函数。

image.png

  • “ touches”:表示当前屏幕中包括的所有触控点,“ touches”是一个列表,如果触控点大于1,表示这是一个支持多点触控的设备。
  • “ targetTouches”:表示当前所有起始于当前DOM元素的触控点,也就是如果一个触控点的“ touchstart”事件发生的位置在该元素的区域内,那就会被包含在该列表中
  • “ changed Touches”:表示发生变化的触控点。
    • 如果类型是“ touchstart”,那就包含新的触控点。
    • 如果是“ touchmove”,那就包含发生移动的触控点。
    • 而“ touchend”就是指触控点移出了屏幕。

每个触控点都有以下属性:

  • 标记属性的唯一ID
  • 触控的目标(也就是对于的DOM元素)
  • 屏幕位置
  • 视图中的位置等

这些原始的触控事件同其他的 DOM 事件区别并不是很大,只能注册在 Clickable Element上。

手势事件

而手势事件则是基于这些原始的触控事件的,有开源库Query mobile、 Sencha Touch等:

  • Long Press
  • Pinch
  • Swipe
  • Fling

    meta 标签

    控制缩放
    1. <meta name=viewport content=" user-scalable=no">
    全屏浏览 ```html // safari

// 非Safari window.addEventlistener(‘load’,function(e){ setTimeout(function(){ window.scrollTo(0, 1) }, 1); }, false);

  1. 图标设置
  2. ```html
  3. <link rel="apple-touch-icon-precomposed" href="/path/to/icon/image"/>

响应式设计
其基本思想是根据不同分辨率或者说不同大小的屏幕,设计不同的布局,

Media Queries

新渲染机制

  • Tiled Backing Store

核心思想是使用后端的缓存技术来预先绘制网页和减少网页的重绘动作,也就是使用空间换时间的典型思路。
image.png

  • 线程化渲染
  • 快速移动翻页

    Application Cache

    提供离线浏览网页的内容,同时还能加速资源的访问并加快启动速度。
    它的基本思想是使用缓存机制并缓存那些需要保存在本地的资源,开发者可以指定哪些是需要缓存的资源

    1. <html manifest="app.appcache">
    2. </html>

    :::tips 这个特性已经被废弃,具体可以参考manifest,当前浏览器广泛支持的 Service worker 是一种替代方案,可以提供 AppCache 所提供的离线体验。请参阅迁移策略。 :::

    调试机制

    Chromium 的开发者工具是基于 Webkit 的 Web Inspector 技术开发出来的

  • 功能: 功能调试能够帮助开发者使用单步调试等技术来査找代码中的问题,

  • 性能: 性能调试能够采集性能瓶颈

    Web Inspector的前后端交互协议

    Web Inspector的前端和后端交互信息的协议定义在 Inspector json文件中( Blink则是 protocol. json文件)。
    image.png

  • types:它有点像预先定义的类型,这些类型表示一些特定的数据,在后面的定义中可以声明使用这些类型来表示一定的数据结构,例如图中定义“id”为“ Style Sheeted”,它表示的是一个字符串。在第二个属“commands”中可以看到对它们的引用。

  • commands:定义“ domain”中包含的所有命令,这些命令类似于远程过程调用,表示前端和后端之间发送请求并响应的方式。如图中的toggleProperty”就是一个命令的定义,可以看到它定义了参数的名称和类型,对于第一个参数它引用了“ CSSStyleld”,这就是之前定义在“ types”中的一个类型(图中没有写出来)。该命令还包括一个或者多个返回值,跟参数类似的定义
  • events:它是用来描述事件的,同样可以包含一个或者多个事件,主要是向对方发送当前的一些状态信息,与命令不同的是,它没有也不需要返回值。图中所示是一个表示样式表变化的事件。

image.png

image.png
image.png
image.pngimage.png
Weinre是一个支持远程调试功能的开源项目,它除了能够支持 WebInspector协议,还能够支持 Firebug( Firefox的调试工具)的协议,

tracing机制

chrome: //tracing
这一机制的实现采用的思想非常简单, Tracing机制在 Chromium代码中插入相应的跟踪代码,然后计算开始和结束之间的时间差。

web 前端的未来

:::info 嵌入式模式: 在渲染引擎之上提供层本地(如C艹+或者Java)接口,这些接口提供了渲染网页的能力,渲染的结果被绘制到一个控件或者子窗口中,本地应用通过本地接口来获得渲染网页的能力。 :::

CEF

Chromium embedded framework,是一个开源项目.依赖于 Content APl,提供一套嵌入式的本地代码(C/C艹+等)编程接口.
image.png
CEF3的接口类:

  • Cefclient:它是一个回调管理类,包含5个接口类,用于创建其他的回调类的对象。
    • CefLifeSpanHandler回调类,用于控制弹出对话框的创建和关闭等操作。
    • CefLoadHandler回调类,可以用来监听 frame的加载开始、完成、错误等信息。
    • CefRequestHandler回调类,用于监听资源加载、重定向等信息。
    • CefDisplayHandler回调类,用于监听页面加载状态、地址变化、标题等信息。
  • CefGeolocationHandler回调类,用于CEF3向嵌入者申请地理位置等权限。
  • CefApp: 与进程、命令行参数、代理、资源管理相关的回调类,用于让CEF的调用者们定制自己的逻辑。
  • CefBrowser: 是 Renderer进程中执行浏览相关的类,如网页的前进、后退等。
  • CefBrowserHost: Browser进程中的执行浏览相关的类,它会把请求发送给CefBrowser类。
  • CefFrame:该类表示的是页面中的一个网页框( Frame),可以加载特定URL,在该运行环境下执行 JavaScript代码等。
  • V8:CEF3提供支持V8扩展的接口,但是这里有两个限制。第一,V8扩展仅在 Renderer进程使用;第二,仅在沙箱模型关闭时才使用。