Web测试中必不可少的天天打交道的一个应用就是浏览器,它是由哪些部分组成的呢?
· 用户接口 – 包括地址栏,前进后退,书签菜单等窗口上除了网页显示区域以外的部分。
· 浏览器引擎 – 查询与操作渲染引擎的接口。
· 渲染引擎 – 负责显示请求的内容。
· 网络 – 用于网络请求, 如HTTP,HTTPS请求。
· UI后端 – 绘制基础元件,如组合框与窗口。它提供平台无关的接口,内部使用操作系统的相应实现。
· JavaScript解释器 – 用于解析执行JavaScript代码。
· 数据存储 – 这是一个持久层。浏览器需要把所有数据存到硬盘上,如cookies,图片,css等。新的HTML规范 (HTML5) 规定了一个完整(虽然轻量级)的浏览器中的数据库:’web database’。
各种渲染引擎
Firefox, Safari两种浏览器构建于两种渲染引擎之上:Firefox使用Gecko —— Mozilla自家的渲染引擎;Safari 和 Chrome 都使用 Webkit,而Chrome曾放出重磅消息,将从开源的Webkit上分叉出自己的开源浏览器引擎Blink,Opera宣布跟随Google Chrome的脚步,将弃用自家的Presto引擎,支持Blink引擎,而IE使用的是Trident内核。众多国内主流浏览器使用的双引擎一般都是Webkit和Trident两种内核。
渲染原理
基本工作流为:
1. 解析HTML构建DOM树:
会解析三个东西:HTML/SVG/XHTML,CSS及javascript。解析CSS会产生CSS规则树,解析javascript主要是通过DOM API和CSSOM API来操作DOM Tree和CSS
2. Rule Tree渲染树构建:
解析完成后,浏览器引擎会通过DOM Tree 和 CSS Rule Tree 来构造 Rendering Tree。不过,Rendering Tree 渲染树并不等同于DOM树,因为一些像Header或display:none的东西就没必要放在渲染树中了。CSS 的 Rule Tree主要是为了完成匹配并把CSS Rule附加上Rendering Tree上的每个Element。也就是DOM结点。
3. 渲染树布局:
计算每个element确切的显示位置,也就是layout和reflow的过程
4. 绘制渲染树:
通过调用操作系统Native GUI的API绘制将每一个节点绘制出来
看起来步骤繁琐,但是为了更好的用户体验,浏览器会尽可能快的把内容显示出来,并不会等到所有的HTML解析完后才创建并布局渲染树,它会在处理后续内容的同时把处理过的局部内容先展示出来。
一个过程
1. 用户第一次访问网址,浏览器向服务器发出请求,服务器返回html文件;
2. 浏览器开始载入html代码,发现<head>标签内有一个<link>标签引用外部CSS或JS文件;
3. 浏览器又发出CSS及JS文件的请求,服务器返回这个CSS,JS文件;
4. 浏览器继续载入html中<body>部分的代码,并且CSS,JS文件已经拿到手了,可以开始渲染页面了;
5. 浏览器在代码中发现一个<img>标签引用了一张图片,向服务器发出请求。此时浏览器不会等到图片下载完,而是继续渲染后面的代码;
6. 服务器返回图片文件,由于图片占用了一定面积,影响了页面布局,因此浏览器需要回过头来重新渲染这部分代码;
7. 浏览器发现了一个包含一行Javascript代码的<script>标签,赶快执行它;
8. Javascript脚本执行了这条语句,它命令浏览器隐藏掉代码中的某个<div> (style.display=”none”)。杯具啊,突然就少了这么一个元素,浏览器不得不重新渲染这部分代码;
9. 终于等到了</html>的到来,浏览器泪流满面……
Reflow及Repaint
页面在加载的过程中,需要对文档结构进行解析,同时需要结合各种各样的样式来计算这个页面长什么样子,最后再经过浏览器的渲染页面就出现了。而整个过程充满了repaint和reflow。对于DOM结构中的各个元素都有自己的盒子(模型),这些都需要浏览器根据各种样式(浏览器的、开发人员定义的等)来计算并根据计算结果将元素放到它该出现的位置,这个过程称之为reflow;当各种盒子的位置、大小以及其他属性,例如颜色、字体大小等都确定下来后,浏览器于是便把这些元素都按照各自的特性绘制了一遍,这个过程称之为repaint。
reflow 会从<html>开始递归往下,依次计算所有的结点几何尺寸和位置,在reflow过程中,可能会增加一些frame,比如一个文本字符串需被包装起来。
Reflow的成本比Repaint的成本高得多的多。DOM Tree里的每个结点都会有reflow方法,一个结点的reflow很有可能导致子结点,甚至父点以及同级结点的reflow。所以过多的reflow会导致CPU性能问题。
基本上来说,reflow有如下的几个原因:
· 网页初始化增加、删除、修改DOM结点时
· 移动DOM位置或操作动画时
· 一些Javascript在操作DOM Tree时
· Resize窗口或滚屏时
· CSS的样式发生变化时
· 修改网页默认字体时
但是display:none会触发reflow,而visibility:hidden只会触发repaint,因为没有发现位置变化
可能出现的bug
当然,如果只是介绍上面的内容,我也不用白费工夫了,因为网上一搜一大片,最主要的是想说说可能会遇到的bug:
· 因图片未设置宽和高而又加载失败时可能会影响到页面样式;
· 未设置宽高的图片在加载完后需reflow会影响页面性能
· 待页面未完全加载完时去操作页面最重要的功能,可能会因JS加载顺序问题无法正确执行,从而功能异常
· 操作浏览器放大缩小resize窗口,可能会出现样式问题
· 是否有遇到某一个样式或图片在加载过程中闪现,但是加载完后就消失了