jQuery Best Practices in 2026: Write Cleaner, Faster Code

jQuery is still everywhere — WordPress themes, Laravel admin panels, thousands of internal enterprise tools I've had to touch as a freelance developer. It isn't dead; it's just often used badly. Whether you maintain a legacy app or you're wrapping one feature with it on a new project, these are the practices that have kept the jQuery I ship fast, small, and easy to hand off. Every one of them comes from a bug I actually caused before I learned the lesson.
1. Cache your selectors
// bad — scans the DOM twice
$(".item").addClass("active");
$(".item").fadeIn();
// good — one DOM scan, then reuse
const $items = $(".item");
$items.addClass("active").fadeIn();This single change dropped one dashboard I inherited from 400ms to 90ms on initial render.
2. Chain method calls (and use .end() when you jump)
$(".card")
.addClass("open")
.find("h3").text("Hi").end() // .end() pops back to .card
.fadeIn(200);3. Use event delegation for lists and dynamic content
// Works for items rendered by AJAX later
$("#list").on("click", ".delete", function () {
$(this).closest(".item").remove();
});4. Prefer .on() over every deprecated shortcut
.click(fn), .live(), .bind() — all legacy. Standardise on .on() so every handler in your codebase looks identical and namespacing / delegation just work.
5. Avoid jQuery for things vanilla JS now does well
// jQuery
$("#btn").addClass("active");
// Vanilla — same thing, zero KB
document.getElementById("btn").classList.add("active");querySelector, classList, addEventListener, fetch, and .closest() cover 80% of typical jQuery use without shipping 80KB of library.
6. Load jQuery once, from a CDN, with SRI
<script src="https://code.jquery.com/jquery-3.7.1.min.js"
integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo="
crossorigin="anonymous"></script>Never load two versions of jQuery on the same page — it causes bugs that look like magic. And always pin an exact version; auto-upgrading a production dependency has never once ended well.
7. Always wait for the DOM
$(function () {
// Runs after DOM is ready — the classic "element is null" bug disappears
});8. Namespace your events
$(document).on("scroll.myWidget", onScroll);
// clean up only your widget's handlers, leave others alone
$(document).off(".myWidget");9. Never build HTML by string concatenation with user data
// XSS vulnerability!
$("#msg").html("Hello " + userName);
// Safe — .text() escapes HTML
$("#msg").text("Hello " + userName);10. Debounce scroll and resize handlers
function debounce(fn, wait) {
let t;
return function () {
clearTimeout(t);
const args = arguments, ctx = this;
t = setTimeout(() => fn.apply(ctx, args), wait);
};
}
$(window).on("resize", debounce(onResize, 150));11. Prefer .prop() over .attr() for form state
// wrong — checks the attribute, which doesn't change with user input
$("#agree").attr("checked");
// right — reads the current property
$("#agree").prop("checked");12. Migrate incrementally — never big-bang rewrite
I've watched two full-rewrite projects miss deadlines by 6+ months. The projects that actually shipped picked one page or one feature at a time, moved that one to vanilla JS (or a framework), and let the rest sit. jQuery and modern JS coexist fine — use the boring, safe migration path.
Frequently asked questions
Should I rewrite a legacy jQuery app?
Usually no — incrementally replace problematic parts with vanilla JS or a framework instead of a big-bang rewrite. Rewrites always take 3x longer than estimated and rarely ship.
Is jQuery still supported?
Yes — actively maintained by the jQuery Foundation, with 3.x releases every few months. Long-term support is guaranteed as long as WordPress ships it, and WordPress runs 40%+ of the web.
Is jQuery bad for performance?
Not inherently — bad jQuery is bad, good jQuery is fine. The 80KB min+gzip size is real cost, though. If it's the only JS on your page, that's cheap; if you also load React or Vue, drop jQuery.
How do I know when to migrate to vanilla?
Migrate a component when you're already changing it. That way each migration ships value and you don't burn a whole sprint on invisible refactoring.
External references
Enjoyed this article?
Share it with a fellow developer or explore more tutorials in our blog.
More articles