1.组成部分
1.用户界面(User Interface)
用户界面次要包含工具栏、地址栏、后退/后退按钮、书签菜单、可视化页面加载进度、智能下载 解决、首选项、打印等。除了浏览器主窗口显示申请的页面之外,其余显示的局部都属于用户界面。
2.渲染引擎(Rendering Engine)
次要用来渲染动态资源(html,css,图片等),可能精确计算页面布局,可应用“回流”,“重绘”逐渐调整页面元素的地位(例如chrome 浏览器的 blink ,老版本的 webkit)。
3.Js引擎(JavaScript Interpreter)
以v8引擎为例,先读取js源代码,应用parse解析器将JavaScript代码转换成AST(形象语法树),再通过Ignition解释器,会将AST转换成ByteCode(字节码)输入。
4.网络(Networking)
用来实现网络调用或资源下载的模块,基于TCP协定,如HTTP,Websocket。(太长,后续会细说)
6.显示后端(Display Backend)
显示后端提供绘图和窗口原语,包含:用户界面控件汇合、字体汇合。
7.数据长久层(Data Persistence)
治理用户数据,例如书签、cookie和偏好设置等。(太长,后续会细说)
2.加载资源程序及流程
首先咱们须要理解有哪些资源:
- html
- css
- js
- 字体
- 图片
- ajax(api接口申请)
- ...
其次须要了解加载流程:
这里比拟重要也是比拟绕的点须要着重挑出来,就是dom,css,js的程序,分三大类状况探讨:
1.dom与css
外链款式:
两者的加载是异步进行,互不烦扰的
不过CSS的加载会阻塞DOM的渲染,因为必须等DOM树和CSSOM树合并为渲染树之后,能力进行DOM的渲染。(这里须要着重辨别渲染和加载的区别)
行内款式与内联款式:
行内款式是dom的某个节点的style属性,内联款式是以style标签包裹的模式,那么前者是节点,后者是标签,他们会被当做dom的一部分随着dom的加载而加载。
2.dom与js
外链js:当加载js文件时,会阻塞dom的加载,如果加载js工夫过久,会导致页面显示滞后,呈现“假死”状态,如果你在head内外链引入js,在js中操作到dom,就会获取不到dom出现异常,这也是为什么咱们个别会将js代码写在onload钩子中,为什么个别将js引入放在文档的最初地位。(题外话:defer,async属性能够人为管制这种状况)
内联js:按从上到下按程序加载,读到script标签包裹的js代码,立刻执行,执行期间,阻塞dom加载,执行完,持续向下加载。
3.css与js
有一种状况分外留神,在JS中拜访了CSSDOM中某个元素的款式,那么这时候就须要期待这个款式被加载实现能力持续往下执行JS脚本,当然反之,这两者是互不影响的。
总结:
html>css>font>图片js>ajax>prefetch(预加载资源)(个别状况,也能够人为管制程序)
3.工作原理
1.拿到url,DNS服务器域名解析成ip地址
2.建设TCP连贯,三次握手
第一次握手:客户端利用过程被动关上,并向服务器端发送申请(即:发送端发送一个带有SYN标记的数据包给接收端)第二次握手:服务端利用过程被动关上,若批准客户端的申请,则返回一个确认报文(即:接收端接管到数据包之后,回传一个带有SYN/ACK标记的数据包给发送端示意确认)第三次握手:客户端接管到确认报文后,告诉下层利用过程连贯曾经建设,并向服务器发送一个确认报文。服务器接管到客户端的申请也告诉其下层利用过程连贯已建设。(最初,发送端再回传一个带有ACK标记的数据包给接收端,代表“握手”’完结)
3.申请动态资源,并按(2.加载资源程序及流程)规定加载,dom树与css规定树整合成rendertree,layout布局实现后,ui后端绘制到页面上(加载和渲染是同时进行的),遇到js的解析,由js解析引擎实现(这里波及到js的事件循环机制以及单线程,详见上面的js的执行机制)。
4.断开http连贯,四次挥手
第一次挥手:客户端的应用程序收回连贯开释的报文,并进行发送数据。第二次挥手:服务端接管到连贯开释的报文后,收回确认报文。此时连贯处于半封闭状态,客户端不再持续向服务端发送数据,然而服务端持续向客户端发送数据。第三次挥手:若服务端没有了要向客户端发送的数据,其利用过程会告诉服务器开释TCP连贯第四次挥手:客户端接管到开释报文后,必须确认。再通过2MSL(最长报文寿命)s后,本次TCP 连贯正式完结。
4.回流和重绘以及如何防止
重绘:在渲染树中的一些元素须要更新属性,而这些属性只是影响元素的外观、格调,不影响布局。
场景:元素的显隐;元素的尺寸发生变化(包含外边距、内边距、边框大小、高度和宽度等);内容发生变化;页面首次渲染;浏览器窗口尺寸发生变化
回流:在渲染树中的一部分(或者全副)因为元素的规模尺寸、布局 、显隐等扭转而须要从新构建
场景:背景色,字体色彩等不扭转构造布局的款式扭转
如何防止:
1.应用碎片文档documenFragment,屡次合并一次渲染
2.防止间接批改款式,批改类名
3.脱离文档流
当然目前大多数浏览器都进行了本身的优化--渲染队列,浏览器会将所有的回流,重绘放到一个队列中,将达到肯定数量或肯定间隔时间浏览器会对队列批处理,这样的目标是屡次变一次,缩小重绘,回流的次数。
5.js的执行机制
js是单线程的,且自上而下解析执行的,当遇到同步工作,就放到主线程中失常按程序执行,当遇到异步工作,则放到event table中,并将其一对一映射为函数,当满足触发条件后,被推入event queue,直到主线程闲暇时,才会去event queue中查看是否有可执行的异步工作,如果有就推入主线程中,js的执行机制也叫事件循环。
多个异步工作的执行程序如何判断:
异步工作分为宏工作和微工作
宏工作:script、setTimeout、setInterval、postMessage、MessageChannel、setImmediate(Node.js 环境)。
微工作:Promise.then、Object.observe、MutationObserver、process.nextTick(Node.js 环境)。
先执行同步代码,遇到异步宏工作则将异步宏工作放入宏工作队列中,遇到异步微工作则将异步微工作放入微工作队列中,当所有同步代码执行结束后,再将异步微工作从队列中调入主线程执行,微工作执行结束后再将异步宏工作从队列中调入主线程执行,始终循环直至所有工作执行结束。