从基础做起--浏览器渲染

    作为一个小白很早就关注前端的相关知识,虽然在各类博客汲取不少知识,但感觉还是需要亲自整理一些知识点,才能更加熟练

用学到手的东西。在去年校招期间有招聘方涉及到浏览器的渲染,当时只懂一点js+css,了解的不够深入,尽管在有大神整理出

清晰的文章,在下还是决定亲自读一下《浏览器工作原理》,话不多说,先从浏览器构成开始。


    浏览器的主要构成(High Level Structure


         浏览器的主要组件包括:

        1. 用户界面 - 包括地址栏、后退/前进按钮、书签目录等,也就是你所看到的除了用
            来显示你所请求页面的主窗口之外的其他部分。

        2. 浏览器引擎 - 用来查询及操作渲染引擎的接口。

        3. 渲染引擎 - 用来显示请求的内容,例如,如果请求内容为html,它负责解析html
            及css,并将解析后的结果显示出来。

        4. 网络 - 用来完成网络调用,例如http请求,它具有平台无关的接口,可以在不同
            平台上工作。

        5. UI后端 - 用来绘制类似组合选择框及对话框等基本组件,具有不特定于某个平台
            的通用接口,底层使用操作系统的用户接口。

        6. JS解释器 - 用来解释执行JS代码。

        7. 数据存储 - 属于持久层,浏览器需要在硬盘中保存类似cookie的各种数据,
            HTML5定义了web database技术,这是一种轻量级完整的客户端存储技术。

        如图 1.1 所示


 图 1.1


         在众多浏览器中,Chrome 浏览器为每个Tab分配了各自的渲染引擎实例,每个Tab就是一个独立的进程。什么是渲染引擎?


    渲染引擎(The rendering engine


     主流程(The main flow)

        在取得通过网络请求的文档以后,渲染引擎的基本流程:


         解析html构建dom

                       ↓

             构建render

                       ↓

             布局render

                       ↓

             绘制render 树


 如图 1.2 所示


        

                                                                                                                 图1.2


       渲染伊始,解析html标签,生成DOM结构,然后解析CSS层叠样式表,根据结果构建Render树Render树由一些包含有颜色和大小等属性的矩

形组成,按顺序排列,然后开始布局,确定结点的坐标,最后绘制,遍历Render树,使用UI后端绘制。

       注意这个过程是边解析边显示的,并非解析完所有结构才显示网页内容。


   渲染树和Dom树的关系(The render tree relation to the DOM tree


        渲染对象和元素相对应,但这种对应关系不是一对一的,不可见的DOM元素不会被插入渲染树,例如head元素。另

外,display属性为none的元素也不会在渲染树中出现visibility属性为hidden的元素将出现在渲染树中)。

        还有一些DOM元素对应几个可见对象,它们一般是一些具有复杂结构的元素,无法用一个矩形来描述。例如,select元素有三

个渲染对象——一个显示区域、一个下拉列表及一个按钮。同样,当文本因为宽度不够而折行时,新行将作为额外的渲染元素被添

加。另一个多个渲染对象的例子是不规范的html,根据CSS规范,一个行内元素只能仅包含行内元素或仅包含块状元素,在存在混

合内容时,将会创建匿名的块状渲染对象包裹住行内元素。一些渲染对象和所对应的DOM节点不在树上相同的位置,例如,浮动和

绝对定位的元素在文本流之外,在两棵树上的位置不同,渲染树上标识出真实的结构,并用一个占位结构标识出它们原来的位置。


        如图 1.3 所示


                                                                                                               图 1.3


   创建树的流程(The flow of constructing the tree

        处理htmlbody标签将构建渲染树的根,这个根渲染对象对应被 CSS规范称为containing block的元素——包含了其他所有

块元素的顶级块元素。它的大小就是viewport——浏览器窗口的显示区域,文档指向的渲染对象。

    样式计算(Style Computation 

        样式数据是非常大的结构,保存大量的样式属性会带来内存问题。不进行优化,找到每个元素匹配的规则会导致性能问题。

    Specifity

        CSS2规范中定义的选择符specifity如下:

        如果声明来自style属性,而不是一个选择器的规则,则计1,否则计0(=a

        计算选择器中id属性的数量(=b

        计算选择器中class及伪类的数量(=c

        计算选择器中元素名及伪元素的数量(=d

        连接abcd四个数量(用一个大基数的计算系统)将得到specifity,根据改值确定优先级。


    布局

        当渲染对象被创建并添加到树中,它们并没有位置和大小,计算这些值的过程称为layout(webkit) reflow(Gecko)

Html使用基于流的布局模型,意味着大部分时间,可以以单一的途径进行几何计算。流中靠后的元素并不会影响前面元素的几何特

性,所以布局可以在文档中从右向左、自上而下的进行。也存在一些例外,比如html tables

        坐标系统相对于根frame,使用topleft坐标。布局是一个递归的过程,由根渲染对象开始,它对应html文档元素,布局

继续递归的通过一些或所有的通过一些或所有的frame层级,为每个需要几何信息的渲染对象进行计算。所有的渲染对象都有一

layoutreflow方法,每个渲染对象调用需要布局的childrenlayout方法。

    Dirty bit系统

        为了不因为每个小变化都全部重新布局,浏览器使用一个dirty bit系统,一个渲染对象发生了变化或是被添加了,就标记它及

它的childrendirty——需要layout。存在两个标识——个标识——dirtychildren are dirtychildren are dirty说明即使

这个渲染对象可能没问题,但它至少有一个没问题,但它至少有一个child需要layout。

    全局和增量layout

        当layout在整棵渲染树触发时,称为全局layout,这可能在下面这些情况下发生:

        1.一个全局的样式改变影响所有的渲染对象,比如字号的改变。

        2.窗口resize

        layout也可以是增量的,这样只有标志为dirty的渲染对象会重新布局(也将导致一些额外的布局)。增量layout会在渲染

对象dirty时异步触发,例如,当网络接收到新的内容并添加到容并添加到DOM树后,新的渲染对象会添加到渲染树中。


   layout过程

        layout一般有下面这几个部分:

        1. parent渲染对象决定它的宽度

        2. parent渲染对象读取chilidren,并:

        a.放置child渲染对象(设置它的xy)。

        b.在需要时(它们当前为dirty或是处于全局layout或者其他原因)调用child渲染对象的layout,这将计算child的高度

        c. parent 渲染对象使用 child 渲染对象的累积高度,以及marginpadding的高度来设置自己的高度-这将被parent渲染

            对象的 parent 使用。

        d.dirty标识设置为false。

    Line breaking

        当一个渲染对象在布局过程中折行时,则暂停告诉它的 parent 需要折行,parent将创建额外的渲染对象并调用它的layout。


    绘制(Painting

        绘制阶段,遍历渲染树并调用渲染对象的 paint 方法将它们的内容显示在屏幕上,绘制使用UI基础组件。

    全局和增量

        和布局一样,绘制也可以是全局的——绘制完整的树——或增量的。在增量的绘制过程中,一些渲染对象以不影响整棵树的方

式改变,改变的渲染对象使其在屏幕上的矩形区域失效,这将导致操作系统将其看作dirty区域,并产生一个paint事件,操作系

统很巧妙的处理这个过程,并将多个区域合并为一个。Chrome中,这个过程更复杂些,因为渲染对象在不同的进程中,而不是在

主进程中。Chrome在一定程度上模拟操作系统的行为,表现为监听事件并派发消息给渲染根,在树中查找到相关的渲染对象,重

绘这个对象(往往还包括它的 children)。

    绘制顺序

         这个是元素压入堆栈的顺序,这个顺序影响着绘制,堆栈从后向前进行绘制。

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

         1. 背景色

         2. 背景图

         3. border

         4. children

         5. outline


    渲染引擎的线程

        渲染引擎是单线程的,除了网络操作以外,几乎所有的事情都在单一的线程中处理,在FirefoxSafari中,这是浏览器的主

线程,Chrome中这是tab的主线程。网络操作由几个并行线程执行,并行连接的个数是受限的(通常是26个)。


    定位策略Position scheme

        这里有三种策略:

        1. normal-对象根据它在文档中位置定位,这意味它在渲染树和在DOM树中位置一致,根据它的盒模型和大小进行布局。

        2. float-对象先像普通流一样布局,然后尽可能的向左或是向右移动

        3. absolute-对象在渲染树中的位置和DOM树中位置无关。

        staticrelativenormalabsolutefixed属于absolutestatic定位中,不定义位置而使用默认的位置。其他策

略中,作者指定位置——top、bottomleftright


    Layered representation

        这个由CSS属性中的z-index指定,表示盒模型的第三个大小,即在z轴上的位置。Box分发到堆栈中(称为堆栈上文),

每个堆栈中靠后的元素将被较早绘制,栈顶靠前的元素离用户最近,当发生交叠时,将隐藏靠后的元素。堆栈根据z-index属性排

序,拥有z-index属性的box形成了一个局部堆栈,viewport有外部堆栈。

        




     






  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值