ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

关于外部样式表也许你不知道的事

2019-11-26 09:03:17  阅读:235  来源: 互联网

标签:style sheet script 外部 也许 阻塞 文档 样式表 解析


singsong: 文章中 demo 猛戳这里吧

✏️最新内容请以github上的为准❗️

在讲解之前,先看一个问题。如下图所示,外部样式表是否会阻塞 HTML 解析(先不要看答案,可以自己思考和实验一下):

default


通过DevTools->network:

default
如上图所示,indexcss.css 并没有阻塞 HTML 解析,因为 DOMContentLoaded 时间线在 indexcss.css 之后。但如果在 indexcss.css 之后添加script 标签(不能为空),结果会一样?

script
通过 DevTools->network:

script

如上图所示,在 indexcss.css 之后添加 script 标签(不能为空)后,此时 DOMContentLoaded 时间线位于 indexcss.css 之后。说明这里 indexcss.css 是阻塞 HTML 解析的。

参考相关资料,找到如下描述:

Style sheets on the other hand have a different model. Conceptually it seems that since style sheets don't change the DOM tree, there is no reason to wait for them and stop the document parsing. There is an issue, though, of scripts asking for style information during the document parsing stage. If the style is not loaded and parsed yet, the script will get wrong answers and apparently this caused lots of problems. It seems to be an edge case but is quite common. Firefox blocks all scripts when there is a style sheet that is still being loaded and parsed. WebKit blocks scripts only when they try to access certain style properties that may be affected by unloaded style sheets.----Tali Garsiel

大概意思是:style-sheets 不会修改 DOM 树,没有理由为了解析 style-sheets 而阻塞文档解析(即 style-sheets 不会阻塞文档解析)。但如果在解析文档过程中有脚本需要访问样式信息时,为了保证访问样式信息的正确性。Firefox 会阻塞所有脚本直到 style-sheets 下载解析完为止。而 WebKit 只在访问的样式属性没有被加载解析时,才会阻塞脚本。

relationship

也即 style-sheet 不会直接阻塞文档解析,它只阻塞 script 的解析执行,才导致 style-sheet 间接阻塞文档解析。如果将 script 设置为非阻塞式的呢?可以通过为 script 标签设置 aysnc 特性来实现。可能你会疑问为什么不用 defer?

Both async and defer scripts begin to download immediately without pausing the parser and both support an optional onl oad handler to address the common need to perform initialization which depends on the script. The difference between async and defer centers around when the script is executed. Each async script executes at the first opportunity after it is finished downloading and before the window’s load event. This means it’s possible (and likely) that async scripts are not executed in the order in which they occur in the page. The defer scripts, on the other hand, are guaranteed to be executed in the order they occur in the page. That execution starts after parsing is completely finished, but before the document’s DOMContentLoaded event.

大概意思:asyncdefer 特性在脚本开始下载时,都不会阻塞文档解析。并且都支持 onl oad 事件回调处理,用于一些初始化工作。另外,两者对内联脚本都无效,脚本中不能调用document.write()。而两者的不同之处:带有 async 特性的脚本会在脚本下载完后立即执行,且在 load 事件之前,所以不能确保脚本在文档中出现的顺序来执行。而带有defer特性的脚本会在文档解析完后按照在文档中出现的顺序来执行,且在 DOMContentLoaded 事件之前。

因此,这里设置 async 特性,而不设置 defer 特性。为了尽早地触发 DOMContentLoaded 事件,因为 defer 会延迟 DOMContentLoaded 事件触发。

为 script 标签添加 async 特性:

async

通过DevTools->network:

async


当然,这里也可以通过媒体查询 media让 style-sheet 异步加载:
media

通过DevTools->network:

media

总结:

  • style-sheet 默认情况下是不会阻塞文档解析。
  • style-sheet 只会阻塞 script 脚本解析执行。因为 script 脚本需要访问 style-sheet 样式信息,为了确保样式信息的正确性,因此 script 脚本需要等待 style-sheet 下载解析完。从而导致 style-sheet 间接地阻塞文档解析。
  • style-sheet 可以通过媒体查询 media来实现异步加载。
  • 为 script 设置 aysnc 特性来实现 script 异步加载,来加快文档解析。

参考文章:

标签:style,sheet,script,外部,也许,阻塞,文档,样式表,解析
来源: https://www.cnblogs.com/homehtml/p/11933138.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有