我以为文章题目起的挺现实,在BS大行其道的今天,浏览器做为一款window软件已是不少程序员兄弟的衣食父母,因此了解一下浏览器是很必要的。javascript
做为前端程序员必定要好奇从地址栏输入地址后到底发生了什么css
IE、Firefox、Safari、Chrome、Opera五你们族, Firefox、Chrome是开源的彻底开源的,safari部分开源html
用户界面、浏览器引擎、渲染引擎、网络、js解释器、UI后端、数据存储,google为每一个tab页分一个渲染引擎,
注:浏览器引擎和渲染引擎的区别
(1) 浏览器引擎是一个主进程、用来管理渲染引擎所在的进程,渲染引擎对应的进程可能只属于一个tab页(chrome),而浏览器进程属于整个浏览器
(2) 渲染引擎没有访问操做系统的权限(文件、网络、设备)而浏览器引擎有,这样的目的是有恶意网站时不会损害整个浏览器或者操做系统
(3) 当用户在地址栏输入网址请求网页时,渲染引擎向浏览器引擎发出请求:依次调用网络获取资源,请求的资源到达后,浏览器引擎把资源传给渲染前端
渲染引擎,渲染引擎将获取的资源进行解析(html css js),有一些组件(布局进程就属于其中的某个组件)格式化后传给浏览器引擎,浏览器在界面中将界面呈现出来
渲染引擎有两种Mozilla和webkit,熟悉css的同窗可能感受这俩外国字挺熟悉,对啊css兼容性的属性都会加这俩前缀,渲染引擎就是将请求的资源在浏览器中呈现出来java
首先是获取请求的文档,文档由8kb的数据块构成,8kb的大小是由tcp缺省缓冲区的大小决定的。构建成dom树->构建render树->布局render树->绘制render树。c++
(1) 渲染引擎从浏览器引擎获取html文档后开始解析,进行词法分析(将输入分红能够理解的单词)和语法分析(对应语言的语义规则,描述文档内容),最终根据文档标签构建一棵DOM树(能够理解成c++的一种数据结构),解析过程若是碰到了行内、内联、外联的css,对应的子进程着手cssom树的构建(能够理解成c++的一种数据结构,描述样式规则),因为是两个进程因此没有阻塞的问题,若是解析过程当中碰到了javascript,那么DOM,而且javascript的执行须要等到cssom构建完毕,下一步构建渲染树是须要两个树都是在完成构建的状态。程序员
(2) 此时要构建渲染树了,先从DOM树的根节点开始逐层遍历,而后依次在cssom中找到对应的样式并合并到渲染树,若是碰到了隐藏样式那么
直接在渲染树种忽略。web
(3) 对渲染树进行'布局',以前的全部操做都没涉及浏览器窗口,他们就是在这个阶段联系起来的,这样渲染树才能适应不一样大小的窗口,这时全部的位置和尺寸都被转换为像素(px)chrome
(4) 最后是将布局树转换格式传给浏览器引擎,在浏览器窗口绘制。后端
从上文中咱们知道css是阻塞的也是非阻塞的,阻塞渲染树的构建,可是对于dom树的构建是不阻塞的。若是在构建渲染树时是不阻塞的会发生什么,咱们会看到'纯html'没有任何样式,这样是不友好的,可是某些时候咱们确实想让它是不阻塞的,好比涉及打印的样式,在特定大屏上的样式,由于他们对渲染的影响比较小,此时能够采用媒体属性(media)
<link href="style.css" rel="stylesheet"> <link href="print.css" rel="stylesheet" media="print"> <link href="style.css" rel="stylesheet" media="all"> <link href="portrait.css" rel="stylesheet" media="orientation:portrait"> <link href="other.css" rel="stylesheet" media="(min-width: 40em)">
注: 不阻塞不是不下载,只是在首次合成渲染树时不受它的阻塞
从衣食父母-浏览器中咱们知道javascript脚本的执行是会阻塞DOM树的构建的,而且在cssom构建完毕前中止执行,这样会有很大的性能开销,有没有不阻塞的方法呢?
一、外部js异步加载
<script src="app.js" async></script>
二、 内联js异步执行
function h () { console.log(document.querySelectorAll('h1')) } setTimeout(h, 0)