包括html,css,js在内的页面是如何解析渲染的
1. 关键词
@import,link,defer,async
2. 流程
请求完html页面之后,首先,主进程是"自上而下,自左而右"依次解析和渲染代码的。
2.1 遇到css
遇到通过<link>导入的css文件,主进程会开辟一个线程去请求服务端的资源文件,不会阻碍主线程的渲染。遇到通过@import导入的样式文件,此时是让主线程去获取,这样阻碍了DOM结构的继续渲染,只有把外部的css文件导入进来,并且解析后才能继续渲染DOM结构;
2.2 遇到JS
- 如果遇到默认方式的
<script src='xxx.js'>,主线程会从服务器获取到JS资源,并且把JS资源进行解析加载,加载完成后再继续渲染DOM结构。现代浏览器都有完善的代码扫描机制,script需要同时加载和渲染代码,浏览器在渲染的时候,同时会向下继续扫描,如果发现有一些异步的资源代码,此时就开始加载请求了。 - 如果设置了
defer或者async,都是让其变为异步获取资源(不会阻塞DOM的渲染),defer会遵循原有的加载顺序,获取后按照顺序去一次渲染JS =>async无序的(谁先获取到谁先执行) - 在js中可能还要操作元素的样式,所有哪怕是异步请求资源的情况下,js先加载回来,也要等到他之前发送的css加载并渲染完成后才会执行JS代码
3. 渲染
- 在上面的过程中解析了html生成了
DOM树,解析了css生成css 生成css rule tree - DOM树和css rule tree结合,生成渲染树(render tree)
- Layout(回流):根据生成的渲染树,计算设备适口(viewport)内的确切位置和大小,这个计算的阶段就是回流
- Painting(重绘):根据渲染树以及回流得到的信息,得到节点的绝对像素
- Display:将像素发送给GPU,展示在页面上
- 浏览器通知GPU(显卡)开始按照render tree绘制图形到页面中