世界上第一款浏览器WorldWideWeb由Berners-Lee李爵士于1990发明。如今二十多年过去,浏览器也经历了迅猛的发展,派生出许多功能。然而其根本作用,还是以页面的形式呈现网络内容。下面本文将简单谈谈浏览器是怎样渲染页面的。
浏览器的组成
目前市面上的浏览器主要有IE,Chrome,Firefox,Safari,Opera及国内的360,UC,搜狗等等。虽功能上各有千秋,但基本组成模块大致不差,主要有如下及部分:
- 用户界面(User Interface):包含地址栏、前进后退按钮,书签栏等等,用于与用户交互。
- 浏览器引擎(Browser Engine):用于查询和控制渲染引擎。
- 渲染引擎(Rendering Engine):用于解析并呈现用户请求的内容。
- 网络(Networking):用于处理网络调用,比如发起HTTP请求。
- UI后端(UI Backend):用于绘制浏览器的一些基本组件,其底层使用的是操作系统的用户接口。
- JavaScript解析器 (JavaScript Interpreter):用于解析并执行JS代码。
- 数据存储(Data Storage):用于将一些数据如cookie持久地存储在硬盘上。
页面的渲染
浏览器通过网络模块向服务器发出请求,获得返回的响应内容后,渲染引擎开始进行渲染,一般流程如下:
(1)渲染引擎会从上到下解析HTML文档,将文档中的标签转换为DOM节点,并生成DOM树。
(2)解析CSS样式,构建CSSOM树。
(3)执行JavaSrcipt代码,通过DOM API和CSSOM API来操作DOM树和CSSOM树.
(4)组合DOM树和CSSOM树,生成render树。
(5)在render树的基础上进行布局,为每个节点找到它出现在屏幕上的几何坐标。
(6)将每个节点通过UI backend绘制在屏幕上。
页面的解析与呈现
浏览器由上到下来解析HTML文档,但是对于CSS和JS在文档中的位置不同,不同的浏览器在不同场景下可能有不同的处理方式,而导致页面呈现的效果不同。
- 白屏和FOUC
白屏,顾名思义,就是屏幕上什么都没有。出现这种现象的原因主要是当把CSS样式放在文档底部,或者是使用@import标签引入一个CSS样式(使用@import引入的 CSS 将在页面加载完毕后被加载),对于某些浏览器在某些场景下(例如IE在新窗口打开和刷新等),会选择先渲染样式,再呈现文档内容,所以在CSS未下载完成,页面样式未渲染完成之前,页面呈现白屏。另外当JS放在文档开头,因为加载JS会禁用并发(即要先加载完成JS文件,后面的文件才会继续加载),所以也可能出现白屏现象。
FOUC(Flash of Unstyled Content)是指当CSS样式放在文档底部或使用@import,某些浏览器在某些场景下(如IE点击链接,书签进入等),会选择先呈现文档内容,等CSS加载完成后,再渲染样式,这时页面在渲染过程中会出现闪烁现象。
为减少以上的状况出现,通常会将CSS样式放在文档顶部,而JS放在文档底部,使得页面样式尽早加载完成,及时渲染,而不会发生JS阻塞。 - async和defer
async和defer是让JS异步加载与执行的两种方式。当在文档中通过<script src="script.js"></script>
引入JS时,如果不用async或defer,浏览器会不等待<script>
标签之后的文档载入而先下载并执行script.js。而使用ansyc即<script async src="script.js"></script>
,会让加载与渲染文档元素的过程和加载与执行script.js的过程同步进行;使用defer即<script defer src="script.js"></script>
,会让加载文档元素的过程和加载script.js的过程同步进行,但是script.js的执行要在所有文档元素解析完成之后,DOMContentLoaded事件触发之前。
小结
本文大致介绍了浏览器页面的渲染步骤和一些影响页面呈现效果的相关因素。我们在实际应用中可以依据这些因素有针对性地进行优化,来达到期望的效果。