Blixtrande domänförslag: Så bygger du snabb autocomplete
Hemligheten bakom snabb autocomplete: Så byggde vi sökning för 240 miljoner domäner
Har du någonsin märkt hur sökförslagen dyker upp innan du ens slutfört tangenttryckningen? Det är ingen magi – det är ren ingenjörskonst. Och det är ett fascinerande problem när du jobbar med 240 miljoner domännamn.
Varför hastighet är avgörande
När användare skriver i en sökruta förväntar de sig omedelbara resultat. Forskning från Nielsen Norman Group visar att 0,1 sekunder är gränsen för att en åtgärd ska kännas ögonblicklig. Allt långsammare än så får gränssnittet att kännas trögt och bryter användarens tankeflod.
För ett verktyg som Wirewiki är autocomplete den primära startpunkten. Varje millisekund spelar roll när du vill slå upp DNS-poster snabbt. Användaren ska känna att verktyget läser tankarna – inte väntar på en server.
Tricksen som gör det möjligt
Det geniala här handlar egentligen inte om att göra API:t snabbare (även om det hjälper). Det handlar om att stjäla tid från inmatningsprocessen själv.
När användaren trycker ner en tangent (keyDown) börjar systemet hämta förslag för det som skrivs plus nästa troliga tecken. När tangenten släpps (keyUp) renderas det som redan finns tillgängligt. Det betyder att din tidsbudget inte längre är API-fördröjningen – utan varaktigheten av två tangenttryckningar plus gapet mellan dem.
På en 60Hz-skärm har du 16,7 millisekunder per bildruta. För snabba skribenter på p99-nivå landar budgeten på ungefär 121 millisekunder. Det är ditt fönster. Se till att resultaten är klara innan andra tangenttryckningen är klar, och för användaren känns allt ögonblickligt.
Arkitektur för hastighet i stor skala
API:t måste hantera 240 miljoner domännamn utan att svettas. Lösningen är att behandla populära domäner annorlunda än den långa svansen:
Toppen: Populära domäner bor i en trie-struktur i minnet. Prefix-sökningar är enkla pekargångar – snabba och förutsägbara. De åtta bästa förslagen för varje möjligt prefix är förberäknade. värsta fall? O(längd på inmatning). Det är minimalt.
Svansen: Allt annat ligger på SSD med ett minnesmappat blockindex. Domänerna är sorterade, deltakomprimerade och organiserade i fast storlek med en liten minnesbaserad katalog för binärsökning. De 240 miljonerna domäner tar cirka 2,5 GB, och operativsystemet sköter cachning av varma sidor automatiskt.
Båda strukturerna har begränsade indata – antalet domäner och frågelängden växer inte obegränsat. Det gör den effektiva komplexiteten praktiskt taget O(1), vilket håller p99-latensen konstant låg.
Siffrorna talar för sig
Belastningstester avslöjade intressanta resultat. API:t självt svarar på de flesta förfrågningar på under 2 millisekunder. Även under belastning med 1 600 förfrågningar per sekund svarar Nginx plus API på 15 millisekunder vid p99. Riktigt stabilt.
Men här kliver verkligheten in: nätverket. I praktiken är end-to-end-latensen lika med round-trip-tiden från webbläsare genom Cloudflare till din server, plus cirka 10 ms overhead. För användare i samma region som servern ligger du inom budget. För alla andra? Där kommer asterisken in i bilden.
Asterisken
p99 0ms* betyder att 99% av förfrågningarna returnerar resultat innan användaren hinner slutföra tangenttryckningen – förutsatt att de befinner sig nära servern. Lägg till 100–200 ms transatlantisk fördröjning, och plötsligt är du över budget.
Lösningen vore geografiskt distribuerade servrar med lastbalansering. Men för ett sidoprojekt är det mycket infrastruktur att underhålla. Ibland är "tilräckligt bra" verkligen tillräckligt – särskilt när dina målanvändare är europeiska utvecklare som kontrollerar domäner.
Vad detta betyder för ditt nästa projekt
Lektionen här gäller långt bortom domänuppslag: förhäämta intelligent. Om du vet vad användarna kan fråga efter härnäst, hämta det innan de frågar. Låt gränssnittet reagera på det som är klart snarare än att vänta på fullständig säkerhet.
Den andra läxan handlar om datastrukturval. En trie för het data, en välindexerad sorterad struktur för allt annat. Du behöver inte hålla 240 miljoner poster i RAM om du designar åtkomstmönstren kring det som faktiskt kommer att efterfrågas.
Slutligen: mät din faktiska budget. I det här fallet två tangenttryckningar plus mellanrum. Vad är din motsvarighet? Hitta den, optimera mot den, och sluta optimera bortom den.
Resultatet känns som magi. Men det börjar med att förstå exakt hur mycket tid du faktiskt har.