DomContentLoaded 与 load
浏览器渲染原理
1 | 当我们在浏览器地址输入url时,浏览器会发送请求到服务器,服务器将请求的html文档发送回浏览器,浏览器将文档下载下来后 便开始从上到下解析,解析完成后 会生成dom,如果页面中有css 会根据css的内容 形成cssdom 然后 dom和css会生成一个渲染树 最后浏览器会根据渲染树的内容计算出各个节点在页面中的确切大小和位置,并将其绘制在浏览器上 |
1 | 在解析html的过程中 有时候解析会被中断,这是因为javascript会阻塞dom的解析 当解析过程中遇到script标签的时候 便会停止解析过程 抓转而去处理脚本 如果脚本是内联的 浏览器会先去执行这段内联的脚本,如果脚本是外链的 那么先去加载脚本 然后执行 在处理完脚本之后 浏览器便继续解析html文档 |
如何计算 DomContentLoaded 加载时间
当文档中没有脚本时 浏览器解析完成文档便能触发 DomContentLoaded 事件 如果文档包含脚本 则脚本会阻塞文档的解析 而脚本需要等位于前面的 css 加载完才能执行 在任何情况下 DomContentLoaded 的触发不需要等待图片等其他资源加载完成
1 | DOMContentLoaded不同的浏览器对其支持不同,所以在实现的时候我们需要做不同浏览器的兼容。 |
如何计算 load 加载时间
页面上所有的资源(图片,音频,视频等)被加载以后才会触发 load 事件,简单来说,页面的 load 事件会在 DOMContentLoaded 被触发之后才触发。
1 | window.onload = function(){ |
我们为什么一再强调将 CSS 放在头部 将 js 放在尾部
因为浏览器生成 Dom 树的时候是一行一行读 html 代码的 script 标签放在最后面就不会影响前面的页面渲染,那么问题来了
既然 Dom 树完全生成好页面才能渲染出来 浏览器又必须读完全部的 html 才能生成完成的 dom 树 script 标签放不放在底部是不是也一样 因为 dom 树的生成需要整个文档解析完成
chrome 页面渲染过程中 会有 firstpaint 的概念,现代浏览器为了更好的用户体验,渲染引擎将尝试尽快在屏幕上显示的内容 他不会等到所有的 html 解析完成才开始构建和布局 dom 树 部分的内容被解析并展示 也就是说 浏览器能够渲染不完整的 dom 树和 cssdom 尽快的减少白屏时间
假如我们将 js 放在 header js 将会阻塞解析 dom dom 的内容会影响到 firstpaint 导致 firstpaint 延后 所以说我们会将 js 放在后面 以减少 firstpaint 时间但是不会减少 DomContentLoaded 被触发的时间