浏览器原理

第一部分:shell外壳:菜单,工具栏等;

第二部分:内核

 

浏览器的组件:

  1. 用户界面:浏览器软件界面;
  2. 浏览器引擎:查询及操作渲染引擎的接口;
  3. 渲染引擎:显示请求内容,即 渲染html组件;
  4. 网络:完成网络调动,发送和响应http请求;
  5. js解释器:编译执行js代码;
  6. UI后端:操作系统的组件,如:下拉列表框和窗口
  7. 数据存储:浏览器持久层:cookie  localstorage sesionstorage
               

渲染引擎:

基本主流程:

请求html ->解析html--加载外部样式及外部脚本-> 构建DOM树->构建render树(dom+cssom树)->绘制render树;

 

(外部样式会阻塞内部脚本的执行。 

外部样式与外部脚本并行加载,但外部样式会阻塞外部脚本执行。)

 

 

不同的内核渲染的流程不一样,webkit:

 

 

 

编译流程:

源码->解析->解析树->转换->机器码

解析原理:

转换成一定意义的结构:编码可以理解和使用的东西。

解析的结果通常是表达文档结构的节点树,解析书或语法树。

解析两个子过程:

  1. 词法解析;
  2. 语法解析

解析树=词法解析+语法解析+…的过程。

转换:把解析书转换为机器码;

 

那么,html解析原理:

特殊性:

  1. html语言的宽容性;
  2. 浏览器对html语言的容错机制(修复);
  3. Html过程的往复性,解析过程可对输入的文档紧进行修改:document.write等;

 

html解析算法两个阶段:

第一:符号化;

第二:构件树;

css解析:selector: p  p-txt  ,  declaration: 3px  margn…

脚本解析<script>:

  1. web的模式是同步的,开发者希望解析到一个script标签时立即解析执行脚本,并阻塞文档的解析直到脚本执行完。
  2. 如果脚本是外引的,则网络必须先请求到这个资源——这个过程也是同步的,会阻塞文档的解析直到资源被请求到;

所以render树渲染后再调<script>,放在htmlz最后;

预解析:

  1. 当执行脚本时,另一个线程解析剩下的文档,并加载后面需要通过网络加载的资源。这种方式可以使资源并行加载从而使整体速度更快。
  2. 预解析并不改变Dom树,它将这个工作留给主解析过程,自己只解析外部资源的引用,比如外部脚本、样式表及图片

渲染树的构建(rendertree):渲染对象RenderObject ;

渲染树和dom树的关系:

 

具体详情:

  1. 遍历dom树,忽略<head>和节点display:none;
  2. 对每一个可见的dom,找到对应的cssom,并且应用样式;
  3. 最后输出一个渲染树rendertree包括:显示可见的节点及内容和信息;

css优先顺序,从低到高有:

1. 浏览器默认样式

2. 用户个性化浏览器设置

3. HTML开发者定义的一般样式

4. HTML开发者定义的!important样式

5. 用户个性化浏览器设置!important样式

 

渲染对象和对应的DOM节点也可能不在相同的位置。例如,浮动和绝对定位的元素在文本流之外。

 

  1. 怎么样解决css数据庞大,占大量内存?
  2. 和每个元素匹配规则导致性能问题?
  3. 应用规则及复杂的联级关系?

 

共享样式;

进化匹配过程;

以正确的级联顺序;

逐步处理。

 

布局layout

当渲染对象被创建并添加到树中,他们斌更没有位置和大小,计算这些值得过程称为layout或reflow。每一个渲染对象都有一个layout或reflow方法,出发布局时调用。

layout过程:

  1. 计算自身宽高;
  2. 读取设置的children,并判断其dirty状态,选择渲染dirty的子对象。
  3. 根据子对象积累高度,margin和padding来设置自己的高度供给parent对象使用;
  4. 更新dirty标识为false;

Dirty bit系统:一个渲染对象发生变化时就标记它和它的children为dirty,表示需要layout。目的:不因每个小变化就全部重新布局。

绘制painting

遍历渲染树并调用渲染对象的pain方法将他们的内容显示到屏幕上;

绘制顺序:

一个块渲染对象的堆栈顺序为:

  1. 背景色;
  2. 背景图;
  3. Border;
  4. Children
  5. Outline

 

动态变化:浏览器总是试着以最小的动作响应一个变化,所以就存在有些属性只改变单个渲染对象就:字体、颜色、等;但也有些属性修改会导致大面积的重绘:位置。

线程和事件:

浏览器是多线程的,渲染引擎和js是单线程的。其中渲染引擎则是浏览器的主线程;

浏览器的主线程是一个事件循环,他被设计为无限循环以保持执行过程的可用:等待时间并执行他们。

 

 

浏览器执行的是多线程,js引擎解释器的执行时单线程。所以说浏览器是单线程的说法不对。

你可能感兴趣的