渲染进程的主要任务,是将HTML、CSS和JavaScript变成用户可以与之交互的网页
HTML解析
<script>
标签,HTML解析需要停止,进行JavaScript的加载、解析与执行。原因是JavaScript可能会使用document.write
等方法改变DOM结构预解析,不同于主线程的正式HTML解析,它会专门去找HTML中嵌入的外部资源,包括CSS、图片、JavaScript等,并进行提前加载,以节省时间。
找到这些内容后,渲染进程会将这些需要加载的内容交给broswer进程中的network线程,让它去发起网络请求,加载这些资源,而渲染进程中的主线程则会同步进行HTML解析
有一些方法可以避免JavaScript的加载和执行阻塞DOM解析,比如
如果脚本不影响DOM结构,则可以给<script>
标签加上async
或defer
标签,使JavaScript加载变成异步
async
,则加载 JavaScript 和 DOM解析会同步进行 (JavaScript的加载时由browser进程中network线程进行,不影响DOM解析)。JavaScript加载完毕后,停止DOM解析,进行JavaScript的解析和执行,JavaScript解析和执行完毕后继续进行DOM 解析defer
,则加载JavaScript和DOM解析会同步进行,JavaScript加载完毕后会进行等待,DOM全部解析完毕后,才会解析和执行这些JavaScript。浏览器会保证所有加了defer
属性的脚本,会按照它们的排列顺序从上往下依次执行rel=preload
属性,则可以使页面尽快下载,而不是等到HTML解析到了才开始下载参考资料:
https://developers.google.com/web/updates/2018/09/inside-browser-part3
https://www.html5rocks.com/zh/tutorials/internals/howbrowserswork/#Speculative_parsing