1、了解浏览器的工作原理有什么好处?
浏览器是个什么东西?
平时我们在浏览器地址栏输入网址到网页展示,这过程发生了什么事?
JavaScript操作的HTML DOM是什么?怎么产生的?
前端网页加载性能如何优化?具体有哪些做法? 。。。。。。
这些问题都是面试官的最爱,网页性能优化是前端设计师必备的技能,了解浏览器的工作原理更有利于日常的前端开发,不止性能优化,包括对JS引擎原理的理解,能让你知道这些代码为什么这样写,哪种方式更好。
在设计中,对原理的理解一般都是技术进阶的方向。比如学习spring boot或Android开发,如果你不了解其生命周期,一些开发错误你可能无法及时处理,
理解一些运行原理,我们能够学习或开发起来更有依据。
2、流行浏览器有哪些?渲染引擎和JS引擎?
浏览器是一个应用程序,主要部分是浏览器内核,内核主要包括渲染引擎和JS引擎。渲染引擎主要负责解析数据,并显示html文档、图片以及其它文档;JS引擎负责解析并执行JavaScript。从整体来看,渲染引擎和JS引擎的执行原理是类似的,它们都需要对数据进行词法分析以及语法分析,目前流行的浏览器以及对应的渲染引擎和JS引擎如下表:
浏览器名称 | 渲染引擎 | JS引擎 |
Internet Explorer | Trident | Jscript |
Firefox | Gecko | TraceMonkey |
Chrome | Webkit | V8 |
Safari | WebKit | SquirrelFish Extreme |
Opera | Presto | Carakan |
3、浏览器的整体结构以及主要工作流程
浏览器主要组成:
1)用户界面。包含基本的组件如地址栏,以及浏览器厂商自定义的功能;
2)数据储存模块。用于持久化网页的数据,如cookies,database;
3)浏览器处理引擎。类似于控制器,在渲染引擎和用户界面之间进行任务调度;
4)渲染引擎,负责处理web文档,并最终显示在用户界面;
5)JS引擎,和渲染引擎类似,不过主要集中处理JS;
6)网络模块,给渲染引擎提供网络请求;
7)UI后端负责绘制渲染引擎处理得到的渲染树节点元素。
浏览器的主要运行流程:用户在浏览器输入www.baidu.com并回车,浏览器引擎将该URL传给渲染引擎,渲染引擎调用网络模块向服务器请求资源,若请求资源成功,则渲染引擎开始解析资源,最后调用UI后端绘制界面。
下面侧重分析三个部分:网络调用模块,渲染引擎以及JS引擎。涉及的内容都是IT开发者基本必备的知识
4、浏览器网络请求过程,从输入URL到网页展示过程都发生了什么?
在浏览器地址栏输入www.baidu.com,到页面显示,该过程涉及的网络调用主要包括:NDS域名解析;客户端和服务端进行TCP/IP三次握手;服务器返回数据给浏览器。
IP(Internet Protocol)即互联网协议,如192.168.1.1,互联网每台主机的IP地址都是唯一的,HTTP连接实际使用的是IP地址,而不是域名www.baidu.com,使用该域名字符串是为了好记忆。查看域名对应的IP可以使用:ping www.baidu.com查看百度的实际IP地址。
好记忆的代价就是每次进行网络访问,都要找到域名对应的IP地址,这就产生了一个叫做DNS(Domain Name Server,域名服务器)的东西,域名服务器中主要保存了一张IP与域名对应的数据表,如:
domain_name(域名) | ip_address(IP地址) |
www.baidu.com | 14.215.177.39 |
www.google.com | 75.126.135.131 |
当浏览器通过DNS服务器找到域名对应的IP地址后,这时浏览器开始和服务器建立TCP/IP连接,这过程经过著名的TCP/IP三次握手,最后服务器响应信息给浏览器,浏览器接受到信息,并进行处理,最后展示。
下面我们再来详细看下这个执行过程
1)DNS域名解析的过程
浏览器DNS缓存记录: 浏览器在寻求域名解析时,首先会先查询浏览器DNS缓存记录,在Chrome地址栏输入:chrome://net-internals/#dns,可以查看浏览器的所有DNS缓存记录:
本机DNS缓存记录:若浏览器在浏览器DNS缓存中找不到,则继续查询本地DNS缓存记录,即你本机的hosts文件。
A、windows下查看本机DNS缓存命令:ipconfig /displaydns,
清除DNS缓存命令:ipconfig /flushdns;
B、linux系统(只有开启nscd服务才会有dns缓存),删除dns缓存命令:rm -f /var/db/nscd/hosts,重启nscd:service nscd restart。
路由DNS缓存记录:路由器中也会有DNS缓存记录。
ISP的DNS服务器:ISP(Internet Service Provider)互联网服务提供商,专门提供DNS解析服务的,比如国内有阿里DNS,360,百度。
根服务器:请求跟服务器进行递归查询。
2)TCP/IP三次握手过程
TCP协议的三次握手主要是保证数据传输的安全可靠性,大概过程如下:
A、客户端发送SYN数据包给服务器,询问服务器是否可以开放新的连接;服务器返回带有SYN/ACK的数据包给客户端作为答复(客户端-浏览器:服务器你让我进去吗?服务器:呐!写在数据包里面,你自己看了!)
B、客户端收到数据包发现允许连接,继续发送ACK包回答服务器(客户端-浏览器:我准备进去了。。。)
C、建立连接,准备传输数据。
3)HTTP报文
什么是HTTP报文呢?其实就是一个文档,该文档遵循一定的格式,一个报文一般由三部分组成:HTTP协议,头部信息,正文信息。报文又分为:HTTP请求和HTTP响应。
A、HTTP请求:浏览器向服务器发出请求,会携带请求报文数据,包括User-agent,cookie,请求头例子如下:
GET请求和POST请求的区别是:
GET请求携带的数据是在请求头中的,所以你提交数据可以在URL中看到。
POST请求携带的数据是在请求体中的,所以数据不暴露,这样显得安全。
B、HTTP响应
服务器响应客户端,其响应报文的HTTP响应头实例如下:
HTTP响应报文也包括:HTTP协议 – 状态码,响应头,相应正文,HTTP相应正文的内容就是html文档内容。
关于HTTP报文信息,在Chrome浏览器的操作如下(其它浏览器类似):
5、渲染引擎执行过程
渲染引擎获取到服务器HTML文档后,开始解析HTML得到HTML DOM节点树,同时解CSS,创建得到渲染节点树,渲染节点元素带有CSS定义的属性(颜色、大小等)。渲染节点树的结构和DOM节点树的结构大致相同。称为渲染树是因为该节点树的节点元素,稍后会被绘制到屏幕上,和HTML DOM节点树比,渲染树没有<head>中不会显示的头部信息。
HTML DOM节点树的结构如下:
接着引擎对渲染树进行布局,布局的意思是在渲染树追加每个节点的屏幕坐标。
布局完成,引擎遍历所有渲染树,并调用UI后端进行绘制,最后显示在屏幕上。
注意:渲染引擎处理的过程不是一次解析一次显示,而是一个渐进过程,能先显示的显示。
渲染引擎解析
关于渲染引擎的解析过是相当复杂的,涉及到编译原理,该解析过程和一般编程语言的解析是类似的。
渲染引擎主要是对web文档资源进行解析,解析的目的是为了得到解析节点树,编译原理中叫语法树,它的样子和上面提到的DOM节点树一样。
解析过程主要分为两步:词法分析和语法分析。
词法分析:主要是将文档内容切分成各种标记,实例如下:
语法分析:对词法分析得出的结果进行语法应用,分析文档结构,语法分析的实例如下:
词法分析和语法分析是所有语言解析中,都比较重要,当前有强大的工具支持生成解析器,你也可以实现自己的解析器:
A、词法分析生成器Flex + 语法分析生成器Bison;
B、词法分析生成器Lex + 语法分析生成器Yacc;
WebKit也是使用Flex创建词法分析器,使用Bison创建语法分析器。
1)关于浏览器的容错机制
A、避免过多的元素嵌套
如果在一个表单中嵌套另一个表单,第二个表单会被忽略;同类标签嵌套最多只能20层,过多也会被忽略;
B、不规则表格元素
在table中嵌入另一个table,但又不在table的单元格中,WebKit会更改为两个同级table的形式。
2)关于处理脚本和样式表的问题
解析器遇到script脚本会立即解析并执行脚本,现在WebKit和Firefox优化成了可以并行解析,也就是在执行脚本的时候,也会解析文档的其余部分,加快了速度。
另外,在加载或解析样式表过程中,firefox会禁止脚本。webkit则是仅当脚本可能访问未加载的样式时候,才禁止脚本。
6、什么是JS解析引擎?
JS解析解析引擎和上面提到的渲染引擎解析html文档是类似的,都是需要进行词法分析,语法分析,不同的是JS引擎还要将解析的结构编译成本地机器码,然后执行机器码。
为什么JS是单线程?JS的主要任务是操作DOM,更友好地实现用户交互,如果对同一个DOM进行读写操作,那么浏览器将不能决定该执行哪个操作。
7、如何优化前端页面加载性能?
关于页面性能的优化可以参考DOM的结构(访问速度),一方面可以关注UI绘制的问题,另一方面可以侧重网络请求的优化,下面是一些建议,但并不是规范性的,更具体的需要根据情况对DOM、UI和网络请求方面作出优化设计。
1)减少HTML DOM的操作,js操作dom会触发reflow(回流,重新计算元素的位置和尺寸)或repaint重画,这会导致性能的损耗;
2)尽量不要使用CSS3动画(动画也会触发回流重画);
3)尽量不用table布局,table的调整会导致重新渲染;
4)使用预加载,使用缓存,主要针对网络请求;
5)使用class和id选择元素,少用后代选择器(针对DOM的结构);