javascript高性能
2015-12-03 13:26
585 查看
我在《javascript高性能》 这本书里面读到这个文章,所以做一下学习笔记,供大家一块学习:
无阻塞脚本的概念什么?
为什么要用无阻塞脚本?
如何实现无阻塞脚本,和每个实现方式应该注意什么问题?
我来围绕以上4个问题来展开阐述:
1.无阻塞脚本的概念是什么?
无阻塞脚本也就是在下载js的时候,不影响网页中其他内容(html,css,image)的下载
2.为什么要用到无阻塞脚本?
网页中的内容无非包括的有(html,css,js,image)等这些内容,但是浏览器在下载这些文件的时候是单线程进行的,所以说:在下载东西的时
候,是一个下载完成之后才能下载另一个文件,在这些内容之中,html+css+image
可能就可以让用户眼前显示出来页面的大体内容,而js是一些动画效果,验证之类的东西,可以在这些东西加载完毕之后来加载js,或者也可以是异步加载
js,这样就可以不影响其他内容的影响,所以这样,就会用到无阻塞脚本技术.
如果js的大小不是很大的时候,可能没有什么影响,如果js的大小灰常或者不是小的情况下,可以考虑采用无阻塞脚本,如果不采用可能用导致用户打开页面是
一片空白,因为这个时候可能是在加载js的原因引起的.
那有的人说css也可以延迟加载,因为他也是有大小的,这个css是渲染页面(告诉浏览器dom树如何显示),所以这个必须是在js前面加载,还有比如在
js里面算某个节点的位置之类的,这个必须得到css渲染页面完成之后,才能得到准确的位置.
3.如何实现无阻塞脚本?
书里面提供了三种方式来实现无阻塞脚本:
延迟脚本属性: defer属性
也就是在脚本的标签里面添加defer属性来实现,最后加载这段javascript
[javascript] view plaincopy
<script type="text/javascript" defer>
//添加defer属性,first会在second弹出之后执行
alert("first");
</script>
<script type="text/javascript">
//没有添加defer属性,second会在first弹出之前执行
alert("second");
</script>
缺点: 只有 Internet Explorer4+和firefox 3.5+ 支持 defer 属性,如果要适应其他的浏览器,只能选择下面的几个方案了
动态脚本语言
也就是通过Dom的方法, createElement方法来创建动态的script标签,检测标签加载完成是script的onload方法来检测加载成功,而ie里面不支持这个方法,则是onreadystatechange方法来检测.详细看以下代码:
[javascript] view plaincopy
function addScript(src,callBack)
{
var head=document.documentElement.getElementsByTagName("head")[0];
var scri=document.createElement("script");
scri.type="text/javascript";
/*ie browser*/
if(document.all)
{
scri.onreadystatechange=function()
{
if(scri.readyState=="loaded"||scri.readyState=="complete")
{
alert(src+" ie brower 加载完毕!");
callBack&&callBack();
}
}
}
/*other browser*/
else
{
scri.onload=function()
{
alert(src+" not ie brower 加载完毕!");
callBack&&callBack();
}
}
<pre name="code" class="javascript"><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"> scri.src=src;</blockquote> //一般在设置src之后再append到dom树里面,
//详情 http://www.iefans.net/ie-script-element-readystate/
head.appendChild(scri);</pre>}addScript("js.js",function(){addScript("js2.js")});
<pre></pre>
在
这段代码里面我异步加载了两个js(js.js和js2.js), 在加载第一个js之后又调用了加载第二个js. 应该注意的是ie里面的
onreadystatechange方法里面,判断加载状态(scri.readyState) 的状态有:<br>
<br>
• uninitialized – 原始状态<br>
• loading – 下载数据中..<br>
• loaded – 下载完成<br>
• interactive – 还未执行完毕.<br>
• complete – 脚本执行完毕<br>
<br>
因为在ie各个版本里面无法确定哪个是加载成功,所以判断了两个状态,下载完成和执行完成两种状态,有关详细的ie中script加载状态请参考: http://www.iefans.net/ie-script-element-readystate/<br>
<br>
优点: 1. 兼容各个主流浏览器<br>
2.可以解决js跨域问题.<br>
XMLHttpRequest脚本注入(XHR)
原理:用XMLHTTP取得要脚本的内容,再创建 script 对象。
注意:服务器端js 必须用UTF8编码保存,因为服务器与XML使用UTF8编码传送数据。
代码如下:
[javascript] view plaincopy
<script language="JavaScript">
function GetHttpRequest()
{
if ( window.XMLHttpRequest ) // Gecko
return new XMLHttpRequest();
else if ( window.ActiveXObject ) // IE
return new ActiveXObject("MsXml2.XmlHttp");
}
function AjaxPage(sId, url){
var oXmlHttp = GetHttpRequest();
oXmlHttp.OnReadyStateChange = function()
{
if ( oXmlHttp.readyState == 4 )
{
if ( oXmlHttp.status == 200 || oXmlHttp.status == 304 )
{
IncludeJS( sId, url, oXmlHttp.responseText );
}
else
{
alert( 'XML request error: ' + oXmlHttp.statusText + ' ('+oXmlHttp.status+')') ;
}
}
}
oXmlHttp.open('GET', url, true);
oXmlHttp.send(null);
}
function IncludeJS(sId, fileUrl, source)
{
if ((source!=null)&&(!document.getElementById(sId))){
var oHead = document.getElementsByTagName('HEAD').item(0);
var oScript = document.createElement( "script" );
oScript.language = "javascript";
oScript.type = "text/javascript";
oScript.id = sId;
oScript.defer = true;
oScript.text = source;
oHead.appendChild( oScript );
}
}
AjaxPage( "script1", "b.js" );
</script>
部分源码来自: http://mario-design.iteye.com/blog/147810
优点:
1.兼容各个主流浏览器
缺点:
1.存在js跨域问题, 也就是 www.baidu.com 页面无法下载 www.google.com?aa.js 这个问题
以上是我对无阻塞脚本的总结,博文有什么问题可以直接留言给我或者发送邮件nishiwode923@qq.com. 中间有部分内容来自其他博文,已将链接公布在博文内部,希望原博文lz可以谅解.
无阻塞脚本的概念什么?
为什么要用无阻塞脚本?
如何实现无阻塞脚本,和每个实现方式应该注意什么问题?
我来围绕以上4个问题来展开阐述:
1.无阻塞脚本的概念是什么?
无阻塞脚本也就是在下载js的时候,不影响网页中其他内容(html,css,image)的下载
2.为什么要用到无阻塞脚本?
网页中的内容无非包括的有(html,css,js,image)等这些内容,但是浏览器在下载这些文件的时候是单线程进行的,所以说:在下载东西的时
候,是一个下载完成之后才能下载另一个文件,在这些内容之中,html+css+image
可能就可以让用户眼前显示出来页面的大体内容,而js是一些动画效果,验证之类的东西,可以在这些东西加载完毕之后来加载js,或者也可以是异步加载
js,这样就可以不影响其他内容的影响,所以这样,就会用到无阻塞脚本技术.
如果js的大小不是很大的时候,可能没有什么影响,如果js的大小灰常或者不是小的情况下,可以考虑采用无阻塞脚本,如果不采用可能用导致用户打开页面是
一片空白,因为这个时候可能是在加载js的原因引起的.
那有的人说css也可以延迟加载,因为他也是有大小的,这个css是渲染页面(告诉浏览器dom树如何显示),所以这个必须是在js前面加载,还有比如在
js里面算某个节点的位置之类的,这个必须得到css渲染页面完成之后,才能得到准确的位置.
3.如何实现无阻塞脚本?
书里面提供了三种方式来实现无阻塞脚本:
延迟脚本属性: defer属性
也就是在脚本的标签里面添加defer属性来实现,最后加载这段javascript
[javascript] view plaincopy
<script type="text/javascript" defer>
//添加defer属性,first会在second弹出之后执行
alert("first");
</script>
<script type="text/javascript">
//没有添加defer属性,second会在first弹出之前执行
alert("second");
</script>
缺点: 只有 Internet Explorer4+和firefox 3.5+ 支持 defer 属性,如果要适应其他的浏览器,只能选择下面的几个方案了
动态脚本语言
也就是通过Dom的方法, createElement方法来创建动态的script标签,检测标签加载完成是script的onload方法来检测加载成功,而ie里面不支持这个方法,则是onreadystatechange方法来检测.详细看以下代码:
[javascript] view plaincopy
function addScript(src,callBack)
{
var head=document.documentElement.getElementsByTagName("head")[0];
var scri=document.createElement("script");
scri.type="text/javascript";
/*ie browser*/
if(document.all)
{
scri.onreadystatechange=function()
{
if(scri.readyState=="loaded"||scri.readyState=="complete")
{
alert(src+" ie brower 加载完毕!");
callBack&&callBack();
}
}
}
/*other browser*/
else
{
scri.onload=function()
{
alert(src+" not ie brower 加载完毕!");
callBack&&callBack();
}
}
<pre name="code" class="javascript"><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"> scri.src=src;</blockquote> //一般在设置src之后再append到dom树里面,
//详情 http://www.iefans.net/ie-script-element-readystate/
head.appendChild(scri);</pre>}addScript("js.js",function(){addScript("js2.js")});
<pre></pre>
在
这段代码里面我异步加载了两个js(js.js和js2.js), 在加载第一个js之后又调用了加载第二个js. 应该注意的是ie里面的
onreadystatechange方法里面,判断加载状态(scri.readyState) 的状态有:<br>
<br>
• uninitialized – 原始状态<br>
• loading – 下载数据中..<br>
• loaded – 下载完成<br>
• interactive – 还未执行完毕.<br>
• complete – 脚本执行完毕<br>
<br>
因为在ie各个版本里面无法确定哪个是加载成功,所以判断了两个状态,下载完成和执行完成两种状态,有关详细的ie中script加载状态请参考: http://www.iefans.net/ie-script-element-readystate/<br>
<br>
优点: 1. 兼容各个主流浏览器<br>
2.可以解决js跨域问题.<br>
XMLHttpRequest脚本注入(XHR)
原理:用XMLHTTP取得要脚本的内容,再创建 script 对象。
注意:服务器端js 必须用UTF8编码保存,因为服务器与XML使用UTF8编码传送数据。
代码如下:
[javascript] view plaincopy
<script language="JavaScript">
function GetHttpRequest()
{
if ( window.XMLHttpRequest ) // Gecko
return new XMLHttpRequest();
else if ( window.ActiveXObject ) // IE
return new ActiveXObject("MsXml2.XmlHttp");
}
function AjaxPage(sId, url){
var oXmlHttp = GetHttpRequest();
oXmlHttp.OnReadyStateChange = function()
{
if ( oXmlHttp.readyState == 4 )
{
if ( oXmlHttp.status == 200 || oXmlHttp.status == 304 )
{
IncludeJS( sId, url, oXmlHttp.responseText );
}
else
{
alert( 'XML request error: ' + oXmlHttp.statusText + ' ('+oXmlHttp.status+')') ;
}
}
}
oXmlHttp.open('GET', url, true);
oXmlHttp.send(null);
}
function IncludeJS(sId, fileUrl, source)
{
if ((source!=null)&&(!document.getElementById(sId))){
var oHead = document.getElementsByTagName('HEAD').item(0);
var oScript = document.createElement( "script" );
oScript.language = "javascript";
oScript.type = "text/javascript";
oScript.id = sId;
oScript.defer = true;
oScript.text = source;
oHead.appendChild( oScript );
}
}
AjaxPage( "script1", "b.js" );
</script>
部分源码来自: http://mario-design.iteye.com/blog/147810
优点:
1.兼容各个主流浏览器
缺点:
1.存在js跨域问题, 也就是 www.baidu.com 页面无法下载 www.google.com?aa.js 这个问题
以上是我对无阻塞脚本的总结,博文有什么问题可以直接留言给我或者发送邮件nishiwode923@qq.com. 中间有部分内容来自其他博文,已将链接公布在博文内部,希望原博文lz可以谅解.
相关文章推荐
- javascript typeof 和 instanceof 的区别和联系
- Javascript正则表达式
- servlet&jsp 学习资料
- 把json对象数组属性相同的进行分组,然后取值
- jsp include指令元素
- jsp技术
- Callback Hell-Javascript异步编程指导
- #学习笔记#(4)输入框提示信息不能为空--JavaScript改变CSS样式
- Javascript 严格模式详解
- 比较两种数组随机排序方法的效率 JavaScript版
- 继续学习javascript闭包
- jsp 日期标签的使用
- 解决js页面滚动效果scrollTop在FireFox与Chrome浏览器间的兼容问题的方法
- Newtonsoft.Json(Json.Net)学习笔记
- js获取当前时间
- 序列化模块之 pickle 和 json
- jsp ajax实例讲解
- 在jsp中运用ajax(简单入门)
- jsp 清除session的方法
- JavaScript碰到的几个方法