javascript 性能分析:响应接口

浏览器UI线程:大多浏览器有一个单独的处理进程 有2个任务所共享:javascript任务和用户界面更新任务 但每个时刻只有其中一个操作得以执行。

这UI线程围绕一个简单的队列系统工作 任务被保存打牌队列中直到进程空闲,一旦空闲 队列中的下一个任务将被检索和运行

<html>
<head>
<title>Browser UI Thread Example</title>
</head>
<body>
<button οnclick="handleClick()">Click Me</button>
<script type="text/javascript">
function handleClick(){
var div = document.createElement("div");
div.innerHTML = "Clicked!";
document.body.appendChild(div);
}
</script>
</body>
</html>

当用户的按钮被点击 触发了UI线程创建2个任务并添加到队列中 第一个任务是改变外观 第二个是javascript运行任务

当UI线程空闲 先更新外观 然后运行javascript 运行过程中 handleClick()创建了一个新元素 追加到body元素上 引起了另外一次的Ui改变。但javascript没有运行完成 Ui线程会停止队列中的任务 这样会影响用户的交互。

浏览器限制:

浏览器在javascript运行时间上采取了限制 确保恶意代码不能通过或长时间运行脚本终止和失控脚本控制

限制有2个:调用栈尺寸限制和长时间脚本限制

Internet Explorer  默认设置为5百万条语句 注册表体现:HKEY_CURRENT_USER\Software\Microsoft\InternetExplorer\Styles\MaxScriptStatements

Firefox:默认是10秒  dom.max_script_run_time

Safari:默认是5秒 develop菜单可以选择 禁止失控javascript定时器

Chrome: 没有独立的长运行脚本的限制 替代以依赖它的通用崩溃检测系统来处理

Opera:没有限制 由于他的结构问题 运行结束时不会导致系统不稳定

一般单一的javascript操作使用正常的时间 是100毫秒  但是如果100毫秒执行不完 可以用定时器解决这个问题

定时器解决优化数组:

for (var i=0, len=items.length; i < len; i++){
process(items[i]);
}

这个循环速度取决与process方法复杂度和items的大小 是否可以用定时器优化 看2个元素

这个过程必须是同步处理?数据必须是按顺序处理?

如果都是否 那就可以用定时器优化:

var todo = items.concat(); //create a clone of the original
setTimeout(function(){
//get next item in the array and process it
process(todo.shift());
//if there's more items to process, create another timer
if(todo.length > 0){
setTimeout(arguments.callee, 25);
} else {
callback(items);
}
}, 25);

封装一下:

function processArray(items, process, callback){
var todo = items.concat(); //create a clone of the original
setTimeout(function(){
process(todo.shift());
if (todo.length > 0){
setTimeout(arguments.callee, 25);
} else {
callback(items);
}
}, 25);
}

分解任务:如果函数运行时间太长 可以拆分一系列更小的步骤 把独立方法放在定时器中调用

function saveDocument(id){
var tasks = [openDocument, writeText, closeDocument, updateUI];
setTimeout(function(){
//execute the next task
var task = tasks.shift();
task(id);
//determine if there's more
if (tasks.length > 0){
setTimeout(arguments.callee, 25);
}
}, 25);
}

上面这个方法将每个方法放入任务数组 然后在每个定时器调用一个方法  封装一下:

function multistep(steps, args, callback){
var tasks = steps.concat(); //clone the array
setTimeout(function(){
//execute the next task
var task = tasks.shift();
task.apply(null, args || []);
//determine if there's more

if (tasks.length > 0){
setTimeout(arguments.callee, 25);
} else {
callback();
}
}, 25);
}

但是 过度使用定时器会产生负面影响 最好保证同一个时间只有一个定时器执行

 网页工人线程API 可以在浏览器UI线程之外的运行代码 不占用浏览器UI线程的时间 html5好像实现这功能

网页工人线程运行环境:

一个浏览器对象 只包含4个属性:appName, appVersion, userAgent, platform

一个location对象 和window里的一样 只是所有属性都是可读的

一个self对象指向全局工人线程对象

一个importScripts()方法 使工人线程可以加载外部javascript文件

所有的ECMAScript对象 例如 Object Array Data

XMLHttpRequest构造器

setTimeout() 和setInterval() 方法

close方法可以立即停止工人线程

因为网页工人线程有不同的全局运行环境 不能在javascript代码创建 要创建一个独立的javascript 包括那些工人线程中的代码 创建网页工人线程:

var worker = new Worker("code.js");

工人线程通过事件和网页代码进行交互

var worker = new Worker("code.js");
worker.onmessage = function(event){
alert(event.data);
};
worker.postMessage("Nicholas");

上面postMessage方法是传送信息onmessage是接收信息

网页工人线程加载外部js

importScripts("file1.js", "file2.js");
self.onmessage = function(event){
self.postMessage("Hello, " + event.data + "!");
};

网页工人线程用处:解析一个很大的json字符串 足够大至少要500毫秒 时间太长以至于不允许javascript在客户端运行

实例:

var worker = new Worker("jsonparser.js");
//when the data is available, this event handler is called
worker.onmessage = function(event){
//the JSON structure is passed back
var jsonData = event.data;
//the JSON structure is used
evaluateData(jsonData);

};
//pass in the large JSON string to parse
worker.postMessage(jsonText);

 

//inside of jsonparser.js
//this event handler is called when JSON data is available
self.onmessage = function(event){
//the JSON string comes in as event.data
var jsonText = event.data;
//parse the structure
var jsonData = JSON.parse(jsonText);
//send back to the results
self.postMessage(jsonData);
};

注意:有些浏览器不支持event.data 像 Safari 4 Chrome 3只支持字符串传送

还有 编或解码一个大字符串

复杂数学运算(像图像和视频处理)

给一个大数组排序

或是处理超过100毫秒 都应该考虑

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值