几百个函数需要执行,怎么优化
大约 5 分钟
优化大量函数执行的页面性能策略
1. 函数执行优化
函数防抖和节流
// 防抖:延迟执行,避免频繁触发
function debounce(func, delay) {
let timeoutId;
return function (...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func.apply(this, args), delay);
};
}
// 节流:限制执行频率
function throttle(func, limit) {
let inThrottle;
return function (...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
// 应用示例
const handleScroll = debounce(() => {
// 处理滚动事件中的多个函数调用
updateUI();
calculatePositions();
renderComponents();
}, 100);函数记忆化(Memoization)
// 缓存昂贵计算的结果
function memoize(fn) {
const cache = new Map();
return function (...args) {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const result = fn.apply(this, args);
cache.set(key, result);
return result;
};
}
// 应用到计算密集型函数
const expensiveCalculation = memoize((data) => {
// 复杂计算逻辑
return data.reduce((acc, item) => acc + Math.sqrt(item.value), 0);
});2. 时间切片(Time Slicing)
使用 requestIdleCallback 分割任务
// 将大量函数分割成小块执行
class TaskScheduler {
constructor() {
this.tasks = [];
this.isRunning = false;
}
addTask(task) {
this.tasks.push(task);
}
start() {
if (this.isRunning) return;
this.isRunning = true;
this.runTasks();
}
runTasks() {
if (this.tasks.length === 0) {
this.isRunning = false;
return;
}
// 使用requestIdleCallback在浏览器空闲时执行
requestIdleCallback((deadline) => {
// 在浏览器空闲时间内尽可能多地执行任务
while (deadline.timeRemaining() > 0 && this.tasks.length > 0) {
const task = this.tasks.shift();
task();
}
// 如果还有任务,继续调度
if (this.tasks.length > 0) {
this.runTasks();
} else {
this.isRunning = false;
}
});
}
}
// 使用示例
const scheduler = new TaskScheduler();
// 添加几百个函数
for (let i = 0; i < 500; i++) {
scheduler.addTask(() => {
// 具体的函数逻辑
processItem(i);
});
}
scheduler.start();使用 setTimeout 实现时间切片
// 手动控制任务执行节奏
function timeSlice(tasks, chunkSize = 10) {
return new Promise((resolve) => {
function processChunk() {
const chunk = tasks.splice(0, chunkSize);
// 执行当前块的所有任务
chunk.forEach(task => task());
// 如果还有任务,安排下一帧继续执行
if (tasks.length > 0) {
setTimeout(processChunk, 0);
} else {
resolve();
}
}
processChunk();
});
}
// 使用示例
const functions = Array.from({ length: 500 }, (_, i) => () => {
// 每个函数的具体实现
performTask(i);
});
timeSlice(functions, 20).then(() => {
console.log('所有函数执行完成');
});3. Web Workers 并行处理
将计算密集型任务移到Web Worker
// main.js
class WorkerPool {
constructor(size) {
this.workers = [];
this.taskQueue = [];
this.workerQueue = [];
for (let i = 0; i < size; i++) {
const worker = new Worker('worker.js');
worker.onmessage = (e) => {
this.handleWorkerMessage(worker, e.data);
};
this.workers.push(worker);
this.workerQueue.push(worker);
}
}
execute(task) {
return new Promise((resolve, reject) => {
this.taskQueue.push({ task, resolve, reject });
this.processQueue();
});
}
processQueue() {
if (this.taskQueue.length === 0 || this.workerQueue.length === 0) {
return;
}
const worker = this.workerQueue.shift();
const task = this.taskQueue.shift();
worker.postMessage(task.task);
worker.currentTask = task;
}
handleWorkerMessage(worker, result) {
const task = worker.currentTask;
if (result.error) {
task.reject(new Error(result.error));
} else {
task.resolve(result.data);
}
worker.currentTask = null;
this.workerQueue.push(worker);
this.processQueue();
}
}
// 使用示例
const workerPool = new WorkerPool(4); // 4个worker线程
// 执行大量函数
async function executeManyFunctions() {
const results = [];
for (let i = 0; i < 500; i++) {
const result = await workerPool.execute({
functionName: 'processData',
params: { index: i, data: getData(i) }
});
results.push(result);
}
return results;
}// worker.js
self.onmessage = function(e) {
const { functionName, params } = e.data;
try {
let result;
switch (functionName) {
case 'processData':
result = processData(params);
break;
// 其他函数...
}
self.postMessage({ data: result });
} catch (error) {
self.postMessage({ error: error.message });
}
};
function processData(params) {
// 复杂计算逻辑
return params.data.map(item => item * 2);
}4. 优先级调度
实现任务优先级系统
class PriorityTaskScheduler {
constructor() {
this.queues = {
high: [],
medium: [],
low: []
};
this.isRunning = false;
}
addTask(task, priority = 'medium') {
this.queues[priority].push(task);
if (!this.isRunning) {
this.start();
}
}
start() {
if (this.isRunning) return;
this.isRunning = true;
this.runNextTask();
}
runNextTask() {
let task;
// 优先执行高优先级任务
if (this.queues.high.length > 0) {
task = this.queues.high.shift();
} else if (this.queues.medium.length > 0) {
task = this.queues.medium.shift();
} else if (this.queues.low.length > 0) {
task = this.queues.low.shift();
} else {
this.isRunning = false;
return;
}
try {
task();
} catch (error) {
console.error('Task execution error:', error);
}
// 使用requestIdleCallback继续执行下一个任务
requestIdleCallback(() => this.runNextTask());
}
}
// 使用示例
const scheduler = new PriorityTaskScheduler();
// 添加不同优先级的任务
for (let i = 0; i < 500; i++) {
if (i < 10) {
// 前10个高优先级(如UI更新)
scheduler.addTask(() => updateCriticalUI(i), 'high');
} else if (i < 100) {
// 接下来90个中优先级(如数据处理)
scheduler.addTask(() => processData(i), 'medium');
} else {
// 剩余低优先级(如日志记录)
scheduler.addTask(() => logData(i), 'low');
}
}5. 懒执行和按需加载
延迟执行非关键函数
class LazyExecutor {
constructor() {
this.functions = new Map();
this.executed = new Set();
}
register(name, fn, isCritical = false) {
this.functions.set(name, fn);
// 关键函数立即执行
if (isCritical) {
this.execute(name);
}
}
execute(name) {
if (this.executed.has(name) || !this.functions.has(name)) {
return;
}
const fn = this.functions.get(name);
fn();
this.executed.add(name);
}
// 按需执行所有函数
executeAll() {
for (const [name, fn] of this.functions) {
if (!this.executed.has(name)) {
fn();
this.executed.add(name);
}
}
}
}
// 使用示例
const executor = new LazyExecutor();
// 注册函数
for (let i = 0; i < 500; i++) {
executor.register(
`function_${i}`,
() => performTask(i),
i < 20 // 前20个为关键函数
);
}
// 页面加载完成后执行剩余函数
window.addEventListener('load', () => {
setTimeout(() => {
executor.executeAll();
}, 1000);
});6. 批处理优化
合并相似操作
class BatchProcessor {
constructor() {
this.batches = new Map();
}
// 批处理相似的函数调用
batch(key, operation, delay = 16) {
if (!this.batches.has(key)) {
this.batches.set(key, []);
}
this.batches.get(key).push(operation);
// 延迟执行批处理
clearTimeout(this.batches.get(key).timer);
this.batches.get(key).timer = setTimeout(() => {
this.executeBatch(key);
}, delay);
}
executeBatch(key) {
const operations = this.batches.get(key);
if (operations && operations.length > 0) {
// 合并执行所有操作
operations.forEach(op => op());
this.batches.delete(key);
}
}
}
// 使用示例
const processor = new BatchProcessor();
// 批处理DOM更新
for (let i = 0; i < 500; i++) {
processor.batch('dom-update', () => {
document.getElementById(`item-${i}`).textContent = `Updated ${i}`;
});
}7. 综合优化策略
完整的性能优化方案
class PerformanceOptimizer {
constructor() {
this.scheduler = new PriorityTaskScheduler();
this.workerPool = new WorkerPool(4);
this.cache = new Map();
this.batchProcessor = new BatchProcessor();
}
optimizeFunctionExecution(functions) {
// 1. 分类函数优先级
const categorized = this.categorizeFunctions(functions);
// 2. 关键函数立即执行
this.executeCriticalFunctions(categorized.critical);
// 3. 计算密集型函数使用Web Worker
this.executeInWorker(categorized.computation);
// 4. 其余函数使用时间切片
this.executeWithTimeSlicing(categorized.other);
}
categorizeFunctions(functions) {
return {
critical: functions.filter((_, i) => i < 20),
computation: functions.filter((_, i) => i >= 20 && i < 100),
other: functions.filter((_, i) => i >= 100)
};
}
executeCriticalFunctions(functions) {
functions.forEach(fn => {
this.scheduler.addTask(fn, 'high');
});
}
async executeInWorker(functions) {
const promises = functions.map(fn =>
this.workerPool.execute({ fn: fn.toString() })
);
await Promise.all(promises);
}
executeWithTimeSlicing(functions) {
timeSlice(functions, 20);
}
}
// 使用示例
const optimizer = new PerformanceOptimizer();
const functions = Array.from({ length: 500 }, (_, i) => () => {
// 各种函数实现
return performTask(i);
});
optimizer.optimizeFunctionExecution(functions);总结
优化大量函数执行的关键策略:
- 时间切片:将任务分割成小块,避免阻塞主线程
- 优先级调度:优先执行关键任务
- Web Workers:将计算密集型任务移到后台线程
- 防抖节流:减少不必要的函数执行
- 记忆化:缓存重复计算结果
- 懒执行:延迟执行非关键函数
- 批处理:合并相似操作减少开销
通过组合使用这些策略,可以显著提升包含大量函数执行的页面性能。