Attack Time: Why Ten Milliseconds Is the Difference Between a Note and a Click
Short answer: A sound that goes from silence to full volume in no time at all makes a click. Bring the volume up over about ten milliseconds and the click is gone. It still sounds instant.
const g = gainNode.gain;
const now = audioCtx.currentTime;
g.setValueAtTime(0, now);
g.linearRampToValueAtTime(level, now + 0.01); // about ten milliseconds
How I found it
The short sounds in my Space world had a nasty tick at the front. I assumed the sounds themselves were too harsh and spent a long time changing them. The tick stayed.
The cause was one line. Each sound was switched on by setting its volume directly, which jumps to the new value at once. The sound was fine. The way it was turned on was the problem.
Why a jump is a click
Think of a light switch and a dimmer. The dimmer brings the light up smoothly. The switch snaps.
A speaker can't snap silently. When the signal jumps from nothing to full in an instant, that sharp edge is itself a sound: a tiny burst of every pitch at once. You hear it as a tick sitting on top of the note. It happens whatever the note is, because it comes from the shape of the volume and has nothing to do with what is being played.
How long is long enough
A few milliseconds already helps. Around ten is safe. That is far too short to hear as a fade, so a drum hit shaped this way still feels like a hit.
Go much longer and the character changes. At a tenth of a second the note starts to swell in, which is a different effect. I ran into that one too, in Why a Fifth Plus a Soft Onset Is Always a Singing Bowl.
The end of the note clicks too
Cutting a sound off at full volume makes the same click in reverse. Fade it out before you stop it. The details are in exponentialRampToValueAtTime Cannot Reach Zero.
What "attack" means on a synthesiser
It is this. The attack control sets how long a note takes to reach full volume. Tutorials present it as a matter of taste, fast for punchy and slow for dreamy. At the very short end it is also what keeps a note from clicking.
Try it: every sound in Ocean starts with a short ramp like this. It is free and starts in one click, with no account.
Open Ocean, free