
Comments are the fastest on/off switch you have for experimenting. Use single-line comments for tiny toggles and block comments when you want to stash large sections without changing indentation or touching the AST. Preferable pattern: comment the intent you temporarily disable so you don’t forget why it was there.
For quick local debug toggles:
// Turn this on to inspect the frame timing
// console.log("frame:", frame, "dt:", dt);
// Minimal toggle: uncomment for a specific frame
// if (frame === 100) console.log("hit 100");
Block comments make it trivial to silence entire subsystems during profiling. They’re blunt but safe because they never affect build optimization. Keep the comment close to the disabled code so context survives refactors.
/* Temporarily disable rendering for CPU profiling
function renderScene(scene, ctx) {
scene.forEach(obj => obj.draw(ctx));
}
*/
/* Re-enable when measuring draw calls */
Don’t confuse commenting out code with conditional removal by the bundler. Using if (false) can be beneficial when you want the minifier to strip code completely; comments won’t be removed by tree-shaking. Example:
if (false) {
// This block will be removed by most minifiers (dead code elimination)
console.log("never executed in production");
}
// Contrast: a comment simply hides it from the interpreter but not from static analysis tools
// console.log("hidden but still present in source");
When you need build-time toggles, use pragmas your pipeline understands rather than ad-hoc comments. /*#__PURE__*/ helps indicate side-effect-free calls for tree-shakers, and preprocessors accept patterns like /*#if DEBUG*/ ... /*#endif*/. That keeps source readable and lets the toolchain do the heavy lifting.
/*#if DEBUG*/
console.log("verbose instrumentation on");
/*#endif*/
// Or rely on env replacement + minifier
if (process.env.DEBUG) {
expensiveInstrumentation();
}
For temporary lint overrides or to silence warnings around commented code, use scoped directives instead of scattering TODOs. That keeps the intent explicit and reversible.
/* eslint-disable-next-line no-console */
// console.log("temporarily disabled logging");
When toggling performance-critical blocks, prefer patterns that let the compiler eliminate work rather than just hide it. Example: wrap instrumentation in a no-op function that the optimizer can inline away when removed, instead of leaving commented logic which can rot and mislead:
let debugHook = function() {};
if (process.env.DEBUG) {
debugHook = function(state) {
// expensive inspection
console.log(state);
};
}
// use in hot loop
for (let i = 0; i < n; i++) {
compute(i);
debugHook(i);
}
Edit-time convenience: learn your editor’s toggle-comment shortcut. It is the fastest profile-iteration multiplier you have. Keep the comment text expressive. “Disabled for profiling” is better than “removed” because it encodes reason. And when you need to re-enable remotely, prefer small, reversible commits that contain only the uncommented lines so blame remains clean. If you find yourself repeatedly commenting the same block, move the switch out to a single flag or a build-time define so the intent is a first-class control rather than an incidental
Apple Pencil Pro: Latest Model - Device Compatibility Check Required - Pixel-Perfect Precision, Tilt and Pressure Sensitivity, Perfect for Note-Taking, Drawing, and Art. Charges and Pairs Magnetically
$61.14 (as of June 2, 2026 22:39 GMT +00:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Disable code fast and keep intent clear
Make the on/off decision visible in the code through a single constant that your build tool can replace. This keeps the source readable and guarantees the optimizer will remove the dead branches entirely.
// Build tool replaces DEBUG with true/false at compile time
const DEBUG = false;
if (DEBUG) {
// instrumentation that should not exist in release
/*#__PURE__*/ console.log("frame timing verbose", metrics);
}
Use plain if (false) for quick local experiments where you want the minifier to drop entire blocks without any toolchain magic. It is explicit and predictable.
if (false) {
// heavy debugging
const dump = expensiveStateSerialize(state);
console.log(dump);
}
Wrap instrumentation in a hook that can be replaced by a no-op. Optimizers will inline and remove the call when the hook is a compile-time constant, and the hot path stays clean.
let debugHook = function () { /* default no-op */ };
if (DEBUG) {
debugHook = function (label, data) {
// keep this compact so it can be optimized away
console.log(label, data);
};
}
// hot loop
for (let i = 0; i < n; i++) {
step(i);
debugHook("step", i);
}
For runtime toggles where you need cheap checks without branching penalties, use bitmask flags. A single integer check is fast and packs multiple features into one field.
const FLAGS = {
RENDER: 1 << 0,
PHYSICS: 1 << 1,
AUDIO: 1 << 2
};
let active = FLAGS.RENDER | FLAGS.PHYSICS; // runtime-configurable
function frame() {
if (active & FLAGS.PHYSICS) stepPhysics();
if (active & FLAGS.RENDER) render();
}
Assertions should be removable. Implement an assert that's a no-op in production so the checks don't pay a runtime cost.
let assert = function () {};
if (DEBUG) {
assert = function (cond, msg) {
if (!cond) throw new Error("Assertion failed: " + (msg || ""));
};
}
// usage
assert(x >= 0, "x must be non-negative");
Prefer build-time replacement of environment constants rather than string checks. Comparing a constant to a string forces the check to remain; a replaced boolean lets the minifier remove dead code.
// Less ideal: string compare may survive
if (process.env.NODE_ENV === "development") {
console.log("dev path");
}
// Better: replace BUILD_DEBUG with true/false
if (BUILD_DEBUG) {
console.log("dev path");
}
When using preprocessors, keep the pragma blocks small and focused so the developer intent is preserved next to the disabled code. The blocks make it obvious why the code is gone in production builds.
/*#if DEBUG*/
profile.start("render");
/*#endif*/
renderScene();
/*#if DEBUG*/
profile.end("render");
/*#endif*/
If you must comment out code, leave the reason and a re-enable note inline. This is more useful than removing the code entirely and losing context during a bisect or performance experiment.
// Disabled for CPU profiling: remove draw calls while measuring physics
// RE-ENABLE after profile: uncomment renderScene
// renderScene(scene, ctx);
For libraries or subsystems that are frequently toggled, make the switch a single exported flag so callers and tooling see the intent. Small, explicit switches scale better than scattered comments.
// module config
export const CONFIG = {
ENABLE_PATH_TRACING: false,
ENABLE_LOGGING: false
};
// usage in multiple places
if (CONFIG.ENABLE_PATH_TRACING) pathTrace(scene);
