浏览器主要是将用户请求的 web 网站,从服务器请求资料后,并重新将资料组合渲染在浏览器的窗口中,资源的格式通常是 HTML,也包括 PDF、 image 和其他格式,用户用 URI (Uniform Resource Identifier 统一资源标识符)来指定请求资源的位置。
HTML 和 CSS 规范中规定了浏览器解释 html 文档的方式,由 W3C 组织对这些规范进行维护, W3C 是负责制定 web 标准的组织。
浏览器厂商纷纷开发自己的扩展,对规范的遵循并不完善,这为 web 开发者带来了严重的兼容性问题。
浏览器可以分来两部分, shell 和 内核。
shell 是指浏览器的外壳,例如:菜单,工具栏等,主要是给用户界面操作,参数设置等等,种类比较多 内核是指浏览器的核心,内核是基于标记语言显示内容的程序或模块,内核种类相对比较少。也有一些不区分外壳和内核的(Mozilla 将 Gecko 独立出来后,才有外壳和内核的区分)
-
Trident: 这种浏览器内核是 IE 浏览器用的内核,因为在早期 IE 占有大量的市场份额,所以这种内核比较流行,以前有很多 网页也是根据这个内核的标准来编写的,但是实际上这个内核对真正的网页标准支持不是很好。但是由于 IE 的高市场占有率,微 软也很长时间没有更新 Trident 内核,就导致了 Trident 内核和 W3C 标准脱节。还有就是 Trident 内核的大量 Bug 等 安全问题没有得到解决,加上一些专家学者公开自己认为 IE 浏览器不安全的观点,使很多用户开始转向其他浏览器。
-
Gecko: 这是 Firefox 和 Flock 所采用的内核,这个内核的优点就是功能强大、丰富,可以支持很多复杂网页效果和浏览器扩 展接口,但是代价是也显而易见就是要消耗很多的资源,比如内存。
-
Presto: Opera 曾经采用的就是 Presto 内核,Presto 内核被称为公认的浏览网页速度最快的内核,这得益于它在开发时的 天生优势,在处理 JS 脚本等脚本语言时,会比其他的内核快3倍左右,缺点就是为了达到很快的速度而丢掉了一部分网页兼容性。
-
Webkit: Webkit 是 Safari 采用的内核,它的优点就是网页浏览速度较快,虽然不及 Presto 但是也胜于 Gecko 和 Trid ent,缺点是对于网页代码的容错性不高,也就是说对网页代码的兼容性较低,会使一些编写不标准的网页无法正确显示。WebKit 前身是 KDE 小组的 KHTML 引擎,可以说 WebKit 是 KHTML 的一个开源的分支。
-
Blink: 谷歌在 Chromium Blog 上发表博客,称将与苹果的开源浏览器核心 Webkit 分道扬镳,在 Chromium 项目中研发 B link 渲染引擎(即浏览器核心),内置于 Chrome 浏览器之中。其实 Blink 引擎就是 Webkit 的一个分支,就像 webkit 是 KHTML 的分支一样。Blink 引擎现在是谷歌公司与 Opera Software 共同研发,上面提到过的,Opera 弃用了自己的 Presto 内核,加入 Google 阵营,跟随谷歌一起研发 Blink。
JavaScript 加载、解析和执行的时候都会阻塞文档解析,在构建 DOM 时,HTML 解析器遇到 JavaScript 就会暂停文档的解析,再将 控制权移交给 JavaScript 引擎,等待引擎运行完毕继续解析文档。如果 JavaScript 脚本操作了 DOM,再继续解析 就很可能会出问题。
也就是说,如果首屏渲染快,而且不影响 DOM tree 就不应该让 JS 阻塞,渲染树的构建,一般都建议将 script
标签放在 body
底部,用来不影响 css 和 dom 树的构建。
但 script
也可以添加 defer
和 async
来控制 JavaScript 脚本的延迟执行。
-
如果
<script>
没有 defer 和 async,浏览器会立即加载并执行指定脚本,也就是说不等待后续载入的文档元素,读到就加载并执行。 -
defer 属性表示会延迟执行引入的 JavaScript, 在 HTML 解析时遇到 JavaScript,加上这属性后并不会停止解析,这两个过程是并行的,当整个 document 解析完毕后再执行脚本,在 DOMContentLoaded 事件触发之前完成,多个脚本按顺序执行。
-
async 属性表示异步执行引入的 JavaScript, 与 derfer 的区别在于,如果脚本加载好,就会开始执行,就是说它仍然会阻塞文档的解析,只是在加载的过程不会阻塞。多个脚本的顺序无法保证。
理论上,即然样式表不改变 DOM 树,也就没有必要停下文档的解析等待它们,然而存在一个问题, JavaScript 脚本执行的时候可能会在文档的解析过程中请求样式信息,如果样式还没有加载和解析,脚本将得到错误的值,显然这将会导致很多问题。
所以如果浏览器尚未完成 CSSOM 的下载和构建,而想运行脚本,那么浏览器将延迟 JavaScript 脚本的执行和文档的解析,直至其完成 CSSOM 的下载和构建,也就是会浏览器会对 CSSOM 和 JavaScript 构建会有一个互斥期,浏览器会先下载和构建 CSSOM 再执行 JavaScript 脚本,最后再继续文档解析。
-
FOUC(Flash of unstyled content) 无样式内容闪烁,主要是由于浏览器渲染机制,如果在 CSS 加载之前就呈现出了 HTML,就会出现无样式 HTML 的内容, 然后 CSSOM 构建成功后,又突然出现的现象,主要原因是 CSS 加载时间过长,或者 CSS 被放在文档底部。
-
白屏有些浏览器渲染机制,需要先构建 DOM 树和 CSSOM 树,构建完成后再进行渲染,如果 CSS 部分放在 HTML 尾部,会由于 CSS 未加载完成,造成浏览器没渲染,导致白屏,也可能 JavaScript 脚本的加载阻塞后面文档内容的解析,从而未渲染出来,出现白屏。
关键资源是阻止网页首次渲染的资源,这些资源越少越快,就对浏览器 CPU 及其他资源占用的越少。
主要是对下面三个方面进行优化:
- 关键资源的数量,把最核心的先加载构建,其它标记为异步延后加载执行
- 关键路径的长度,尽早下载所有核心资源,减少排队执行的长度
- 关键文件的大小,压缩 tree-shaking 等方法减少大小。