超文本文档
万维网的起源,一种只有基本格式,但支持超链接的纯文本文档。(这个时候CSS和Javascript 还没有出现)
富媒体网页
交互式Web应用
javascript、AJAX出现,网页转换成交互式Web应用的革命时代。揭开脚本、样式和文档之间复杂依赖关系的时代
网页的三个时代
首先来看一下浏览器的高层基本结构
浏览器的主要组件为:1.用户界面 - 包括地址栏、前进/后退按钮、书签菜单等。除了浏览器主窗口显示的您请求的页面外,其他显示的各个部分都属于用户面。
2.浏览器引擎 - 在用户界面和呈现引擎之间传送指令
3.呈现引擎 - 负责显示请求的内容。如果请求的内容是 HTML,它就负责解析 HTML 和 CSS 内容,并将解析后的内容显示在屏幕上
4.网络 - 用于网络调用,比如 HTTP 请求。其接口与平台无关,并为所有平台提供底层实现
5.用户界面后端- 用于绘制基本的窗口小部件,比如组合框和窗口。其公开了与平台无关的通用接口,而在底层使用操作系统的用户界面方法。
6.JavaScript解释器-用于解析和执行 JavaScript 代码。
7.数据存储-这是持久层。浏览器需要在硬盘上保存各种数据,例如 Cookie。新的 HTML 规范 (HTML5) 定义了“网络数据库”,这是一个完整(但是轻便)的浏览器内数据库。
下面有一张非常简单的html页面,内容只有一行文本和一张图片,有一些HTML基本元素和一个CSS文件,没有引入javascript文件。那么思考一个比较直观的问题,对于这么简单的页面,浏览器是怎么把它从一个文档变成像素呈现在显示器上?
先撇开原理这种比较学术的字眼,直观一些地思考这个问题。HTML文档原来肯定是在服务器上,那么浏览器要显示它,肯定首先要获取到这个页面。浏览器拿到的是上图左边部分的内容,这个和最终右边的像素内容还差十万八千里,这中间它怎么处理?这时它就要认真研究拿到的HTML文档了。它有一套自己从左到右的流程。下面会说到。
总的来说,浏览器要做的事情就是:
1.取得资源(得先拿到HTML文档吧)
2.分析计算页面布局和渲染 (从左到右的流程)
3.javascript 执行Q: 谁最重要?
A: 都重要(废话)。但如果一定要选取一个话,always remember that,获取资源是第一要义!巧妇难为无米之炊,没有HTML文档,任何优化技巧都是没有用的。
指浏览器所经历的一系列步骤,将HTML CSS 和 JavaScript 转换为在屏幕上呈现像素内容的过程。 提高网页呈现速度,即优化关键呈现路径。
练习1
很简单,首先各自建立DOM和CSS的树形结构,然后对应DOM树上的每个节点,将对应的CSS样式附着上去。注意渲染树上只捕捉可见内容,span元素是display:none,所以不显示在渲染树上,span下原来有一个文本节点,但由于CSS的继承属性,所以这个文本节点也是不可见,不显示在最终的渲染树里。
渲染树如下。html、head、meta等元素虽然也在DOM结构里,但这些都不是可以呈现的元素,所以不会出现在最终的渲染树里。
我们在讨论Web性能时有三个不同的测量指标。
最早渲染时间
文档完成时间
资源最后获取时间
那么这 3个时间是什么概念呢?还记得文章刚开始提到的web的发展历史吗?最初的超文本文档上根本没有图片、音视频等资源,所以它就只有文档加载时间,即浏览器拿到HTML的时间,这就是它的性能指标。当富媒体网页出现时,性能的关键指标就从文档加载时间变成了页面加载时间(Page Load Time),即PTL 。
PTL的简单定义就是:“ 浏览器中的加载旋转图标停止旋转的时间。”即浏览器中的onload事件,这个事件由浏览器在文档及其所有依赖资源(javascript、图片等)下载完毕时触发。
大家还记得曾经比较热门的一道面试题:window.onload 和$(document).ready()的区别?在这里就可以比较清楚地解释这个问题了。
onload是浏览器的内置事件,ready是jQuery封装的事件。
onload事件如上面所说,要等到页面上所有资源(注意不是文档,资源包括javascript,图片等等)都下载完成时才触发,而ready事件是当DOM结构准备好后就触发,即我们上面提到的DOM树形结构,一旦浏览器拿到HTML文档就会构建DOM结构。我们前面提到的三个测量指标,我们大体可以对应文档完成时间到ready,资源最后获取时间到onload.
那么什么是最早渲染时间?
用户访问一个站点时,浏览器会先发出一个请求获取html文档,拿到html后开始解析并渲染到窗口。这个过程中需要知道以下两个时间点:
Time Of First Byte
首字节时间。衡量网络性能和后端程序的一个关键指标。Start Render Time
指用户屏幕刚开始显示某些内容的时刻。
浏览器屏幕刚开始是一大片空白,绘制时会发生一些变化,可能是显示背景、logo或者文字等。上面提到渲染树的时候说过,DOM树上会有一些非可视化的元素(例如html、head等),这些元素不会出现在最后的渲染树里,即不会呈现在窗口上。所以绘制肯定需要先解析完head元素中的内容。
一般情况下,CSS准备就绪后,即可以开始绘制。css文件通常放在head中,所以大体上可以认为浏览器开始渲染body标签的时间就是Start Render Time 。这个时间减去首字节时间,就是head标签的解析时间。首屏时间(above the fold)
指用户在没有滚动页面的时候看到的内容渲染完成并且可以交互的时间。首屏一般指根据用户屏幕分辨率数确定一个首屏线,首屏线以上即为首屏。这个区域本身也需要时间来渲染。这个区域的资源越多(css,js,img等),其渲染时间越长,首屏时间也就越长。
哪个时间最重要?
答案不唯一,需要根据应用而定。一般来说最好让用户能够尽早与重要内容进行交互。
这里推荐一个非常好用的在线工具 http://www.webpagetest.org/
用于显示网页加载过程的资源瀑布图。(注意看这里的很多竖线,非常详细地标注了加载过程中各个阶段的时间点)
开发者工具中的Timeline Tool 也可以看到类似信息,但没有这个来自直观和全面。开发者工具相关p/e0fb716a834f
这里提一个很简单的问题:
浏览器是什么时候开始绘制页面的?
答案:B . 绘制网页需要渲染树,构建渲染树需要DOM tree 和 CSS tree . 因此浏览器需要等到获取了CSS后再绘制网页。
文章开头提到,交互式Web应用揭开了揭开脚本、样式和文档之间复杂依赖关系的时代。这个是什么意思?到目前为止,在提到Javascript之前,浏览器呈现网页的流程看起来还是很清晰的,从HTML文档里提取DOM,从CSS资源里得到CSSOM,然后得到渲染树,布局绘制,done!
然而网页要交互,必然需要JavaScript的能力。然而随之而来的,便是这个第三者带来的复杂依赖关系
Javascript 拥有操作DOM和CSS的能力。当HTML遇到