[关闭]
@yacent 2016-10-21T17:28:42.000000Z 字数 2038 阅读 1209

HTML文档的加载顺序

性能优化


加载的顺序,浏览器在获取了一个html文档时,会 自上而下 地进行加载,在加载过程中进行解析渲染

如前所述,网络的模型是同步的。网页作者希望解析器遇到 <script> 标记时立即解析并执行脚本。文档的解析将停止,直到脚本执行完毕。如果脚本是外部的,那么解析过程会停止,直到从网络同步抓取资源完成后再继续。

加载


原因:
    JS有可能会修改DOM,最为经典的document.write,这意味着,在JS执行 完成前,后续所有资源的下载可能是没有必要的,这是js阻塞后续资源下载的根本原因。

办法:
    可以将外部引用的js文件放在</body>前。

浏览器的五个常驻线程

  1. 浏览器GUI渲染线程
  2. JavaScript引擎线程
  3. 浏览器定时器触发线程(setTimeout)
  4. 浏览器事件触发线程
  5. 浏览器http异步请求线程
    注意:这里涉及到 阻塞 的现象,当js引擎线程(第二个)进行时,会挂起其他一切线程

加载过程js文件优化方式:
1. prefetch 一般现在的浏览器也已经做了这个优化,会并行地发送文件请求,但是执行与否要等到真正调用的时候才会执行,还是会阻塞其他
2. 放在body后面,这个还是比较常用的,不会阻塞DOM树的构造
3. defer async: defer的话,延迟,在onload事件前触发,就是烦在js文件之间必须按顺序写,因为存在依赖关系,但是可以用模块化解决(AMD CMD之中个 loader),async的话,异步,但是有个缺点,是他们真正到达的时间不确定,哪个下载好了就执行,这给js之间存在依赖关系时,带来很大的问题


JavaScript的性能优化:加载和执行

脚本位置

<script>标签尽可能放到 <body> 标签的底部,以尽量减少对整个页面加载、解析、渲染的影响

组织脚本

由于每个<script>标签初始下载会阻塞页面渲染,故减少页面包含的<script>标签数量有助于改善这依情况。因为HTTP请求的延迟影响,过多的文件请求会带来性能的开销。应根据实际情况,进行相对应文件的合并。
但是,不要一味地进行合并,因为如果合并后,文件过大,对于请求等待的时间,也会很长,网页将会有一段时间失去响应,这交互也不好。

无阻塞脚本

关键在于 页面加载完成后 才加载JavaScript代码,即window对象的onload事件触发后再下载脚本

延迟脚本

defer:
执行时机:DOM加载完成之前,即将要完成的时候,实际效果和 放在底部 类似
脚本会延迟加载,即在DOM完成加载之后,才进行加载,解析和执行,但是其兼容性不好,目前只有IE和firefox支持,其余浏览器都忽略该属性,而且,js文件的顺序必须按顺序写,才能解决依赖性的问题

async:
异步地加载和执行脚本,但是async情况下,js脚本一旦下载好就会执行,可能不按照原本的顺序来执行,故文件之间的依赖关系也很难维护

动态脚本元素

将以上三者用一个函数来进行封装,如下

  1. function loadScript(url, callback) {
  2. var script = document.createElement('script');
  3. script.type = 'text/javascript';
  4. if (script.readyState) { // IE
  5. script.onreadystatechange = function() {
  6. if (script.readyState == "loaded" || script.readyState == "complete") {
  7. script.onreadystatechange = null;
  8. callback();
  9. }
  10. };
  11. } else { // others
  12. script.onload = function() {
  13. callback();
  14. };
  15. }
  16. script.src = url;
  17. document.getElementsByTagName('head')[0].appendChild(script);
  18. }

总结

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注