Case study · käyttöliittymäsuunnittelu ja toteutus

PARKSIDE-käyttöohjeetKatalogi, jota ei ollut olemassa

Lidlin PARKSIDE-työkaluista ei ole julkista luetteloa. Manuaalin löytää vain, jos tietää tuotenumeronsa etukäteen. Rakensin puuttuvan katalogin — ja sen käyttöliittymän: 10 257 listausta kolmelta markkinalta, rikastettuna niillä tiedoilla joita omistaja oikeasti kysyy. Yksi staattinen sivu, ei kehystä, ei käännösvaihetta.

Rooli suunnittelu + toteutus Kesto 12 päivää, 81 committia Pino HTML · CSS · vanilla JS · Python Julkaisu staattinen, 139 MB
10 257listausta
3 markkinaa
2 935erillistä
tuotetta
62 kBsivun koko
17 kB pakattuna
44 msDOMContentLoaded
0riippuvuutta
ei build-vaihetta
2 001käsin tehtyä
korjausta
1Ongelma

≤ 3tulosta kyselyä kohden. Ei sivutusta, ei listausta, ei hakuparametreja.

Rajapinta, jota ei voi selata

Lidlin manuaalihaku palauttaa enintään kolme tulosta kyselyä kohden, jättää huomiotta jokaisen sivutusparametrin eikä tarjoa listausreittiä lainkaan.

Tämä on suunnittelun kannalta ratkaiseva yksityiskohta. Rajapinta olettaa, että käyttäjä tietää jo mitä etsii: syötä tuotenumero, saat manuaalisi. Kaikki muut kysymykset — mitä tuotteita on olemassa, mikä näistä on uusin, mikä akku tähän käy — ovat rakenteellisesti vastaamattomia, koska mitään selattavaa pintaa ei ole.

Käyttöliittymän tehtävä ei siis ollut nopeuttaa hakua. Se oli tehdä olemassaolo näkyväksi. Kaikki myöhemmät päätökset seuraavat tästä.

LIDLIN RAJAPINTA IAN 313266 3 osumaa · loput 10 254 näkymättömissä SELATTAVA ARKISTO
KUVA 1Sama data, kaksi pintaa. Rajapinta vastaa vain kysymykseen jonka vastaus on jo tiedossa; arkisto vastaa siihen mitä ei osattu kysyä.

Kenelle

Käyttäjä on työkalun omistaja tai sitä harkitseva — käytännössä kuka tahansa 20 V akkuekosysteemissä, joka yrittää selvittää mikä sopii mihin. Kolme kysymystä toistuvat:

  • Mikä akku tähän käy? Alusta ei lue tuotteen nimestä, ja 40 V ei ole oma alustansa vaan kaksi 20 V kennostoa.
  • Onko tämä uudempi kuin minun? Revisio (A1 → B2 → C4) kertoo sen, mutta vain saman mallin sisällä.
  • Mitä laatikossa on? Nimi ei kerro: “Akkuiskuporakone­sarja” ei paljasta sisältyykö akku ja laturi.

Sivun tehtävä ei ole hakeminen. Sen tehtävä on tehdä olemassaolo näkyväksi.

2Tietomalli

Kolme identiteettiäja oikea niistä riippuu kysymyksestä.

Mikä on yksi rivi ruudulla?

Ennen kuin ruudukkoa voi piirtää, on päätettävä mitä yksi kortti tarkoittaa. Datassa on kolme eri identiteettiä, ja ne eroavat kertaluokan verran.

YksikköMääräMitä se onVastaa kysymykseen
Listaus10 257Yksi tuote yhdellä markkinallaMyydäänkö tätä Suomessa?
Tuotenumero4 806IAN — yksi pakkausMikä manuaali minun laatikkooni kuuluu?
Tuote2 935Malli + revisioMitä työkaluja on olemassa?

Sama akku esiintyy 29 eri tuotenumerolla — paljaana, laturin kanssa, osana sarjaa — ja jokaisella markkinalla on oma listauksensa. Jos kortti olisi listaus, sama työkalu täyttäisi ruudun kolmesti. Jos kortti olisi tuotenumero, akkua olisi 29 kappaletta.

Kortti on tuote. Se yhdistää kaksi eri päällekkäisyyttä kerralla, ja koska yhdistäminen on väite, korttiin kuuluu myös se mitä väite ei sano.

20 V AKKU 3 IAN A1 B2 C3 D4 E6 I9 FI · PDF EN · PDF Käyttövoima luetaan manuaalista, ei nimestä. Yksi luokka 14:stä · todisteet jäävät talteen “3 IAN” = sama malli ja revisio. Ei “identtinen”: manuaalit eroavat satoja sivuja Nimi luettuna manuaalin kannesta. 6 781 nimeä korvattu katalogin lyhenteen tilalta Katalogin alkuperäinen nimi jää hoverille. Korjaus ei saa hävittää sitä mitä lähde sanoi Revisiolinja: katkoviiva = ei tällä markkinalla. Piilottaminen näyttäisi kattavuudelta — aukko on tieto Painike per kieli, vain jos useampi on näkyvissä. Sama tuote, eri manuaali
KUVA 2Kortin anatomia. Jokainen elementti vastaa yhteen kysymykseen listasta yllä; mikään ei ole koristetta.

Ryhmittely ei ole puhdas sääntö. Mallikoodi ratkaisee valtaosan, mutta viisi poikkeusta on kirjattu käsin: kaksi listausta yhdistetty vaikka mikään koodi ei liitä niitä, yhdeksän pidetty erillään vaikka koodi on sama (PARS 4 A1 on sekä auton puhdistussetti että 4 V ruuvinväännin), lisävarusteita omille korteilleen, monen työkalun sarjat avattuina työkaluikseen, ja malli tunnistettuna yli markkinarajojen. Lyhyesti: tuote on malli ja revisio, paitsi silloin kun ihminen on sanonut toisin.

Kaksi lukua, jotka vastaavat eri kysymykseen

Arkistossa on 2 935 tuotetta, mutta ruudukko piirtää 2 932 korttia. Ero on 24 tuotenumeroa, joiden PDF on kadonnut lähteestä: ne ovat yhä rekisterissä, mutta piilossa oman suodattimensa takana kunnes niitä pyydetään. Kumpikin luku on oikein — “mitä arkisto sisältää” ja “mitä ruudulla on” eivät ole sama kysymys, eikä niitä pidä esittää samana lukuna.

Merkinnän tarkkuus on suunnittelutyötä

Merkki lukee “3 IAN” ja avautuu muotoon sama malli ja revisio — ei “sama tuote”. Ero ei ole pilkunviilausta: näiden kolmen listauksen manuaalit eroavat toisistaan satoja sivuja, ja yksi PAP 20 B1 -akun 29 tuotenumerosta on todellisuudessa akku + laturi -paketti. Käyttöliittymä saa väittää vain sen minkä data kantaa.

3Rautalanka

760 / 600 / 420 pxKolme katkaisukohtaa. Jokainen korjaa vian, ei kiillota.

Layout

Yksi näkymä, ei reittejä. Suodattimet ylhäällä pysyvinä riveinä, ruudukko alla — koska kysymys “mitä on olemassa” vaatii, että vaihtoehdot ovat näkyvissä samaan aikaan tuloksen kanssa.

LOGO FI EN TEEMA SARJA KÄYTTÖVOIMA MARKKINA PAKKAUS NÄYTÄ 20 V akku 1926 verkko 3205 kaasu 0 Hae nimestä, mallista tai tuotenumerosta… Uusin ensin 2 932 tuotetta seuraava erä täyttyy vieritettäessä
KUVA 3Työpöytä. Suodatinrivit ovat kaksisarakkeinen ruudukko: nimiö 96 px:n sarakkeessa, sirut viereisessä. Sarakeleveys on määrätty pisimmästä suomenkielisestä nimiöstä, ei englannista.
390 px · SUODATTIMET KIINNI Suodattimet 3 Hae… 390 px · SUODATTIMET AUKI Suodattimet KÄYTTÖVOIMAMARKKINAPAKKAUS Nimiö siirtyy sirujen yläpuolelle. .facet-chips tarvitsee min-width: 0 — muuten nowrap-sirut leventävät sarakkeen yli 1fr:n ja sivu vierii sivusuunnassa Otsake muuttuu staattiseksi alle 760 px. Tarttuvana se peitti 750 px 813 px:n ruudusta Laskuri painikkeessa on pakollinen. Suodatettu näkymä ei saa näyttää samalta kuin suodattamaton, kun rivit ovat piilossa Testaus vaatii iframen. Headless Chrome kiinnittää asetteluikkunan 500 px:iin, joten --window-size=390 renderöi 500 px:n asettelun ja rajaa sen — näyttää täsmälleen ylivuotovialta
KUVA 4Kapea näyttö. Suodatinrivit olivat 868 px korkeat 390 px:n ruudulla — enemmän kuin koko näyttö. Ne taittuvat painikkeen taakse, mutta painike kantaa valintojen määrän.
4Päätökset

Jokainen päätöskertoo myös mikä vaihtoehto hylättiin ja mitä valinta maksoi.

Yhdeksän päätöstä

Suunnittelupäätös ilman hylättyä vaihtoehtoa on mielipide. Nämä on kirjattu niin, että myöhempi minä — tai kuka tahansa muu — näkee mitä mitattiin ennen kuin valittiin.

Ei kehystä

Arkkitehtuuri

Yksi HTML-tiedosto, joka lukee yhden JSON-tiedoston. Ei Reactia, ei Nextiä, ei Tailwindia, ei käännösvaihetta.

ValittuSivu on 62 kB (17 kB pakattuna), DOMContentLoaded 44 ms, ja koko arkiston 2 932 korttia maalautuu ilman että ruudukko lukitsee pääsäikeen.
HylättyReact + ReactDOM ovat yksinään ~45 kB pakattuna — noin kolme kertaa koko nykyinen sivu. Mikään sen tarjoama (SSR, reititys, API-reitit) ei koske yhtä sivua joka lukee yhden JSONin.
HylättyTailwindin CDN-versio on ~90 kB ja kääntää selaimessa; CLI toisi Node-työkaluketjun projektiin jossa työnkulku on “muokkaa tiedostoa, lataa välilehti uudelleen”.
HintaAinoa todellinen puute oli, ettei URL tunnistanut tuotetta. Se on ~20 riviä location.hash-käsittelyä, ei kehys.

Kortti on tuote, ei manuaali

Tietomalli

Yksi kortti = yksi malli + yksi revisio. Kortti yhdistää sekä markkinoiden että tuotenumeroiden päällekkäisyyden.

ValittuKieli­kohtaiset manuaalit tulevat korttiin painikkeina; useampi tuotenumero tiivistyy “N IAN” -merkiksi, jonka klikkaus listaa numerot hakukenttään vertailtavaksi.
HylättyKortti per listaus: sama työkalu täyttäisi ruudun kolmesti. Kortti per tuotenumero: yksi akku esiintyisi 29 kertaa.
HintaSama mallikoodi ei aina ole sama tuote — koodi voidaan käyttää uudelleen. Siksi “ei tämä tuote” erottaa listauksen omaksi kortikseen, peruutettavasti.

Revisioita ei yhdistetä oletuksena

Tietomalli

Malli PABS 20-Li kulkee revisiosta A1 (2015) revisioon I9 (2025). Jokainen on oma korttinsa.

ValittuKortti näyttää mallinsa revisiolinjan, ja markkinalta puuttuvat revisiot piirretään katkoviivalla, ei piiloteta. Suomi otti tuosta koneesta A1, C3, D5, E6, G8 ja I9 — muttei B2, D4, F7 eikä H9. Se aukko on kiinnostavin osa.
ValittuRevision klikkaus rakentaa saman kortin uudelleen paikallaan, ohittaen aktiiviset suodattimet: revision pyytäminen nimeltä on tietoinen ohitus.
HintaRyhmittely näyttää epäjohdonmukaiselta — yksi malli täyttää 8 korttia, toinen yhden. Se ei ole epäjohdonmukaisuutta vaan kattavuutta, joten “Yhdistä revisiot” tarjoaa toisen kysymyksen: 1 105 korttia → 756.

Fasettiluvut lasketaan muiden suodattimien mukaan

Fasetit

Sirun luku kertoo, mitä tämä valinta tuottaisi, kun kaikki muut suodattimet ovat voimassa.

ValittuFasetti ei koskaan nollaa omia vaihtoehtojaan. “20 V akku” valittuna näet yhä montako olisi 12 V:llä — vaihtaminen on yksi klikkaus, ei umpikuja.
ValittuLuvut lasketaan tuotteina, samana yksikkönä jonka ruudukko piirtää. Listauksina laskettuna siru lupaisi 1 926 korttia ja ruudukko piirtäisi 900.
HylättyNollasirun himmentäminen opasiteetilla: brändivihreällä otsakkeella tausta paistoi läpi ja siru näytti toisenlaiselta sirulta. Nyt himmenee sisältö, ei siru.

Nimi luetaan manuaalista, ei katalogista

Sisältö

Katalogin nimikenttä on lyhennetty kentänmittaan ja katkeaa kesken sanan. 6 781 nimeä korvattiin manuaalin kannesta luetulla.

Katalogi sanoiKortti sanooIAN
Bensiinik. ketjusaha KATBensiinikäyttöinen ketjusaha495510
Akkuk. ruohonleikkuri i akkua40 V Akkuruohonleikkuri507920
Akkuk. 3 in 1 -yleispuhallin12 V Akkukäyttöinen pieni yleispuhallin 3 in 1504168
Αθόρ.αεροσυμπ.Silent air compressor339048
ValittuAlkuperäinen nimi jää talteen ja näkyy hoverilla. Korjaus ei saa hävittää sitä mitä lähde sanoi.
HylättyEnglanninkielisen otsikon lukeminen PDF:stä automaattisesti: kannet vaihtelevat liikaa. Ankkurointi tuotti saksankielisen otsikon, kaksi “User manual”-riviä ja kompressorille nimen “HOSE REEL”.

Järjestysvalikko on natiivi <select>

Saavutettavuus

Suljettu tila on tyylitelty — nuoli piirretään itse, koska selaimen oma osuu laatikon reunaan. Avattu lista on käyttöjärjestelmän piirtämä eikä sitä voi tyylitellä.

HylättyOma listbox. Se olisi maksanut iOS:n rullavalitsimen, Androidin alapaneelin, näppäimistön type-aheadin ja ruudunlukijasemantiikan — kaikki neljä tulevat natiivilla ilmaiseksi.
HintamacOS asemoi popupin hieman sivuun, koska se sijoittaa valitun rivin kontrollin päälle. Hyväksytty tietoisesti.

URL on hakukentän sisältö

Navigointi

Osoitteen hash on kirjaimellisesti se mitä hakukentässä lukee. #313266 avaa tuotteen, #313266,495965 avaa kahden vertailun.

ValittuVain haku koodataan, ei suodattimia. Suodatin on tapa katsella ympärille; haku nimeää sen, minkä vuoksi tulit. Vain jälkimmäinen kannattaa jakaa.
ValittureplaceState, ei pushState: hakukentän kirjoittaminen ei ole navigointia, ja jokainen näppäinpainallus päätyisi muuten selaimen historiaan.

Kapealla suodattimet taittuvat — laskurin kanssa

Responsiivisuus

Kolme katkaisukohtaa (760 / 600 / 420 px). Jokainen korjasi todellisen vian, ei viimeistellyt.

ValittuOtsake on tarttuva vain leveällä. Täydessä korkeudessaan se peitti 750 px 813 px:n puhelinruudusta. Alle 760 px se on staattinen ja suodattimet vierivät pois tieltä.
ValittuSuodatinrivit olivat 868 px korkeat 390 px:n ruudulla, joten ne menevät “Suodattimet”-painikkeen taakse — painike kantaa valintojen määrän, koska suodatettu näkymä ei saa näyttää identtiseltä suodattamattoman kanssa silloin kun rivit ovat piilossa.
HintaRuudukkosolun oletus min-width: auto antoi nowrap-sirujen leventää saraketta yli 1fr:n, jolloin sivu vieri sivusuunnassa rivittymisen sijaan. Korjaus on min-width: 0.

Julkaisu on datamuunnos, ei sivun haara

Julkaisu

Sama index.html toimii sekä paikallisena työkaluna että julkaistuna sivuna, ilman ehtoja tai build-lippuja.

ValittuMuokkauskontrollit kytkeytyvät päälle vain jos tarkistuspalvelin vastaa. Kun sitä ei ole, ne piilottavat itsensä — julkaistulla sivulla ei ole kuollutta käyttöliittymää.
ValittuPDF-linkki putoaa takaisin valmistajan omaan osoitteeseen, kun paikallista tiedostoa ei ole. Julkaisu on siksi 139 MB kansikuvia — ei 19 GB manuaaleja — eikä levitä yhtään niistä edelleen.
HintaLinkki kuolee, jos Lidl poistaa tiedoston. Kahdeksan on jo kuollut, ja ne jäävät rekisteriin oman suodattimensa taakse näkyviin.
5Suodatus

Kuusi riviäJokainen vastaa yhteen kysymykseen. Ruudukko vain piirtää tuloksen.

Suodatus on sivun varsinainen käyttöliittymä

Ruudukko ei tee päätöksiä — se piirtää sen mitä jää jäljelle. Kaikki merkityksellinen tapahtuu suodatinriveillä, ja siksi niihin meni enemmän suunnittelua kuin mihinkään muuhun osaan sivua.

Kuusi riviä, kussakin yksi kysymys

Rivi ei ole datakenttä vaan kysymys. Sama tieto voisi olla jaettu monella tapaa; jako on tehty sen mukaan, mitä ihminen tulee kysymään.

RiviKysymys jonka se esittääEsimerkkejä
MarkkinaOnko tätä myyty täällä?FI · EN · DE
KäyttövoimaMitä minun täytyy omistaa, jotta tämä toimii?20 V akku · verkkovirta · bensiini
PakkausMitä laatikossa on?akku · laturi · sarja · pelkkä työkalu
SarjaOnko tämä PERFORMANCE vai erikoiserä?PERFORMANCE · limited
RevisioMonesko versio tästä mallista?A · B · C · …
VuosiMiltä vuodelta manuaali on?2015 … 2026 · ei vuotta

Huomaa Käyttövoima-rivin sanamuoto. Se ei kysy “mikä tämän tekniikka on” vaan “mitä minun täytyy omistaa”. Siksi 40 V on oma sirunsa vaikkei se ole oma alustansa — se on kaksi 20 V kennostoa, ja siru sanoo sen ääneen — ja siksi painepesu ja puutarha ovat ryhmiä eivätkä käyttövoimia.

Rivin sisällä TAI, rivien välillä JA

Yhden rivin sirut ovat vaihtoehtoja samaan kysymykseen, joten useampi valinta laajentaa tulosta. Eri rivien valinnat ovat eri kysymyksiä, joten ne kaventavat sitä. Tämä on ainoa sääntö, joka käyttäjän täytyy oppia, eikä sitä kerrota missään — se opitaan lukuja katsomalla.

KÄYTTÖVOIMAPAKKAUSRYHMÄ 20 V akku TAI 12 V akku verkkovirta JA pelkkä työkalu akku laturi JA puutarha painepesu akku- tai verkkokäyttöiset puutarhatyökalut, joiden laatikossa ei ole akkua 3 tuotetta Useampi valinta samalla rivillä LAAJENTAA · valinta uudella rivillä KAVENTAA
KUVA 5Sääntöä ei selitetä käyttäjälle missään. Se opitaan siitä, että luvut käyttäytyvät johdonmukaisesti: sirun lisääminen samalle riville kasvattaa tulosta, uudelle riville pienentää.

Laskuri jättää oman rivinsä laskematta

Tämä on koko suodatuksen tärkein yksityiskohta ja samalla se, joka on helpoin tehdä väärin. Kun lasketaan mitä Käyttövoima-rivin siru tuottaisi, kaikki muut rivit ovat voimassa — mutta käyttövoimavalintaa itseään ei huomioida. Muuten valitseminen nollaisi saman rivin muut vaihtoehdot, ja käyttäjä joutuisi umpikujaan, josta pääsee vain perumalla valintansa.

Mitkä ehdot ovat voimassa, kun kunkin rivin sirujen luvut lasketaan
Laskettava rivi Markk.Käyttöv.Pakk.SarjaRev.VuosiHaku
Markkina
Käyttövoima
Pakkaus
Sarja
Revisio
Vuosi
KUVA 6Tyhjä lävistäjä on koko sääntö. Jokainen rivi laskee itsensä ulos — ja huomaa, että Haku on aina voimassa, koska haku ei ole yksi riveistä vaan rajaa niitä kaikkia.

Luvut laskevat tuotteita, eivät listauksia

Siru, jossa luki 1 926 ruudukon näyttäessä 700 korttia, vastasi eri kysymykseen kuin se, joka oli esitetty. Luku lasketaan nyt samana yksikkönä kuin ruudukko piirtää. Tulosrivi säilyttää molemmat: montako tuotetta näkyy ja montako manuaalia niiden takana on — jälkimmäinen on se, mitä arkisto todella sisältää.

Neljä kohtaa, jotka rikkovat symmetrian

Puhdas fasettimalli olisi siisti mutta valehtelisi datan luonteesta. Neljä poikkeusta on tehty tarkoituksella:

  • Monijännitteinen työkalu näkyy jokaisessa perheessä, jonka se hyväksyy. 20 V radio, joka käy myös 12 V kennostolla, löytyy kummallakin sirulla — ei vain sirulla “monijännitteinen”. Se, mitä sinun täytyy omistaa, on kysymys johon on kaksi oikeaa vastausta.
  • “Ei vuotta” istuu vuosirivissä, ei erillisenä valintana. Sen pyytäminen vuoden 2019 rinnalla antaa molemmat: vuosisiru on TAI, ja vuoden puuttuminen on yksi vastaus lisää samaan kysymykseen.
  • Ryhmäliput eivät ole poissulkevia. Puutarha, painepesu ja kompressori kertovat mihin työkalu on tarkoitettu — eivät sitä, että se olisi jotain muuta kuin työkalu. Siksi ne eivät kilpaile pakkaustyyppien kanssa vaan elävät niiden rinnalla.
  • “Tarvitsee tarkistuksen” on sirunsa käyttövoimarivissä, vaikkei se ole käyttövoima. Se on tuotteen sijaan väite tiedon laadusta — ja juuri siksi se kuuluu samaan riviin: se on vastaus kysymykseen “mikä tätä käyttää”, ja vastaus kuuluu “emme tiedä varmasti”.

Haku ei ole suodatin

Hakukenttä ja suodatinrivit näyttävät samalta työkalulta mutta käyttäytyvät eri tavalla, ja ero on tietoinen. Suodatin rajaa; haku nimeää.

  • Pelkistä tuotenumeroista koostuva haku ohittaa suodattimet. Jos kirjoitat numeroita jotka arkisto tuntee, saat täsmälleen ne — vaikka aktiivinen suodatin sanoisi muuta. Nimeäminen on vahvempi aikomus kuin selailu.
  • Jokaisen osan on oltava tunnettu tuotenumero. Muuten 2015 olisi ohitus eikä vuosiluku, jonka joku kirjoitti. Arkiston oma numeroalue 35391–550492 ratkaisee kumpi on kyseessä — sääntö tulee datasta, ei arvauksesta.
  • Kaksi tai useampi tuotenumero on vertailu. Kortit pidetään tarkoituksella erillään sen sijaan että ne ryhmiteltäisiin — usean nimeäminen on nimenomaan pyyntö nähdä ne rinnakkain.
  • Mallikoodit ovat hakukelpoista tekstiä. Suomenkielinen nimi on usein vain “Akkuporakone”, joten koodi on ainoa tapa pyytää tiettyä työkalua. Ja koska sarja nimeää osansa, akku + laturi -paketti löytyy myös laturin koodilla.
  • Vähintään kaksi merkkiä. Yksi merkki osuu tuhansiin tuotteisiin eikä kerro mitään siitä mitä haluttiin — sama raja, jonka alkuperäinen rajapinta asettaa, samasta syystä.

Poissaolo on tuotteen ominaisuus, ei listauksen

“Vain ilman manuaalia olevat” kuulostaa yksinkertaiselta ehdolta ja osoittautui kolmiportaiseksi. IAN 300098 menetti saksalaisen tiedostonsa, mutta suomalainen ja englantilainen ovat levyllä: se ei ole tuote ilman manuaalia. Eikä siihen pysähdytä — jos saman tuotteen toinen listaus tarjoaa saman dokumentin, se on jo samalla kortilla. Tuote on ilman manuaalia vasta, kun yksikään sen listaus ei tarjoa sellaista.

Mitä laskenta maksaa

Rivit pitävät noin viittäkymmentä sirua, ja jokainen niistä käy koko aineiston läpi. Tuoteavaimen selvittäminen ei ole ilmaista — se ratkaisee mallin yli markkinarajojen — joten sirukohtaisesti laskettuna sitä kutsuttaisiin puoli miljoonaa kertaa jokaisella näppäinpainalluksella. Avaimet muistetaan siksi yhden laskentakierroksen ajan, eikä sen pidempään: muuten mallin, ryhmittelyn tai “Yhdistä revisiot” -valinnan muuttaminen jättäisi vanhentuneen avaimen elämään.

Kokeile itse

Alla on sama logiikka 18 aidolla suomalaisella listauksella. Vaihda laskutapaa oikealta ja katso mitä naiivi tekee saman rivin muille vaihtoehdoille.

Käyttövoima
Pakkaus
Ryhmä

Vähintään 2 merkkiä. Pelkät tunnetut tuotenumerot ohittavat suodattimet.

18 tuotetta · 70 tuotenumeroa · ei suodattimia

Yliviivattu rivi kortissa on katalogin alkuperäinen nimi. Oikeassa tuotteessa se on hoverilla.

6Suorituskyky

Mitattuei arvioitu. Jokainen luku on selaimen profiloijasta.

Kolmetuhatta korttia ilman kehystä

Sivu ei valitse oletusmarkkinaa, joten ensimmäinen näkymä on koko arkisto: 2 932 korttia. Suomen katalogi on pienempi tapaus (1 105), ei oletus. Kehyksetön sivu ei tarkoita, ettei suorituskykyä tarvitse tehdä — se tarkoittaa, että se on tehtävä itse.

Sama oire, kolme eri syytä

Puhelimella ensimmäinen painallus tuntui katoavan. Helppo selitys oli, että ruudukko pitää pääsäiettä varattuna. Se oli osa totuutta, mutta vasta profilointi kertoi loput — ja tämä on koko osion tärkein kohta: oire oli yksi, syitä kolme, eikä ensimmäisenä korjattu ollut niistä suurin.

  • Ruudukko ei ollut keskeytettävissä. Erän koko mitataan nyt ajassa, ei korttimääränä — hidas puhelin saa pienemmän erän kuin työpöytä ilman että kumpaakaan säädetään käsin — ja pointerdown pysäyttää täytön, jotta kosketus saa vastauksen heti eikä jonon perässä.
  • Käynnistys oli aidosti hidas, muttei siitä syystä kuin oletin. 5,7 MB:n JSON.parse on 28 ms — ei ongelma. Kaksi apufunktiota sen sijaan kävi läpi kaikki 10 257 listausta jokaista korttia kohden kysyäkseen mitä muuta samalla tuotenumerolla on: yhdestä 1 104 ms:n tehtävästä 945 ms ja 620 ms. Ne lukevat nyt indeksiä.
  • Ja lopulta aloitusruutu söi kosketuksen. Se pidetään näkyvissä yhden raitajakson ajan (1 300 ms), vaikka sivu on valmis paljon aiemmin — joten ensimmäinen painallus osui overlayhin ja katosi. Se poistuu nyt ensimmäisestä pointerdown-tapahtumasta, ja koska samalla katoaa pointer-events, sama painallus läpäisee alla olevaan painikkeeseen.

Rehellinen tulkinta on siis, ettei mikään näistä yksin selitä lukua alla. Paloittelu teki ruudukosta keskeytettävän, indeksi lyhensi käynnistyksen — ja aloitusruutu piilotti sen, että kumpikin oli jo toiminut.

Kosketuksen vasteaika, puhelin — kaikki kolme korjausta yhdessä

Ennen
1 600 ms
Jälkeen
99 ms

Teeman vaihto — tyylien uudelleenlaskenta

Ennen
131 ms
Jälkeen
17 ms

Raskain yksittäinen käynnistystehtävä

Ennen
1 104 ms
Jälkeen
375 ms

2 935 tuotteen lajittelu nimen mukaan

Ennen
155 ms
Jälkeen
2 ms

Yksi näppäinpainallus hakukentässä

Ennen
40 ms
Jälkeen
10 ms

Näkymän ulkopuoliset kortit eivät maksa mitään

Teeman vaihto ja hakukentän näppäinpainallus paranivat samasta muutoksesta: content-visibility ja mitattu contain-intrinsic-size 430 px. Ilman mitattua arviota vierityspalkki hyppii; mitatun kanssa selain ohittaa näkymän ulkopuolisten korttien tyylityksen ja asettelun kokonaan. Kansikuvat ladataan laiskasti: 245 kuvaa 6 153:sta ensimmäisellä maalauksella.

Kaksi halvalta näyttänyttä asiaa, jotka eivät olleet

Profilointi nosti esiin kaksi kohtaa, joita kumpaakaan ei olisi arvannut lukemalla koodia. String.localeCompare rakentaa uuden vertailijan jokaista vertailua kohden, joten 2 935 tuotteen lajittelu nimen mukaan maksoi 155 ms — jaettuna Intl.Collator-oliona 2 ms. Ja fasettiluvut käyvät jokaisen listauksen läpi kerran sirua kohden, yhteensä 164 ms.

Fasettilukujen kohdalla korjaus ei ollut tehdä työtä nopeammin vaan tehdä se eri järjestyksessä. Kukaan ei lue sirun lukua sillä sekunnilla kun ensimmäiset kortit vasta ilmestyvät, joten luvut lasketaan nyt ruudukon jälkeen eikä ennen sitä. Mitattu kokonaisaika ei muuttunut lainkaan.

Miksi tämä on suunnittelukysymys

1,6 sekunnin vaste kosketukseen ei näytä hitaudelta vaan rikkinäisyydeltä: käyttäjä painaa uudelleen. Huomaa, että kaksi kolmesta korjauksesta ei nopeuta mitään mitattavaa kokonaisaikaa — erän keskeytys ja fasettilukujen siirto vain asettavat työn siihen järjestykseen, jossa käyttäjä sitä katsoo. Se on käyttöliittymäpäätös, ei optimointi. Ja aloitusruutu on muistutus siitä, että mitattu nopeus ja koettu nopeus voivat erota 1 300 ms — juuri sen verran kuin animaatio, jota kukaan ei pyytänyt.

7Teemat

Väri on maaliaTeema ei muuta sitä, mitä tuotteita näkyy.

Kolme teemaa, yksi token-joukko

Värit on luettu PARKSIDEn omista design-tokeneista heidän tyylitiedostostaan — ei näytteistetty silmämääräisesti kuvakaappauksesta. Vihreä #1e4b32, power-vihreä #00ff99, punainen #cd2828.

Plain #111111
20 V 1926verkko 3205ilma 463
20 V AkkuporakonePABS 20-Li I9 · 2025-02
Parkside #1e4b32
20 V 1926verkko 3205ilma 463
20 V AkkuporakonePABS 20-Li I9 · 2025-02
Performance #cd2828
20 V 1926verkko 3205ilma 463
20 V AkkuporakonePABS 20-Li I9 · 2025-02

Oletus: Parkside · valinta muistetaan localStoragessa

Kolme yksityiskohtaa, jotka teema pakotti ratkaisemaan

  • Otsake on kokonaan brändivihreä, joten kaikki sen päällä tarvitsee oman kontrastinsa: --header-bg, --header-ink, --header-muted, --header-line ovat toinen token-joukko, ja sirut pitävät oman vaalean pintansa.
  • Valittu siru ottaa power-vihreän #00ff99, koska brändivihreä brändivihreällä katoaisi täysin. Sama sääntö toistuu tälläkin sivulla — valitun sirun väri on lainattu suoraan.
  • Teema asetetaan <head>:ssä ennen tyylitiedostoa. Muuten jokainen käynti välähtäisi edellisen teeman värit ennen oikeaa.

Kaksi tokenia, ei yhtä

Tumma teema toimii siksi, että --ink on korkean kontrastin väri (tumma vaalealla, vaalea tummalla) ja --strong on täytetty pinta erikseen. Näin valittu siru voi olla punainen hiilenharmaalla ilman että leipäteksti lähtee mukaan. Yhdellä tokenilla se ei onnistu.

8Kieli

Kaksi eri asiaajoita käyttäjät sekoittavat jatkuvasti.

Käyttöliittymän kieli ei ole katalogin kieli

Ylhäällä oikealla on FI / EN. Alempana suodatinriveissä on Markkina. Ne ovat eri asioita, ja niiden sekoittaminen olisi ollut helppo — mutta väärä — yksinkertaistus.

  • FI / EN vaihtaa sivun tekstit. Oletus on suomi vain jos selain pyytää suomea, muuten englanti.
  • Markkina valitsee selattavan katalogin. Suomenkielinen käyttöliittymä voi hyvin listata englantilaisia manuaaleja — se on täysin kelvollinen tilanne.
  • Englanti on lähdeteksti, suomi on päällyste. Puuttuva avain putoaa englantiin, ei näytä avaimen nimeä. Käyttäjä ei koskaan näe facet.power.label-tyylistä vuotoa.

Kielenvaihto rakentaa sirut uudelleen, ei nimeä niitä uudelleen

Uudelleennimeäminen olisi jättänyt valintatilan ja nimiön eri tahtiin. Nyt sirurivit tyhjennetään ja rakennetaan uudelleen valintajoukosta — muuten jokaisesta rivistä ilmestyisi toinen kappale. Ja suodatinsarake on 96 px leveä siksi, että KÄYTTÖVOIMA on puolitoista kertaa POWER-sanan mittainen. Layout mitoitetaan pisimmän kielen mukaan, ei lähdekielen.

9Rajat

KirjattuTunnettu puute on eri asia kuin tuntematon.

Mikä on yhä kesken

Arkisto on käytössä ja julkaistu, mutta kolme asiaa tiedetään keskeneräisiksi. Ne ovat kirjattuina, koska tunnettu puute on eri asia kuin tuntematon.

  • Lisävarusteet perivät jännitteitä. Reikäsahasarja, joka mainitsee yhteensopivat 20 V työkalut, luokittuu 20 V akkutyökaluksi. Tarvitsee nimitason lisävarustesäännön.
  • Tuotekuvia on 1 356 / 2 935. Loput näyttävät manuaalin ensimmäisen sivun, joka on mitä sattuu olemaan. Neljää Lidlin verkkokauppaa (BE / PL / NL / ES) ei ole vielä käyty läpi.
  • Hyväksytty listaus ei enää parane säännöllä. Kaikki 10 257 on merkitty varmaksi, joten myöhemmin lisätty luokka ei tavoita niitä — vain merkinnän poistaminen tavoittaa.

Mitä tekisin toisin

Kaksi asiaa. Ensinnäkin olisin rakentanut rekisterin invarianttitarkistuksen ensimmäisenä päivänä enkä viimeisellä viikolla — jokainen virhe tässä projektissa oli samanmuotoinen: sääntö, joka oli oikeassa käsillä olevasta tapauksesta ja muutti hiljaa satoja muita. Toiseksi olisin mitoittanut suodatinsarakkeen suomeksi heti alusta; englanniksi mitoitettu layout oli rakennettava kahdesti.