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 + toteutusKesto 12 päivää, 81 committiaPino HTML · CSS · vanilla JS · PythonJulkaisu 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ä.
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: “Akkuiskuporakonesarja” 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 on
Vastaa kysymykseen
Listaus
10 257
Yksi tuote yhdellä markkinalla
Myydäänkö tätä Suomessa?
Tuotenumero
4 806
IAN — yksi pakkaus
Mikä manuaali minun laatikkooni kuuluu?
Tuote
2 935
Malli + revisio
Mitä 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.
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.
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.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.
ValittuKielikohtaiset 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 sanoi
Kortti sanoo
IAN
Bensiinik. ketjusaha KAT
Bensiinikäyttöinen ketjusaha
495510
Akkuk. ruohonleikkuri i akkua
40 V Akkuruohonleikkuri
507920
Akkuk. 3 in 1 -yleispuhallin
12 V Akkukäyttöinen pieni yleispuhallin 3 in 1
504168
Αθόρ.αεροσυμπ.
Silent air compressor
339048
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.
Rivi
Kysymys jonka se esittää
Esimerkkejä
Markkina
Onko tätä myyty täällä?
FI · EN · DE
Käyttövoima
Mitä minun täytyy omistaa, jotta tämä toimii?
20 V akku · verkkovirta · bensiini
Pakkaus
Mitä laatikossa on?
akku · laturi · sarja · pelkkä työkalu
Sarja
Onko tämä PERFORMANCE vai erikoiserä?
PERFORMANCE · limited
Revisio
Monesko versio tästä mallista?
A · B · C · …
Vuosi
Miltä 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.
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.
Sarja
Rev.
Vuosi
Haku
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.