浏览器渲染 defer async css cssom
2017-11-13 11:21
267 查看
转自:http://web.jobbole.com/92765/
阻塞渲染:CSS 与 JavaScript
谈论资源的阻塞时,我们要清楚,现代浏览器总是并行加载资源。例如,当 HTML 解析器(HTML Parser)被脚本阻塞时,解析器虽然会停止构建 DOM,但仍会识别该脚本后面的资源,并进行预加载。同时,由于下面两点:
默认情况下,CSS 被视为阻塞渲染的资源,这意味着浏览器将不会渲染任何已处理的内容,直至 CSSOM 构建完毕。
JavaScript 不仅可以读取和修改 DOM 属性,还可以读取和修改 CSSOM 属性。
存在阻塞的 CSS 资源时,浏览器会延迟 JavaScript 的执行和 DOM 构建。另外:
当浏览器遇到一个 script 标记时,DOM 构建将暂停,直至脚本完成执行。
JavaScript 可以查询和修改 DOM 与 CSSOM。
CSSOM 构建时,JavaScript 执行将暂停,直至 CSSOM 就绪。
所以,script 标签的位置很重要。实际使用时,可以遵循下面两个原则:
CSS 优先:引入顺序上,CSS 资源先于 JavaScript 资源。
JavaScript 应尽量少影响 DOM 的构建。
浏览器的发展日益加快(目前的 Chrome 官方稳定版是 61),具体的渲染策略会不断进化,但了解这些原理后,就能想通它进化的逻辑。下面来看看 CSS 与 JavaScript 具体会怎样阻塞资源。
CSS
JavaScript12 | <style> p { color: red; }</style><link rel="stylesheet" href="index.css"> |
1 2 3 | <link href="index.css" rel="stylesheet"> <link href="print.css" rel="stylesheet" media="print"> <link href="other.css" rel="stylesheet" media="(min-width: 30em) and (orientation: landscape)"> |
第二个资源设置了媒体类型,会加载但不会阻塞,print 声明只在打印网页时使用。
第三个资源提供了媒体查询,会在符合条件时阻塞渲染。
JavaScript
JavaScript 的情况比 CSS 要更复杂一些。观察下面的代码:JavaScript
1234567891011 | <p>Do not go gentle into that good night,</p><script>console.log("inline")</script><p>Old age should burn and rave at close of day;</p><script src="app.js"></script><p>Rage, rage against the dying of the light.</p> <p>Do not go gentle into that good night,</p><script src="app.js"></script><p>Old age should burn and rave at close of day;</p><script>console.log("inline")</script><p>Rage, rage against the dying of the light.</p> |
改变阻塞模式:defer 与 async
为什么要将 script 加载的 defer 与 async 方式放到后面呢?因为这两种方式是的出现,全是由于前面讲的那些阻塞条件的存在。换句话说,defer 与 async 方式可以改变之前的那些阻塞情形。首先,注意 async 与 defer 属性对于 inline-script 都是无效的,所以下面这个示例中三个 script 标签的代码会从上到下依次执行。JavaScript1 2 3 4 5 6 7 8 9 10 | <!-- 按照从上到下的顺序输出 1 2 3 --> <script async> console.log("1"); </script> <script defer> console.log("2"); </script> <script> console.log("3"); </script> |
defer
JavaScript123 | <script src="app1.js" defer></script><script src="app2.js" defer></script><script src="app3.js" defer></script> |
async
JavaScript1 2 3 | <script src="app.js" async></script> <script src="ad.js" async></script> <script src="statistics.js" async></script> |
从上一段也能推出,多个 async-script 的执行顺序是不确定的。值得注意的是,向 document 动态添加 script 标签时,async 属性默认是 true,下一节会继续这个话题。
document.createElement
使用 document.createElement 创建的 script 默认是异步的,示例如下。JavaScript
1 | console.log(document.createElement("script").async); // true |
1 2 3 4 | const style = document.createElement("link"); style.rel = "stylesheet"; style.href = "index.css"; document.head.appendChild(style); // 阻塞? |
在以前是阻塞的,现在会怎样我没有试验。
相关文章推荐
- 浏览器环境下JavaScript脚本加载与执行探析之defer与async特性
- 浏览器加载跟渲染html的顺序-css渲染效率的探究
- 解释一下你对盒模型的理解,以及如何在 CSS 中告诉浏览器使用不同的盒模型来渲染你的布局。
- 【浏览器渲染原理】解析和DOM树构建之CSS解析
- 浏览器渲染页面、CSS原理及优化
- 浏览器加载和渲染html的顺序-css渲染效率的探究
- 解释一下你对盒模型的理解,以及如何在 CSS 中告诉浏览器使用不同的盒模型来渲染你的布局。
- 浏览器加载和渲染html的顺序(html/css/js)
- 解释一下你对盒模型的理解,以及如何在 CSS 中告诉浏览器使用不同的盒模型来渲染你的布局。
- 浏览器加载和渲染html的顺序(html/css/js)
- 利用浏览器CSS渲染原理写出高性能的CSS代码
- 如何书写高性能的css(原题:优化浏览器渲染)
- 解释一下你对盒模型的理解,以及如何在 CSS 中告诉浏览器使用不同的盒模型来渲染你的布局。
- CSS Position定位过多是否会影响浏览器渲染速度
- 浏览器环境下JavaScript脚本加载与执行探析之defer与async特性
- 浏览器加载渲染HTML、DOM、CSS、 JAVASCRIPT、IMAGE、FLASH、IFRAME、SRC属性等资源的顺序总结
- 解释一下你对盒模型的理解,以及如何在 CSS 中告诉浏览器使用不同的盒模型来渲染你的布局。
- 浏览器css渲染差异
- IE的CSS渲染跟其它浏览器有什么不同