原文链接(https://developers.google.com/web/fundamentals/performance/rendering/optimize-javascript-execution)
js的执行会引起视图的变化,视图的变化有时候是直接通过样式的改变,有时候是由于计算,比如说是搜索或者数据排序。js的执行效率是导致页面表现力的通常的原因,我们需要尽量减少这样的影响
现代浏览器使用及时编译器,利用各种优化方法和技巧使代码的执行效率达到最佳
这里有一些很基础的建议可以帮助优化js的执行效率
1. 避免使用setTimeout或者setInterval去更新视图;用requestAnimationFrame来更新(涉及到硬件的优化)
2. 把那些需要长时间运行的js提取出来放到Web Workers里面去做
3. 用微任务去更新dom节点
4. 用chrome的Timeline和js Profiler区做js运行评估
为什么要用requestAnimationFrame来做视图更新
在视图更新即将发生在屏幕时,唯一可以保证你的任务在正确的时间点上被调用的方法是requestAnimationFrame
function updateScreen(time){
}
requestAnimationFrame(updateScreen)
有些框架或者说例子也许会用setTimeout or setInterval去做视图的更新,但是问题是执行任务的时间点无法确保是在每一帧开始的位置
减少复杂性或者用web workers
js和样式的计算,布局,绘图等一起运行在浏览器的主线程上,要是js运行了很长时间,这会阻塞其他的任务
在很多情况下,我们可以将计算量大的工作交给web worker,例如,不需要访问dom.
但是像数据修改,遍历,排序, 搜索很适合
var dataSortWorker = new Worker("sort-worker.js"); //instantiate an web worker
dataSortWorker.postMessage(dataToSort); // pass data to webworker
dataSortWorker .addEventListener('message', function(evt){
var sortedData = evt.data;
//update on screen
}) // once done, inform to update data on screen
有些时候我们可以通过批处理的方式来更新视图
var taskList = breakTaskIntoMicroTask(monsterTaskList)
requestAnimationFrame(processTaskList);
function processTaskList(taskStartTime) {var taskFinishTime;
do {
// Assume the next task is pushed onto a stack.
var nextTask = taskList.pop();
// Process nextTask.
processTask(nextTask);
// Go again if there’s enough time to do the next task.
taskFinishTime = window.performance.now(); } while (taskFinishTime - taskStartTime < 3);
if (taskList.length > 0)
requestAnimationFrame(processTaskList);
}
网友评论