《高性能 JavaScript》笔记(一):脚本加载和执行
2014-05-04 15:19
561 查看
1.1 把 css 放在头,把 js 放在尾
HTML、CSS 和 JavaScript 的解析任务在同一个线程的队列中进行。脚本加载后会立即被执行,如果将脚本放在 <head> 中,需要等到脚本执行完毕,才能继续解析 <body> 中的内容。
因此绝大部分情况下请将脚本放在 <body> 的底部,也就是 </body> 出现之前。如下:
<!doctype html> <html> <head> <meta charset="utf-8"> <title>示例</title> <!--样式表--> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body> <!--网页主体--> <p>Hello, world!</p> ... ... ... <!--脚本--> <script type="text/javascript" src="script.js"></script> </body> </html>
1.2 合并脚本
一个网站通常需要多个 JavaScript 文件,考虑到 HTTP 请求的开销,下载单个 100 KB 的文件要比下载四个 25 KB 的文件更快。如果你的网站用到了过多的脚本,那么合并它们吧。看看雅虎怎么做:
<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.7.0/build/yahoo/yahoo-min.js&2.7.0/build/event/event-min.js"></script>
1.3 无阻塞脚本
为了创建快速响应的 Web 应用,我们精简代码,合并脚本只产生一次请求,把脚本放在 <body> 底部加载,但仍无法改变脚本的执行会锁死浏览器一段时间这一事 实。为了避免这种问题,可以在页面加载完毕以后才加载 JavaScript 代码,即在 window 的 load 事件触发以后再下载脚本。1.3.1 延迟脚本
给 <script> 标签加一个 defer 属性,告诉浏览器请下载该脚本文件,但不要立即执行它,当网页加载完毕后(但会在 onload 事件触发前)执行代码。如下:<!doctype html> <html> <head> <meta charset="utf-8"> <title>示例</title> </head> <body> <script type="text/javascript" defer> alert('defer'); </script> <script type="text/javascript"> alert('script'); </script> <script type="text/javascript"> window.onload = function() { alert('load'); }; </script> </body> </html>不支持 defer 属性的浏览器弹出顺序为 defer、script、load。而支持 defer 属性的浏览器弹出的顺序为 script、defer、load。
defer 属性的兼容性不好,旧的浏览器和移动设备上兼容性不佳,不过没关系,接下来还有别的解决方案。
1.3.2 动态脚本元素
通过 DOM API 可以用 JavaScript 动态创建 HTML 中的所有元素,包括 <script> 元素。于是,你可以这样加载 JavaScript 脚本:var script = document.createElement('script'); script.type = 'text/javascript'; script.src = 'script.js'; document.head.appendChild(script); // HTML 5 支持,可以使用 docuent.getElementsByTagName('head')[0] 代替这样加载的好处在于:无论何时启动下载,文件的下载和执行过程都不会阻塞页面其他进程。即便将代码放在 <head> 里面也不影响页面,而且推荐将动态生成的 <script> 元素插入到 <head> 中,因为当 <body> 中的内容没有全部完全加载完成时,IE 可能会抛出一个错误。
jQuery 的 $.Ajax() 函数支持回调,回调是个好东西,可以做很多事情。我们想写一个 loadScript(url, callback) 函数,其中的 callback 参数是我们感兴趣的,执行这个 callback 的关键是确定动态脚本元素何时被加载完成,下面给出这个函数:
// 函数定义 function loadScript(url, callback) { var script = document.createElement('script'); script.type = 'text/javascript'; if(script.readyState) { // IE script.onreadystatechange = function() { if(script.readyState == 'loaded' || script.readyState == 'complete') { // 已下载 || 已就绪 script.onreadystatechange = null; // 防止经历上面两种状态时执行两次 callback(); } }; } else { // 其他浏览器 script.onload = function() { callback(); }; } script.src = url; document.getElementsByTagName('head')[0].appendChild(script); } // 使用 loadScript 函数 loadScript('script.js', function() { alert('load successfully'); });
1.3.3 Ajax 请求脚本
// 不完善的实现 var xhr = new XMLHttpRequest(); xhr.open('get', 'script.js', true); xhr.onreadystatechange = function() { if(xhr.readyState == 4) { if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) { var script = document.createElement('script'); script.type = 'text/javascript'; script.text = xhr.responseText; document.body.appendChild(script); } } }不推荐这种方式,因为浏览器的同源策略限制了 xhr 的跨域请求,大型网站的一些静态资源都缓存在 CDN 上面,xhr 请求不到这上面的资源,还要做特殊处理。
loadScript 函数是推荐的方式,具体组织方式看你的习惯。
相关文章推荐
- 高性能JavaScript笔记一(加载和执行、数据访问、DOM编程)
- <高性能javascript>阅读笔记一 ---关于脚本放的位置以及加载方式
- 高性能JavaScript--加载和执行(简要学习笔记一)
- 编写高性能的JavaScript 脚本的加载与执行
- 编写高性能的JavaScript-脚本的加载与执行(1)
- 编写高性能的JavaScript-脚本的加载与执行(2)
- 编写高性能的JavaScript 脚本的加载与执行
- 编写高性能的JavaScript 脚本的加载与执行
- 高性能JavaScript 笔记之 第1章 加载和执行
- 高性能JavaScript-JS脚本加载与执行对性能的影响
- 高性能Javascript:脚本的无阻塞加载策略
- javascript笔记--(第二十三章)动态加载脚本和样式
- 高性能JavaScript:脚本的无阻塞加载策略
- 浏览器环境下JavaScript脚本加载与执行探析之defer与async特性
- 浏览器环境下Javascript脚本加载与执行探析之DOMContentLoaded
- 高性能网站优化-确保异步加载脚本时保持执行顺序
- 1.加载和执行 -高性能JavaScript
- 高性能JavaScript_编程---笔记一(Loading and Execution加载和运行)
- 远程加载 耗时javascript 脚本时,没法取消其执行
- 探析浏览器执行JavaScript脚本加载与代码执行顺序