jQuery 性能优化

jQuery 常用的性能优化技巧和最佳实践

问题

针对 jQuery 的优化方法有哪些?

解答

1. 选择器优化

// ❌ 慢:通用选择器
$('.container *');

// ✅ 快:具体选择器
$('.container p');

// ❌ 慢:类选择器前加标签
$('div.header');

// ✅ 快:直接用类选择器
$('.header');

// ❌ 慢:层级过深
$('.container .wrapper .list .item a');

// ✅ 快:减少层级或用 find()
$('.list').find('.item a');

2. 缓存 jQuery 对象

// ❌ 差:重复查询 DOM
$('.btn').addClass('active');
$('.btn').on('click', handler);
$('.btn').attr('disabled', true);

// ✅ 好:缓存后复用
const $btn = $('.btn');
$btn.addClass('active');
$btn.on('click', handler);
$btn.attr('disabled', true);

// ✅ 更好:链式调用
$('.btn')
  .addClass('active')
  .on('click', handler)
  .attr('disabled', true);

3. 事件委托

// ❌ 差:给每个元素绑定事件
$('.list li').on('click', function() {
  $(this).toggleClass('selected');
});

// ✅ 好:事件委托到父元素
$('.list').on('click', 'li', function() {
  $(this).toggleClass('selected');
});

4. 批量 DOM 操作

// ❌ 差:循环中多次操作 DOM
const $list = $('.list');
for (let i = 0; i < 100; i++) {
  $list.append(`<li>Item ${i}</li>`);
}

// ✅ 好:拼接后一次插入
const $list = $('.list');
let html = '';
for (let i = 0; i < 100; i++) {
  html += `<li>Item ${i}</li>`;
}
$list.append(html);

// ✅ 或使用文档片段
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
  const li = document.createElement('li');
  li.textContent = `Item ${i}`;
  fragment.appendChild(li);
}
$('.list').append(fragment);

5. 使用原生方法

// ❌ 慢:jQuery 方法
$('#app').each(function() {
  const id = $(this).attr('id');
});

// ✅ 快:原生属性
$('#app').each(function() {
  const id = this.id;
});

// 常用原生属性替代
// $(this).attr('id')     -> this.id
// $(this).attr('class')  -> this.className
// $(this).attr('href')   -> this.href
// $(this).html()         -> this.innerHTML
// $(this).val()          -> this.value

6. 减少 DOM 操作次数

// ❌ 差:多次修改样式触发多次重排
$el.css('width', '100px');
$el.css('height', '100px');
$el.css('margin', '10px');

// ✅ 好:一次性修改
$el.css({
  width: '100px',
  height: '100px',
  margin: '10px'
});

// ✅ 或使用 class
$el.addClass('box-style');

7. 使用 ID 选择器

// ❌ 慢:复杂选择器
$('.container #header');

// ✅ 快:ID 选择器直接查找
$('#header');

// ID 选择器内部调用 getElementById,最快

8. 限定选择器作用域

// ❌ 慢:全局查找
$('.item');

// ✅ 快:限定范围
const $container = $('#container');
$container.find('.item');

// 或使用上下文参数
$('.item', '#container');

关键点

  • 缓存选择器:避免重复查询 DOM,用变量存储 jQuery 对象
  • 事件委托:用 on(event, selector, handler) 代替给每个元素绑定事件
  • 批量操作:拼接 HTML 字符串后一次性插入,减少 DOM 操作次数
  • 选择器效率:ID > class > 标签 > 属性/伪类,避免过度嵌套
  • 用原生属性this.idthis.value 比 jQuery 方法更快