jQuery Best Practices
jQuery code ages well when it follows a few habits. These practices keep pages fast, code readable and future migrations to plain JavaScript easy.
On this page · 5 min · Advanced
On this page
- Learning objectives
- Explanation
- Code example
- Step by step
- Real-world use
- Common mistakes
- Best practices
- Remember this
- Practice exercise
- Mini quiz
- Related topics
- My notes
- Reading time
- 5 min
- Difficulty
- Advanced
- Updated
- Oct 28, 2026
Related tutorials
Learning objectives#
- Write fast selections and DOM updates
- Organise code into modules without globals
- Handle events and AJAX robustly
- Decide between jQuery and native APIs
Explanation#
Cache and scope: const $list = $("#list"); then $list.find(".item") — fewer DOM searches, clearer code.
Batch DOM work: build elements (or an array of them) and append once, instead of appending inside a loop.
Delegate events from stable containers, and namespace them (click.cart) so you can remove only your own.
Avoid globals: wrap page code in a module (an IIFE or ES module) and expose one small object if needed.
Security: .text() for user data, anti-forgery tokens on POST, never eval server responses.
Know the native equivalents (querySelectorAll, classList, fetch, addEventListener). In new code, a few lines of plain JavaScript usually beat adding a 30 KB library.
Code example: Before and after: the same feature, done well#
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<div id="app" style="font-family:sans-serif"><button class="load">Load products</button><ul class="list"></ul></div>
<script>
// ✓ One module, no globals, cached and scoped selections, batched DOM updates
const ProductList = (function ($) {
const products = [{ name: 'Pen', price: 20 }, { name: 'Notebook', price: 60 }, { name: '<script>alert(1)<\/script>', price: 1 }];
function render($root) {
const $items = products.map(p => $('<li>').text(p.name + ' — ₹' + p.price)); // .text() = safe
$root.find('.list').empty().append($items); // one DOM update
}
function init(selector) {
const $root = $(selector); // cached
$root.off('.products').on('click.products', '.load', () => { // namespaced + delegated
render($root);
console.log('Rendered', $root.find('.list li').length, 'items');
});
}
return { init };
})(jQuery);
$(function () { ProductList.init('#app'); });
</script>
Clicking “Load products” renders three items in one DOM update and logs “Rendered 3 items”. The third product’s name containing a script tag is shown as plain text, not executed. No global variables except ProductList are created.
Step-by-step explanation#
- The IIFE keeps products and helpers private; only ProductList.init is public.
- $root is selected once and all other lookups are scoped to it.
- All list items are built in an array and appended in a single call.
- The click handler is namespaced (.products) and delegated, so init can be called again safely.
- .text() neutralises the malicious product name.
Real-world use case#
A team modernising a legacy site first refactors its jQuery into modules following these rules. Later, swapping jQuery calls for native ones module by module becomes straightforward.
Common mistakes#
$(".total") inside a loop of 1,000 rows searches the DOM 1,000 times. Select once outside.
Hundreds of lines in one ready callback become unmaintainable. Split into named modules and functions.
Native APIs now cover selection, classes, events and fetch. Add jQuery only when you need its plugins or are in a jQuery codebase.
Best practices#
- Cache and scope selections
- Append once per batch
- Delegate and namespace events
- Modules instead of globals; .text() for user data
Remember this#
Select once, reuse $variables.
Build, then append once.
New project? Try native JS first.
Practice exercise#
Your task: Refactor: for (let i = 0; i < 100; i++) { $("#list").append("<li>" + i + "</li>"); } so it touches the DOM only once.
Need a hint?
Show solution
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<ul id="list"></ul>
<script>
$(function () {
const items = [];
for (let i = 0; i < 100; i++) items.push($('<li>').text(i));
$('#list').append(items);
console.log($('#list li').length); // 100
});
</script>
Mini quiz#
Which is faster for adding 500 rows?
Want more? Practise all jQuery MCQs · jQuery interview questions
My notes#
Saved in this browser.