<script>
标签的数量,包括内嵌和外链脚本,最小化执行延迟会明显改善页面性能,
方式一:合并
方式二:<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>
defer
延迟脚本,兼容性不佳,代码仍会下载,但会等到DOM加载完,onload事件触发前执行<script defer>
alert("defer");
</script>
<script>
alert("script");
</script>
<script>
window.onload = function(){
alert("load");
};
</script>
不支持defer属性的浏览器:defer、script、load 支持defer属性的浏览器:script、defer、load 3.2 动态添加script标签,添加到head中比添加到body中安全 3.3 XHR动态脚本注入兼容性好,但不能跨域
var xhr = new XMLHttpRequest();
xhr.open("get", "file1.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.send(null);
3.4 推荐的方式
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 { //Others
script.onload = function(){
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
loadScript("the-rest.js", function(){
Application.init();
});
3.5 LazyLoad类库实现懒加载
var doc = document;
doc.X……
doc.XX……
doc.XXX……
var alldivs = document.getElementsByTagName('div');
for (var i = 0; i < alldivs.length; i++) {
document.body.appendChild(document.createElement('div'))
}
这个例子反映了集合的动态性,此处为死循环,因为alldivs.length是不断更新的,并且速度相比直接查询数组length慢很多,因为length每次都要重新查询。优化方法:1、把HTMLCollection存储在局部变量数组中;2、把length缓存在循环外部。 5. 在IE中,nextSibling比childNode表现优异,选择过滤非元素节点的api效率更高。
属性名 被替代的属性
children childNodes
childElementCount childNodes.length
firstElementChild firstChild
lastElementChild lastChild
nextElementSibling nextSibling
previousElementSibling previousSibling
document.querySelector('#menu a');
减少事件处理器数量,利用了事件三个阶段:捕获–>到达目标–>冒泡 中的最后一个阶段。在父元素绑定事件,实现对子元素的事件监听,需要实现一堆浏览器兼容代码,流程:1、访问事件对象,判断事件源;2、取消文档树中的冒泡(可选);3、阻止默认操作(可选)
通常情况下, switch比if-else快,switch适合于使用一系列的操作的场景,当单个键和单个值存在逻辑映射且判断条件较多时,使用查找表(数组映射)比使用if-else/switch效率更高
浏览器的调用栈大小限制了递归的使用规模,尽量使用迭代代替递归 栈溢出错误的解决方式: 使用try-catch捕获
try{
// 递归程序
}catch(e){}
String.prototype.trim = function(){
var str = this.replace(/^\s+/,""),
end = str.length - 1,
ws = /\s/;
while(ws.test(str.charAt(end))){
end--;
}
return str.slice(0,end+1);
}
function timedProcessArray(items,process,callback){
var todo = items.concat(); // 克隆原始数组
setTimeout(function(){
var start = +new Date();
do{
process(todo.shift());
}while(todo.length > 0 && (+new Date()-start<50));
if(todo.length>0){
setTimeout(arguments.callee,25);
}else{
callback(items);
}
},25);
}
【常用】: 1. XMLHttpRequest (XHR): 收到的所有数据当成一个字符串,可能降低解析速度 2. Dynamic script tag insertion 动态脚本注入(跨域) 3. Multipart XHR (MXHR) 优点:客户端一个HTTP请求从服务器端获取多个资源(http请求对ajax的性能影响极大) 缺点:浏览器无法缓存资源、老版本IE不支持 readyState==3 和 data:URL
// 实时处理请求响应数据
var req = new XMLHttpRequest();
var getLatestPacketInterval, lastLength = 0;
req.open('GET', 'rollup_images.php', true);
req.onreadystatechange = readyStateHandler;
req.send(null);
function readyStateHandler{
// 传输中
if (req.readyState === 3 && getLatestPacketInterval === null) {
// Start polling.
getLatestPacketInterval = window.setInterval(function() {
getLatestPacket();
}, 15);
}
// 传输结束
if (req.readyState === 4) {
// Stop polling.
clearInterval(getLatestPacketInterval);
// Get the last packet.
getLatestPacket();
}
}
function getLatestPacket() {
var length = req.responseText.length;
var packet = req.responseText.substring(lastLength, length);
processPacket(packet);
lastLength = length;
}
编写健壮的MXHR代码较为复杂,此处略过……
【极端】: 4. iframes 5. Comet
req.onerror = function() {
setTimeout(function() {
xhrPost(url, params, callback);
}, 1000);
};
请求失败时重发数据有利于用户体验 2. 信标(beacons)
<script>
标签来调用服务器提供的js脚本var localCache = {};
function xhrRequest(url, callback) {
// Check the local cache for this URL.
if (localCache[url]) {
callback.success(localCache[url]);
return;
}
// If this URL wasn't found in the cache, make the request.
var req = createXhrObject();
req.onerror = function() {
callback.error();
};
req.onreadystatechange = function() {
if (req.readyState == 4) {
if (req.responseText === '' || req.status == '404') {
callback.error();
return;
}
// Store the response on the local cache.
localCache[url] = req.responseText;
callback.success(req.responseText);
}
};
req.open("GET", url, true);
req.send(null);
}
delete localCache['/user/friendlist/'];
delete localCache['/user/contactlist/'];
避免使用 eval()、Function(),给setTimeout()、setInterval()传递函数作为参数而非字符串
{}、[] 速度更快且代码简洁
使用延迟加载、条件预加载
尤其是数学运算与DOM操作
合并js文件减少请求数、使用YUI Compressor压缩js文件、服务器端压缩js代码(Gzip)、设置http响应头缓存js文件、使用CDN