MST

星途 面试题库

面试题:JavaScript函数定义性能优化之高级场景

在大型JavaScript项目中,涉及频繁调用函数且函数体复杂,包含大量的DOM操作、异步任务等。从函数定义角度出发,如何进行全面的性能优化,以确保应用的流畅运行?请详细阐述优化思路及可能用到的技术手段。
13.1万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

优化思路

  1. 减少函数调用次数:将重复执行且结果不变的函数逻辑提取到更高层级作用域,避免在频繁调用的函数内重复计算。
  2. 简化函数体:拆分复杂函数为多个简单函数,每个函数职责单一,这样便于理解、维护与优化。
  3. 优化 DOM 操作:批量处理 DOM 操作,减少回流与重绘次数。
  4. 处理异步任务:合理安排异步任务,避免过多异步任务同时执行导致资源过度占用。

技术手段

  1. 函数防抖与节流
    • 防抖:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。适用于输入框实时搜索等场景,减少不必要的函数调用。
    function debounce(func, delay) {
        let timer;
        return function() {
            const context = this;
            const args = arguments;
            clearTimeout(timer);
            timer = setTimeout(() => {
                func.apply(context, args);
            }, delay);
        };
    }
    
    • 节流:规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。常用于滚动事件等场景。
    function throttle(func, delay) {
        let lastTime = 0;
        return function() {
            const context = this;
            const args = arguments;
            const now = new Date().getTime();
            if (now - lastTime >= delay) {
                func.apply(context, args);
                lastTime = now;
            }
        };
    }
    
  2. Web Workers:对于复杂的计算任务,将其放到 Web Workers 线程中执行,避免阻塞主线程,保证页面的流畅性。
// main.js
const worker = new Worker('worker.js');
worker.postMessage({ data: 'your data' });
worker.onmessage = function(event) {
    console.log('Received from worker:', event.data);
};

// worker.js
self.onmessage = function(event) {
    // 复杂计算
    const result = performComplexCalculation(event.data);
    self.postMessage(result);
};
function performComplexCalculation(data) {
    // 具体计算逻辑
    return data * 2;
}
  1. 虚拟 DOM:利用虚拟 DOM 库(如 React 中的虚拟 DOM 机制),通过对比虚拟 DOM 的差异,批量更新真实 DOM,减少直接操作真实 DOM 的频率。
  2. 异步加载与懒执行:对于非关键的函数或模块,采用异步加载和懒执行的方式,只有在需要时才加载和执行,提高页面初始加载性能。
// 异步加载模块
import('./expensiveModule.js').then(module => {
    module.doSomething();
});
  1. Memoization(记忆化):缓存函数的计算结果,当相同参数再次调用时,直接返回缓存结果,避免重复计算。
function memoize(func) {
    const cache = new Map();
    return function(...args) {
        const key = args.toString();
        if (cache.has(key)) {
            return cache.get(key);
        }
        const result = func.apply(this, args);
        cache.set(key, result);
        return result;
    };
}