JavaScript性能优化技术详解 ⚡
今天,让我们继续深入研究JavaScript的性能优化技术。掌握这些技术对于构建高性能的JavaScript应用至关重要。
性能优化基础概念 ????
???? 小知识:JavaScript性能优化涉及多个方面,包括代码执行效率、内存使用、DOM操作、网络请求等。通过合理的优化策略,可以显著提升应用的响应速度和用户体验。
性能分析工具实现 ????
// 1. 性能计时器
class PerformanceTimer {
constructor() {
this.marks = new Map();
this.measures = new Map();
}
mark(name) {
this.marks.set(name, performance.now());
}
measure(name, startMark, endMark) {
const startTime = this.marks.get(startMark);
const endTime = this.marks.get(endMark);
if (startTime && endTime) {
const duration = endTime - startTime;
this.measures.set(name, duration);
return duration;
}
return null;
}
getMeasure(name) {
return this.measures.get(name);
}
clearMarks() {
this.marks.clear();
}
clearMeasures() {
this.measures.clear();
}
}
// 2. 代码性能分析器
class CodeProfiler {
constructor() {
this.profiles = new Map();
}
startProfile(name) {
const startTime = performance.now();
const startMemory = performance.memory?.usedJSHeapSize;
this.profiles.set(name, {
startTime,
startMemory,
calls: 0,
totalTime: 0,
maxTime: 0
});
}
endProfile(name) {
const profile = this.profiles.get(name);
if (!profile) return;
const endTime = performance.now();
const endMemory = performance.memory?.usedJSHeapSize;
const duration = endTime - profile.startTime;
const memoryDiff = endMemory - profile.startMemory;
profile.calls++;
profile.totalTime += duration;
profile.maxTime = Math.max(profile.maxTime, duration);
profile.lastMemoryImpact = memoryDiff;
}
getProfile(name) {
const profile = this.profiles.get(name);
if (!profile) return null;
return {
...profile,
averageTime: profile.totalTime / profile.calls
};
}
getAllProfiles() {
const results = {};
for (const [name, profile] of this.profiles) {
results[name] = this.getProfile(name);
}
return results;
}
}
// 3. 函数执行时间分析装饰器
function profileExecution(target, propertyKey, descriptor) {
const originalMethod = descriptor.value;
const profiler = new CodeProfiler();
descriptor.value = function(...args) {
profiler.startProfile(propertyKey);
const result = originalMethod.apply(this, args);
profiler.endProfile(propertyKey);
console.log(`Function ${propertyKey} profile:`, profiler.getProfile(propertyKey));
return result;
};
return descriptor;
}
代码优化技术 ????
// 1. 循环优化
class LoopOptimizer {
// 优化数组遍历
static optimizedForEach(array, callback) {
const length = array.length;
for (let i = 0; i < length; i++) {
callback(array[i], i);
}
}
// 分块处理大数组
static *chunkedProcess(array, chunkSize = 1000) {
const length = array.length;
for (let i = 0; i < length; i += chunkSize) {
yield array.slice(i, Math.min(i + chunkSize, length));
}
}
// 使用Web Worker处理耗时操作
static createWorkerProcess(workerFunction) {
const blob = new Blob([`(${workerFunction.toString()})()`],
{ type: 'application/javascript' });
return new Worker(URL.createObjectURL(blob));
}
}
// 2. 函数优化
class FunctionOptimizer {
constructor() {
this.cache = new Map();
}
// 函数记忆化
memoize(fn) {
return (...args) => {
const key = JSON.stringify(args);
if (this.cache.has(key)) {
return this.cache.get(key);
}
const result = fn.apply(this, args);
this.cache.set(key, result);
return result;
};
}
// 函数防抖
debounce(fn, delay) {
let timeoutId;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn.apply(this, args), delay);
};
}
// 函数节流
throttle(fn, limit) {
let inThrottle;
return (...args) => {
if (!inThrottle) {
fn.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
}
// 3. DOM优化
class DOMOptimizer {
constructor() {
this.mutationObserver = null;
this.virtualDOM = new Map();
}
// 批量DOM更新
batchUpdate(updates) {
const fragment = document.createDocumentFragment();
updates.forEach(update => {
const element = this.createElement(update);
fragment.appendChild(element);
});
document.body.appendChild(fragment);
}
// 虚拟DOM实现
createElement(vnode) {
if (typeof vnode === 'string') {
return document.createTextNode(vnode);
}
const element = document.createElement(vnode.tag);
for (const [key, value] of Object.entries(vnode.props || {})) {
element.setAttribute(key, value);
}
(vnode.children || []).forEach(child => {
element.appendChild(this.createElement(child));
});
return element;
}
// DOM变更监控
observeChanges(target, callback) {
this.mutationObserver = new MutationObserver(callback);
this.mutationObserver.observe(target, {
childList: true,
subtree: true,
attributes: true
});
}
}
高级优化模式 ????
// 1. 虚拟滚动实现
class VirtualScroller {
constructor(container, items, itemHeight) {
this.container = container;
this.items = items;
this.itemHeight = itemHeight;
this.visibleItems = new Map();
this.scrollTop = 0;
this.container.style.overflow = 'auto';
this.container.style.position = 'relative';
this.init();
}
init() {
// 设置容器高度
this.container.style.height = `${this.items.length * this.itemHeight}px`;
// 监听滚动事件
this.container.addEventListener('scroll', this.onScroll.bind(this));
// 初始渲染
this.render();
}
onScroll() {
this.scrollTop = this.container.scrollTop;
this.render();
}
render() {
const startIndex = Math.floor(this.scrollTop / this.itemHeight);
const endIndex = Math.min(
startIndex + Math.ceil(this.container.clientHeight / this.itemHeight),
this.items.length
);
// 移除不可见项
for (const [index, element] of this.visibleItems) {
if (index < startIndex || index >= endIndex) {
element.remove();
this.visibleItems.delete(index);
}
}
// 添加可见项
for (let i = startIndex; i < endIndex; i++) {
if (!this.visibleItems.has(i)) {
const element = this.createItem(i);
this.container.appendChild(element);
this.visibleItems.set(i, element);
}
}
}
createItem(index) {
const element = document.createElement('div');
element.style.position = 'absolute';
element.style.top = `${index * this.itemHeight}px`;
element.style.height = `${this.itemHeight}px`;
element.textContent = this.items[index];
return element;
}
}
// 2. 资源预加载器
class ResourcePreloader {
constructor() {
this.cache = new Map();
this.loading = new Set();
}
preload(resources) {
resources.forEach(resource => {
if (!this.cache.has(resource) && !this.loading.has(resource)) {
this.loading.add(resource);
const promise = this.loadResource(resource)
.then(result => {
this.cache.set(resource, result);
this.loading.delete(resource);
})
.catch(error => {
console.error(`Failed to preload ${resource}:`, error);
this.loading.delete(resource);
});
return promise;
}
});
}
loadResource(resource) {
if (resource.endsWith('.js')) {
return this.loadScript(resource);
} else if (resource.endsWith('.css')) {
return this.loadStyle(resource);
} else if (/\.(png|jpg|gif|svg)$/.test(resource)) {
return this.loadImage(resource);
}
return Promise.reject(new Error('Unsupported resource type'));
}
loadScript(url) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = url;
script.onload = () => resolve(script);
script.onerror = reject;
document.head.appendChild(script);
});
}
loadStyle(url) {
return new Promise((resolve, reject