WEB前端底层知识之浏览器是如何工作的

    概述

    对于一直从事B/S(其实我感觉BS也是一种CS架构,只不过CS自己写显示而BS有相对统一的显示引擎实现而已)模式WEB领域的开发人员来说,浏览器Browser再熟悉不过了。不管你是JAVA流还是微软流抑或PHP流,WEB开发新流派。不论你的服务器端采用哪种业务架构,ORACLE数据库还是MSSQL,站在用户的角度思考,这个才是他们直接能接触到的,前端的用户体验给了用户直观的印象,投其所好,我们也总少不了要跟它打交道,很多问题的根源皆来源于此,了解一下其内部执行原理,也许对我们的开发工作会事半功倍,从一位纯粹的开发人员到一位技术领域的专家,也许就在于这些细节中。

  接下来的文章系列里,我将要给大家讲述一下浏览器是如何在后台默默工作的。当我们在浏览器地址栏中输入'oschina.net'直到从浏览器视图区域browser screen见到我们想要的结果这个过程中,浏览器内部是如何实现的。

  浏览器种类

  我们现在经常使用的主要有5种浏览器,Internet Explorer,Firefox,Safari,Chrome跟Opera,包含了市面上3种主流的浏览器网页排版引擎,WebKi(chrome,safari,opera),Gecko(Mozilla,Firefox 等使用的排版引擎)和Trident(也称为MSHTML,IE 使用的排版引擎)。(详见http://www.cnblogs.com/liuzijing688/archive/2008/05/18/1201755.html)。其中Firefox,Chrome ,Safari三款浏览器部分源代码是开源的,一些分析工作正式基于其源码进行的分析。顺便说一句, Chrome等开源浏览器市场中所占的份额越来越高(见http://www.w3schools.com/browsers/browsers_stats.asp), HTML5前端开发利器的推出,HTML支持标准的逐渐统一,IE6(7,8)等低版本的逐渐淘汰,也许往后针对CSS HACK等兼容性场景的需求会越来越少,专注于实现而不是专注于兼容,提高我们的效率,体现思想价值核心,这才是开发人员真正该干的事。站在用户的角度来思考,只是稍微改变一下操作方式换来的是真正的产品易用性与安全性的提升,也是一件好事。

  浏览器的主要职责

  浏览器,我们天天在用,可是如果哪天面试一个WEB领域的开发,要你说出他的职责,未必人人都能一下子清楚的表述出来。我觉得浏览器的首要功能就是把用户想要的各种形式WEB资源确认无误的显示出来,通常我们见到的资源格式主要是HTML,当然还包括PDF,图片,视频等,资源的定位通过URI来实现(Uniform resource Identifier)。

  W3C (World Wide Web Consortium) 组织制定了一套HTML/CSS规范,清楚的描述了浏览器如何解释HTML文件以及如何去显示它,W3C 也是WEB领域标准协议的制定组织。目前我们常见的HTML主要为  HTML4.01跟XHTML1.0,由1999年推出(http://www.w3.org/TR/html401/)。 HTML5 规范现在仍处于发展阶段,虽然已接近尾声且各大主流浏览器都有所支持,但仍不是很完善。目前CSS也主要是CSS2.0((http://www.w3.org/TR/CSS2/),     随着时间的推移,硬件的发展,软件行业的进步,HTML5/CSS3黄金组合一定会流行起来的,同样,CSS版本3进行中。以前的浏览器市场是百花争艳,百家齐鸣,往往只支持大部分的规范内容同时还在发展各自的拓展,这对于WEB开发人员和最终用户来说带来了严重的兼容性问题。幸好,现如今大多数的浏览器渐渐的修正了这一错误行为。

  各大浏览器之间有很多共同点,其中公共的界面元素有:

  1. 地址栏
  2. 前进,后退按钮
  3. 书签设置
  4. 刷新,停止按钮
  5. 主页按钮

  从浏览器界面上来看,没有相关的规范竟然能做到如此的一致,确实很奇怪。这正是各大浏览器厂商多年来相互的模仿导致的。HTML5协议并未约束浏览器要有哪些界面元素,只是列出了一些常用的,比如地址栏,状态栏,工具栏。当然各浏览器都有一些各自的特性,如firefox的下载管理器。更多的介绍起参见以后的Browser User interface(浏览器界面元素)章节,此处不再累牍。

  上面说了我们看到的浏览器大体情况,接下来再谈谈浏览器的主要组件有哪些,相互间的关系是怎样的。

  浏览器的基础架构

  1. 界面元素(或界面控件) – 包括地址栏,前进后退,书签菜单等窗口上除了网页显示区域以外的部分。
  2. 浏览器引擎 – 查询与操作渲染引擎的接口。
  3. 渲染引擎 – 负责显示请求的内容。比如请求到HTML, 它会负责解析HTML 与 CSS 并将结果显示到窗口中。
  4. 网络 – 用于网络请求, 如HTTP请求。它包括平台无关的接口和各平台独立的实现。
  5. UI后端 – 绘制基础元件,如组合框与窗口。它提供平台无关的接口,内部使用操作系统的相应实现。
  6. JavaScript解释器。用于解析执行JavaScript代码。
  7. 数据存储。这是一个持久层。浏览器需要把所有数据存到硬盘上,如cookies。新的HTML规范 (HTML5) 规定了一个完整(虽然轻量级)的浏览器中的数据库:’web database’。

  需要注意的是,与其它浏览器不同chrome使用多个渲染引擎实例,每个Tab页一个,即每个Tab都是一个独立进程。

    渲染过程

    用户请求的资源通过浏览器的网络层到达渲染引擎后,渲染工作开始。每次渲染文档通常不会超过8K的数据块,其中基础的渲染流程图如下:       

  

  渲染引擎首先解析HTML文档,转换为一棵DOM树,此为第一步。接下来不管是内联式,外联式还是嵌入式引入的CSS样式也会被解析,渲染出另外一棵用于渲染DOM树的树-渲染树(render tree) ,渲染树包含带有颜色,尺寸等显示属性的矩形,这些矩形的顺序与显示顺序一致。然后就是对渲染树的每个节点进行布局处理,确定其在屏幕上的显示位置。最后就是遍历渲染树并用上一章提到的UI后端层将每一个节点绘制出来。

  以上步骤是一个渐进的过程,为了提高用户体验,渲染引擎试图尽可能快的把结果显示给最终用户。它不会等到所有HTML都被解析完才创建并布局渲染树。它会在从网络层获取文档内容的同时把已经接收到的局部内容先展示出来。

    更具体的流程可能与不同渲染引擎有关,webkit的如下

    

    DOM树

    DOM对于前端JAVASCRIPT开发人员来说也许再熟悉不过了,DOM全称为Document Object Model,即我们所说的文档对象模型。我们可以把它看做是HTML元素对外的接口,有了这些接口javascript开发人员才能够实现复杂的页面功能。DOM树的根节点是Document对象。

    Render树 

    浏览器在构造DOM树的同时也在构造着另一棵树-Render Tree,与DOM树相对应暂且叫它Render树吧,我们知道DOM树为javascript提供了一些列的访问接口(DOM API),但这棵树是不对外的。它的主要作用就是把HTML按照一定的布局与样式显示出来,用到了CSS的相关知识。从MVC的角度来说,可以将render树看成是V,dom树看成是M,C则是具体的调度者,比HTMLDocumentParser等。

    DOM树与Render树

    可以这么说,没有DOM树就没有Render树,但是它们之间可不是简单的一对一的关系。我们已经知道了render树是用于显示的,那不可见的元素当然不会在这棵树中出现了,譬如<header>,您还能想到哪些呢?除此之外,diplay等于none的也不会被显示在这棵树里头,但是visibility等于hidden的元素是会显示在这棵树里头的,可以自己想一下为什么。说了这么多render树,我们还没见一下它的真容呢,它到底会是个什么模样呢?我们看一下图。

 

  与DOM对象类型很丰富啊,什么head,title,div,而Render树相对来说就比较单一了,毕竟它的职责就是为了以后的显示渲染用嘛。从上图我们还可以看出,有些DOM元素没有对应的renderer,而有些DOM元素却对应了好几个renderer,对应多个renderer的情况是普遍存在的,就是为了解决一个renderer描述不清楚如何显示出来的问题,譬如select元素,我们就需要三个renderer,one for the display area, one for the drop down list box and one for the button。

  上图中还有一种关系未可看出,即renderer与dom元素的位置也可能是不一样的。说的就是那些添加了float:---或者position:absolute的元素,因为它们脱离了正常的文档流顺序,构造Render树的时候会针对它们实际的位置进行构造。

    布局与显示

    上面确定了renderer的样式规则后,然后就是重要的显示因素布局了。当renderer构造出来并添加到render树上之后,它并没有位置跟大小信息,为它确定这些信息的过程,我们就称之为布局。

    拿到一个HTML页面,明确了页面要实现的功能之后,首先开始动手做的就是布局啦,其它譬如背景图片,字体,文字啦之类的样式问题还好说,布局却是让人有点感觉经常与其打交道却经常的感觉驾驭不了它,至于界面逻辑或者交互设计虽然也比较难但是至少能让人摸着头脑,所以有必要细说一下这个布局。平时大家浏览网页遇到好看的布局也一定要多花点时间去分析分析它,非前端开发人员多掌握一点界面设计或者交互设计之类的知识未尝不是一件好事,更何况现在好多情况都是一套软件产品从设计到出品整套制造过程都要参与,很有收缩性。

    浏览器进行页面布局基本过程是以浏览器可见区域为画布,左上角为(0,0)基础坐标,从左到右,从上到下从DOM的根节点开始画,首先确定显示元素的大小跟位置,此过程是通过浏览器计算出来的,用户CSS中定义的量未必就是浏览器实际采用的量,除非熟知了浏览器的计算规则,但灵活的布局方式却是靠经验等得来的。如果显示元素有子元素得先去确定子元素的显示信息,如果页面布局完后有改动能不整体重新布局就不重新布局,当然由于脚本或者用户操作也有可能随时会被重新布局,那就回到了本段路起点。

    高度和宽度

    显示元素的高度(height),宽度(width)的确定。

    最终所有显示元素被构建成一个盒子类似的东西构成了整个布局效果,盒子模型效果图如下:

 

    Box Model详细描述可见http://www.w3.org/TR/CSS2/box.html

    BOX TYPE

    每个显示元素上还有一个重要属性就是display及z-index,display不同的类型使用不同的渲染方式,即使没有手动去指定它本身也会存在一个默认值,具体默认值情况请参见 http://www.w3.org/TR/CSS2/sample.html.

    定位方案,坐标值(left,top)

    Normal--定位基于基本布局过程,从左到右,从上到下递增实现。

    Float--脱离正常文档流,居最左或居最右。

    Absolute--其位置信息由用户指定。

    有了size(width,height),position(left,top),box type(display:none,inline,block..e.t.c)一个显示元素基本就最终确定了。

 

    布局完成后,浏览器将结果渲染出来,最终我们看到了眼前的页面。




转载于:https://my.oschina.net/u/924512/blog/119955

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值