闲言少叙,直入正题吧。我们作为前端工程师,每天就是跟页面打交道。页面呢又是在浏览器中展现的。每天开发项目时,一遍遍的刷新浏览器,来看页面的展现效果。
不过我们可曾想过,浏览器是如何工作将我们开发的项目转化为页面的呢?为什么我们在浏览器输入一个URL,点击回车就能够展现出一个页面呢?
可能有人会说,不就是浏览器发送了一个请求,下载了一个html,然后解析渲染就好了。对,其实就是这样的。但是浏览器是如何请求的呢?又是怎么渲染的呢?
下面我们带着问题一起来探讨一下:
答案很多同学应该都知道了,那当然是根据URL查找本地缓存啦!先看本地缓存中是否有当前请求的URL的内容,如果存在,当然好了,直接用就好了。如果不存在,那就得去向服务器请求该URL了。
但是同学们,你可别小看了这个本地缓存,这里边可有大学问呢。首先让我们回顾一下浏览器的缓存标识字段都有哪些。
这么多缓存标识,判断时肯定得有个优先级吧,那是肯定的,Cache-control优先级高于Expires,Etag优先级高于Last-Modified。说这么多,直接上图吧,看下图更清晰:
看完上图我相信大家应该对浏览器缓存的机制就了解了,那我们接着研究浏览器下一步会做什么?
首先客户机将域名查询请求发送到本地DNS服务器,本地DNS服务器先在之前的记录(缓存)中查找,如果有缓存,则直接利用缓存进行解析,如果没有缓存,则进入本地的缓存的寻找。如果本地服务器不能在本地找到缓存,则将请求发送到根域名DNS服务器。
DNS服务器在拿到我们的域名后,会将它解析成IP地址返回给浏览器,这样浏览器就能直接定位到要请求的服务器的地址了。
这样根据IP和端口,浏览器就开始跟服务器建立TCP连接啦。看到TCP连接,我们就想到了三次握手。
三次握手简化版:
甲:你瞅啥?
乙:瞅你咋地?
甲:不服来一发数据啊。
甲和乙就来一发数据了。
当然啦,连接建立后,那就是愉快的互相发数据啦,那么问题来了。
渲染展现页面是肯定的啦,关键是如何渲染。我们先来看一下浏览器的简单处理步骤:
(1)解析HTML/SVG/XHTML,build DOM树。
(2)解析CSS,build CSSOM树。
(3)build render树。render树并不等同于DOM树,因为一些像Header或display:none的东西就没必要放在render树中了。
(4)reflow。计算每个Element在设备中显示的具体位置。
(5)paint。最后通过调用操作系统Native GUI的API绘制。
转换(Conversion):浏览器读取HTML的原始字节,然后根据指定的编码规则转换成单独的字符(比如按UTF-8编码)。
标记分解(Tokenizing):浏览器将字符串按照W3C的HTML5标准转换成确定的标记,比如带尖括号的字符。每个标记都有特定的意义以及一套规则。
词法分析(Lexing):分解出来的标记被转换成能定义其属性和规则的对象。
DOM构造:最终由于HTML标记创建出来的对象被关联到一个树形数据结构。这颗树会反映在原先标签里定义的父子关系,比如HTML对象就是body对象的父对象,body对象又是p 对象的父对象等等。 我们看下图吧,更直观一些:
过程跟构建dom tree一样,看下图吧:
浏览器在渲染时只有同时具备DOM和CSSOM才能来构造渲染树。大致步骤是这样的:
现在我们已经得到了渲染树,并且知道哪个节点要展示,并且展示成什么样子。但是这时候我们并不知道这些节点在当前设备中的具体位置和尺寸,没错,这正是reflow阶段要做的工作,从根节点递归调用,计算每一个元素的大小、位置等,给每个节点所应该出现在屏幕上的精确坐标。
到这里,我们已经知道了哪些节点是可视的、它们的样式和它们的几何外观,以及它们在设备上的精准位置,终于可以绘制了。在paint阶段,浏览器通过调用操作系统Native GUI的API绘制每一个像素点,更新显存,给显示器发送信号,显示器根据得到的信号进行显示。
恭喜你,到这里你已经可以看到页面啦!那么我们的介绍到这里也要结束了,如果有不对的地方,欢迎批评指正,有不同的想法,也欢迎来跟我们交流。
如果你喜欢我们的文章,关注我们的公众号和我们互动吧。
我们是转转FE团队,欢迎大家关注公众号 大转转FE 。更多的了解我们
来源: http://www.cnblogs.com/zhuanzhuanfe/p/7610002.html