网页如何加载、解析、渲染

发布于 2021-12-02 12:49:52 字数 4069 浏览 1010 评论 0

1. CSS 和 JS 文件加载的影响

当用户访问网页,浏览器发送请求给 DNS 服务器,解析得到 IP 地址后,然后发送请求得到 HTML 文件,然后自上而下加载。

在加载过程中会遇到图片、CSS、JS 等外部文件,浏览器会发出异步请求来加载。

1.2 外部文件的加载顺序

文件加载通常先出现的标签先加载,但并不串行,即它们的过程可同时进行。结果就是一些比较大的文件虽然先加载,但可能后加载完成。

1.3 衡量加载、解析、渲染先后的方法

我们需要借助于浏览器的调试工具,将请求的网速调到较低,才可以肉眼直观看到下面一些示例的过程。

1.4 JS 文件加载的影响

JS 对 HTML 解析的影响

JS文件的加载和解析过程是连续进行的,在这个过程中,HTML文档的渲染会被阻塞,即在JS文件加载完成以前,它网页内容是看不到的。

  1. <script> 加载一个大的 js 文件比如一个 jquery 的源文件
  2. <h1> 一个普通的文本暂时可以看到在等待js文件加载完毕以前,h1的内容是看不到的

JS 对后面 JS 的加载和解析的影响

那么对于多个JS文件之间,假定按照顺序先后加载了 a.js 和 b.js,其中 a.js 文件很大需要花较长时间,b.js 的文件很快加载好,这时候 b.js 却会等到 a.js 执行完毕后才执行。

  1. a.js 写入比较多的内容比如 jquery 的内容
  2. b.js 直接输出一行$('body')

可以看到不会因为b.js先加载完就执行,而导致$未定义,而是等到a.js加载执行完毕后,b.js中的内容才在console中输出

JS 对后面 CSS 的加载和解析的影响

和 JS 类似的,我们可以看到CSS文件可能很早就加载完毕了,但是会直到JS加载解析完毕后,样式才被应用到界面上。

  1. <h1>
  2. <script> 加载一个大的 js 文件比如一个 jquery 的源文件
  3. <style> 加载一个普通的给 h1 设置颜色的文件

可以看到,h1 的颜色会等到 JS 文件加载和解析才生效

1.5 CSS 文件加载的影响

1.5.1 对 HTML 文档的影响

CSS 加载不会影响于 HTML 文档的解析和渲染。关于这一点和 https://zhuanlan.zhihu.com/p/43282197 提到的不一致,需要分辨是否可能不同的浏览器或者版本会有差异。

  1. <script 执行一个 setTimeout(0 的脚本,最快会 12ms 后执行,去查找 h1
  2. <style 加载一个很大的样式文件比如boostrap的css用于增加耗时
  3. <h1>

可以看到 console 中输出了 NodeList,但是界面没看到标签,需要等到样式文件加载完毕。

1.5.2 对 JS 解析的影响

不影响 JS 文件的加载,但会影响 JS 文件的解析。

  • <style 加载一个很大的样式文件比如 boostrap 的 css 用于增加耗时
  • <script 输出一行执行的 log 代码

可以看到执行的代码会等到样式文件加载完毕才执行

1.5.3 对后面 CSS 的加载和渲染的影响

不影响后面的 CSS 的加载,渲染需要等到当前的 CSS 渲染完毕。

<link 给h1添加一个颜色
<h1
<link 导入很大的bootstrap.css文件
# 可以看到h1出现的时候带上了颜色,bootstrap的样式加载好以后字体变化

<h1
<link 导入很大的bootstrap.css文件
<link 给h1添加一个颜色
# 可以看到文字先出现,颜色会等到boostrap字体效果加载好才生效


<h1
<link 给h1添加一个颜色
<link 导入很大的bootstrap.css文件
# 可以看到文字先出现,颜色变化,然后再是boostrap的样式被应用

2. 加载的实践

有第1节可以得出如下的表格:

    HTML             JS         CSS 
JS  阻塞             加载不执行  可加载/解析,不渲染
CSS 构建DOM不渲染白屏  加载不执行  加载,不渲染

因为 JS 会阻塞 HTML 的加载和渲染,所以应该讲 JS 文件放在 </body> 结束之前,一方面确保先让界面出来,另一方面防止提前操作了还不存在的 DOM。

CSS 的加载太久导致界面白屏,因此要想办法提高加载 CSSD 速度,可用的策略有:使用 CDN、对 CSS 进行压缩、使用缓存技术、减少 HTTP 请求数将多个 css 文件合并。

3. defer 和 async

<script       src="myscript.js"></script>
<script async src="myscript.js"></script>
<script defer src="myscript.js"></script>

Without async or defer, browser will run your script immediately, before rendering the elements that's below your script tag.

With async (asynchronous), browser will continue to load the HTML page and render it while the browser load and execute the script at the same time.

With defer, browser will run your script when the page finished parsing. (not necessary finishing downloading all image files. This is good.)

4. DOMContentLoaded, onload, beforeunload, unload

onLoad 表示所有资源都加载完毕,DOMContentLoaded 表示页面内容渲染完毕,beforeunload 表示用户正在离开页面,unload 表示用户已经基本离开了页面。

因为 JS 会阻塞 HTML 渲染,CSS 会阻塞 JS 的解析,因此 DOMContentLoaded 的触发时机就有几种情况:

  • 只有 CSS,那么不等到CSS加载渲染完毕,就会事件该事件
  • JS 在 CSS 前面,也不需要等待CSS加载完毕,就会触发该事件
  • CSS 在 JS 前面,必须要等到JS和CSS都加载完毕,才会触发该事件

在 load 阶段,因为资源已经被加载好了,我们可以获取到图片大小之类的信息。
在 beforeunload 阶段,我们可以检查未被保存的信息,并且提示用户是否确定要离开。
在 unload 阶段我们可以做一些数据的统计请求的发送。

参考

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

0 文章
0 评论
711 人气
更多

推荐作者

wanghao

文章 0 评论 0

蓝天

文章 0 评论 0

handsomedeng

文章 0 评论 0

仙女

文章 0 评论 0

石海龙

文章 0 评论 0

dianjvnan

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文