web页面加载、解析、渲染过程

对web项目进行优化首先得知道浏览器是怎么工做的这里推荐 how browsers work 中文版;javascript

1、浏览器

浏览器的主要功能是将用户选择的web资源呈现出来,它须要从服务器请求资源,并将其显示在浏览器窗口中,资源的格式一般是HTML,也包括PDF、image及其余格式。用户用URI(Uniform Resource Identifier统一资源标识符)来指定所请求资源的位置,经过DNS查询,将网址转换为IP地址。整个浏览器工做的流程:
  一、输入网址。
  二、浏览器查找域名的IP地址。
  3. 浏览器给web服务器发送一个HTTP请求
  4. 网站服务的永久重定向响应
  5. 浏览器跟踪重定向地址 如今,浏览器知道了要访问的正确地址,因此它会发送另外一个获取请求。
  6. 服务器“处理”请求,服务器接收到获取请求,而后处理并返回一个响应。
  7. 服务器发回一个HTML响应
  8. 浏览器开始显示HTML
  9. 浏览器发送请求,以获取嵌入在HTML中的对象。在浏览器显示HTML时,它会注意到须要获取其余地址内容的标签。这时,浏览器会发送一个获取请求来从新得到这些文件。这些文件就包括CSS/JS/图片等资源,这些资源的地址都要经历一个和HTML读取相似的过程。因此浏览器会在DNS中查找这些域名,发送请求,重定向等;css

浏览器的主要组件包括

1. 用户界面: 包括地址栏、后退/前进按钮、书签目录等,也就是你所看到的除了用来显示你所请求页面的主窗口以外的其余部分;html

2. 浏览器引擎:用来查询及操做渲染引擎的接口;html5

3. 渲染引擎: 用来显示请求的内容,例如,若是请求内容为html,它负责解析html及css,并将解析后的结果显示出来;java

4. 网络:用来完成网络调用,例如http请求,它具备平台无关的接口,能够在不一样平台上工做;web

5. UI 后端:用来绘制相似组合选择框及对话框等基本组件,具备不特定于某个平台的通用接口,底层使用操做系统的用户接口;后端

6. JS解释器:用来解释执行JS代码;浏览器

7. 数据存储:H5定义了web database技术,这是一种轻量级完整的客户端存储技术;性能优化

 2、页面生成过程

一、DNS服务器经过域名查找对应的web 服务器ip地址;服务器

二、浏览器访问web服务器;

 这里涉及到客户端与服务器的tcp 三次握手与四次挥手,能够参考上篇博文《TCP的三次握手(创建链接)与 四次挥手(关闭链接)》;

三、服务器处理完成返回html;

四、浏览器解析、加载页面

  解析html 构建dom树 -> 构建render树 -> 布局render树 -> 绘制render树 :

咱们知道浏览器为了体验友好,并非文档所有都解析才绘制到屏幕上,而是从上至下开始解析html,遇到css 会开启线程下载css;

解析:
  一、将HTML构建成一个DOM树(DOM = Document Object Model 文档对象模型),DOM 树的构建过程是一个深度遍历过程:当前节点的全部子节点都构建好后才会去构建当前节点的下一个兄弟节点。
  二、将CSS解析成CSS去构造CSSOM树( CSSOM = CSS Object Model CSS对象模型)
  三、根据DOM树和CSSOM来构造 Rendering Tree(渲染树)。注意:Rendering Tree 渲染树并不等同于 DOM 树,由于一些像 Header 或 display:none 的东西就不必放在渲染树中了。

  4.有了Render Tree,浏览器已经能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系。
  5.下一步操做称之为Layout,顾名思义就是计算出每一个节点在屏幕中的位置 layout render tree。
  6.再下一步就是绘制,即遍历render树,并使用浏览器UI后端层绘制每一个节点。

性能优化中重绘、重排:
(1)Reflow(回流/重排):当它发现了某个部分发生了变化影响了布局,渲染树须要从新计算。
(2)Repaint(重绘):改变了某个元素的背景颜色,文字颜色等,不影响元素周围或内部布局的属性,将只会引发浏览器的repaint,根据元素的新属性从新绘制,使元素呈现新的外观。重绘不会带来从新布局,并不必定伴随重排;
Reflow要比Repaint更花费时间,也就更影响性能。因此在写代码的时候,要尽可能避免过多的Reflow。

reflow的缘由:

(1)页面初始化的时候;
(2)操做DOM时;
(3)某些元素的尺寸变了;
(4)若是 CSS 的属性发生变化了。

减小 reflow/repaint

 (1)不要一条一条地修改 DOM 的样式。与其这样,还不如预先定义好 css 的 class,而后修改 DOM 的 className。
 (2)不要把 DOM 结点的属性值放在一个循环里当成循环里的变量。
 (3)为动画的 HTML 元件使用 fixed 或 absoult 的 position,那么修改他们的 CSS 是不会 reflow 的。
 (4)千万不要使用 table 布局。由于可能很小的一个小改动会形成整个 table 的从新布局。

3、影响页面渲染

css注意事项

css选择符是从右到左进行匹配的。因此,#nav li 咱们觉得这是一条很简单的规则,秒秒钟就能匹配到想要的元素,因此,会去找全部的li,而后再去肯定它的父元素是否是#nav。所以,写css的时候须要注意:

  1. dom深度尽可能浅。
  2. 减小inline javascript、css的数量。
  3. 使用现代合法的css属性。
  4. 不要为id选择器指定类名或是标签,由于id能够惟一肯定一个元素。
  5. 避免后代选择符,尽可能使用子选择符。缘由:子元素匹配符的几率要大于后代元素匹配符。后代选择符;#tp p{} 子选择符:#tp>p{}
  6. 避免使用通配符,举一个例子,.mod .hd *{font-size:14px;} 根据匹配顺序,将首先匹配通配符,也就是说先匹配出通配符,而后匹配.hd(就是要对dom树上的全部节点进行遍历他的父级元素),而后匹配.mod,这样的性能耗费可想而知.

javascript 位置

若是在解析html的时候遇到js会阻塞页面渲染,因此通常咱们会将全部的script标签放到页面底部,也就是body闭合标签以前,这能确保在脚本执行前页面已经完成了DOM树渲

染。尽量地合并脚本。页面中的script标签越少,加载也就越快,响应也越迅速。不管是外链脚本仍是内嵌脚本都是如此。

采用无阻塞下载 JavaScript 脚本的方法:
(1)使用script标签的 defer、async 属性、;
(2)使用动态建立的script元素来下载并执行代码等异步加载等方法;

defer、async 区别:

defer、async都是异步下载,可是执行时刻不一致;

相同点:

  • 加载文件时不阻塞页面渲染;
  • 使用这两个属性的脚本中不能调用document.write方法;
  • 容许不定义属性值,仅仅使用属性名;

不一样点:

  • html的版本html4.0中定义了defer,html5.0中定义了async;这将形成因为浏览器版本的不一样而对其支持的程度不一样;
  • 每个async属性的脚本都在它下载结束以后马上执行,同时会在window的load事件以前执行,因此就有可能出现脚本执行顺序被打乱 的状况;
  • 每个defer属性的脚本都是在页面解析完毕以后,按照本来的顺序执行,同时会在document的DOMContentLoaded以前执行;

动态建立DOM方式

function downloadJSAtOnload() {

            var urlList = [

                "@ViewHelper.Content("/Content/plugin/alert/js/j_alert.js", "20170111")",

                "@ViewHelper.Content("/Content/js/swiper.min.js")",

                "@ViewHelper.Content("/Content/js/imageview_new.js", "201702271")"

            ];

            for (var i = 0; i <= urlList.length - 1; i++) {

                var element = document.createElement("script");

                element.src = urlList[i];

                document.body.appendChild(element);

            }

        }
相关文章
相关标签/搜索