chromium 柒

 主流浏览器市场份额

根据Net Applications公司分析,2016年12月全球浏览器市场份额如下图

2016年12月全球浏览器市场份额

其中Chrome已经占据56%市场,而IE下滑到20%。开源浏览器Chrome Safari Firefox之和达到72%之多。

在开源越来越流行的当下,开源浏览器也是越来越受欢迎。

2 主流浏览器内核分析

现今五大主流浏览器IE、Firefox、Safari、Chrome及Opera的内核分别如下:

  • IE:Trident,1997年首次在IE4中搭载,微软在Mosaic之上修改代码而成。Mosaic是后来鼎鼎有名的NetScape的前身。由于早期占据了绝大部分的市场份额,Trident很长一段时间都没有更新。这也引发了被无数前端开发者吐槽的问题,Trident与W3C标准基本脱节,IE的兼容性问题永远是一个让人头疼的问题。
  • 这也使得其他浏览器,如Firefox崭露头角。很多国产浏览器,如QQ浏览器,搜狗浏览器等都是基于它。
  • Firefox: Gecko,基本只用于Firefox浏览器
  • Opera:早期使用Presto内核,现在已经更换为Blink内核。Blink是Google在Webkit基础上开发的开源内核,后面会重点介绍
  • Safari:Webkit,苹果开发的浏览器内核,并于2005年开放源代码。Chrome的Blink也是基于Webkit开发的,差异性不是特别大,也可以认为是Webkit内核浏览器。由此可见Webkit的重要性,我们后面的几篇文章会基于Webkit来分析浏览器内核。
  • Chrome:Blink,谷歌基于Webkit开发的开源内核。Chrome最初是基于Webkit的,后来越来越觉得Webkit过于保守,因此单独拉取了Blink分支。Blink在多进程架构,JavaScript引擎方面都与Webkit有比较大的差别。但二者都是遵守W3C标准的,因此开发者不用考虑二者兼容性问题。现在很多国产浏览器,如QQ,360都是采用Trident和Blink两个内核。
  • 移动端:ios和Android 4.4以前平台使用Webkit内核,Android4.4及以后版本使用Blink。

3 浏览器主要构成

浏览器主要组件包括以下几方面:

  1. 用户界面:与用户交互,如前进 后退 书签等,这部分不包括在内核中
  2. 网络:用来完成网络请求,如http请求,获取网络资源。
  3. HTML解析器:用来解析HTML文件,并构建DOM树
  4. CSS解析器:用来解析CSS文件,得到CSS规则匹配集
  5. JS引擎:编译和运行代码,编译占用的是用户时间,这一点与Java等静态编译语言不同。编译阶段将字符串解析为抽象语法树,然后解析为中间字节码或者本地代码
  6. 渲染单元:构建RenderObject树,分为布局和绘制两个部分。绘制结果为保存在内存中的Bitmap。
  7. 数据存储:持久层。浏览器可能将Cookie等数据保存在硬盘中。也需要支持HTML5的Local Storage存储技术。

4 浏览器网页加载流程简单分析

现在简单分析下从用户输入url地址到网页展现出来这段过程浏览器都做了哪些事情,每个阶段后面都有文章具体分析。

    1. 资源加载:用户输入URL后,浏览器首先要加载HTML CSS JS PNG等资源文件。 
      1)首先以URL为key在内存缓存和磁盘缓存中查找,命中则直接结束 
      2)未命中,则根据scheme来请求资源。file:// 为本地资源,http:// 则通过发送http请求来获取资源

    2. HTML解析器构建DOM树 
      1)HTML字节流解码变为字符流。根据不同编码方式,如UTF-8 GBK来解码 
      2)词法分析:将字符流解析为一个个词语 
      3)语法分析:通过不同标签,生成node节点 
      4)构建DOM树:将node节点组织成DOM树

    3. CSS解析器读取CSS文件,得到元素最匹配的样式 
      1)经过词法分析和语法分析,生成一个个CSS规则。规则由选择器和一个key:value对组成的属性集合构成 
      2)进行规则匹配:根据元素信息,如id class 标签,通过不同优先级得到元素最匹配的CSS规则

    4. JS引擎编译并运行代码 
      1)编译:针对目前执行到的代码,先将源码编译为抽象语法树,然后编译为中间字节码或本地代码。Webkit基于的JavaScriptCore引擎编译为字节码,而Blink基于的V8引擎比较激进,直接编译为本地代码 
      2)运行:执行字节码或本地代码。涉及到内存分配,指令执行等很多过程。运行阶段也会做后期优化,比如JavaScriptCore将运行比较频繁的字节码即时编译为本地代码(称为JIT,JVM中也会用到)。

    5. 渲染:生成RenderObject树,并进行布局和绘制 
      1)生成RenderObject树:由DOM树构建RenderObject树,并将CSS得到的元素匹配的样式存入到RenderObject中。 
      2)布局:根据RenderObject中的样式属性,先测量元素的宽高,这个过程一般需要递归,因为父元素的大小会受到子元素影响。然后计算根据框模型,由paddind border margin计算布局 
      3)绘制:先绘制元素背景,然后是浮动部分,最后是前景(content,padding,border等部分)。最后得到了用户可见区域(ViewPort)的内存表示。

    6. 得到图像:根据渲染得到的图像内存表示,调用显示屏驱动等模块绘制到用户界面上。

猜你喜欢

转载自www.cnblogs.com/dhsz/p/9252851.html