浏览器的组成
浏览器就是请求资源 展示到用户面前
- 用户界面 UI
- 呈现引擎 负责显示请求的内容
- 网络 用于网络调用
- 用户界面后端
- JavaScript 解释器
- 数据存储
页面解析过程
- 浏览器地址栏输入url
- DNS解析(DNS解析会查找浏览器的缓存,本地缓存等等)
- 浏览器使用网络模块发起请求
- server返回html,下载完成
- 浏览器开始Parse HTML(解析一部分,就会渲染,并不是全部解析完成之后再去渲染)
- 浏览器发现一个加载css的外链, 发起一个请求加载这个样式表文件,期间(下载css文件和解析css文件期间), 不阻塞Parse HTML(可以使用添加async的js脚本来验证),但是因为css tree 没有构建完成,所以无法和DOM tree 一起构成render tree,后面的 layout, paint 也无法进行,所以文档后面内容无法展现到浏览器上
- 发现一个外链js文件,发起一个请求,去请求js,期间(下载js解析执行js脚本)会阻塞document的解析,所以会导致阻塞后面dom tree和后面的css tree的构建,最终导致阻塞 render tree的形成,所以浏览器上看不到显示(注意:这个时候现代浏览器都会启动另外的线程去解析剩余的document,去加载后面的外部资源,但是不会影响dom tree)
文件类型 | 是否阻塞后续DOM tree解析 | 是否阻塞后续 css tree | 是否阻塞后续 render tree | 是否影响最终展现屏幕上 | 备注 |
---|---|---|---|---|---|
css样式 | 👍 | 👎 | 👎 | 👎 | 阻塞js的执行 |
js脚本 | 👎 | 👎 | 👎 | 👎 | js的下载和执行会阻塞dom 解析,自然会阻塞css tree的解析, 但是现代浏览器都会启动另外的线程去解析剩下的dom,但是只会下载需要的资源 |
验证demo地址
js脚本异步加载
- 使用defer属性 作用是:异步的加载js脚本
- 不会阻塞页面的渲染 会异步的加载 等到dom构建完成之后 再去执行脚本(异步的下载 dom之后执行)
- 使用async属性(html5新增)
- 不会阻塞页面的渲染 并且下载完成之后异步的解析执行(异步下载 异步执行)
同时拥有async 和 defer的时候 , async优先级高
css的解析
css解析规则 是从右向左
1 | div p em{} |
另一方面,样式表的处理有这不同的模型。理论上来说,由于样式表不会改变dom结构,所以没有必要等待他们而停止文档解析。但是有一个问题:在文档解析阶段,脚本访问了样式信息,如果样式表没有下载完成,解析完毕,脚本将得到错误的答案,这样会引起很多问题。貌似是一个极端情况,却很常见。
- firfox将会阻止所有的脚本,当还有没下载和解析的脚本时。
- WebKit仅在用户尝试访问未加载样式表可能影响的某些样式属性时阻止脚本。
注意点
1.http协议的网页加载https的外部资源(非跨域情况)都能无伤加载
2.https协议的网页不能加载http的外部资源