Opdatering på udviklingen

Bubbles, FC Sunnyvale Udvikler 9. september 2025, 13:40

Ja, min plan om at skrive meget hyppigere blogindlæg gik desværre i vasken. Det beklager jeg. Da jeg lagde planen med at dele udviklingsarbejdet op i milestones havde jeg en ambition og forventning om at hver milestone ville kunne klares væsentligt hurtigere.

Så hvorfor tager det så lang tid? Det er der ikke et simpelt svar på - der er mange faktorer, der spiller ind:

1. Undervurderet hvor mange grundlæggende problemstillinger skulle løses

Hvis man skal redesigne 100 sider, så tager den første side kun 1% af tiden, ikke? Niks, sådan fungerer det selvfølgelig ikke i virkeligheden. Det har været en kæmpe opgave bare for at komme i gang med at lave de første par sider om, da der var mange fundamentale problemer, der skulle løses først. Jeg skriver om nogle af dem længere nede.

Og, som jeg har forsøgt at forklare før, så er det ikke blot et re-design af det visuelle. Det er en omfattende omstrukturering og omskrivning af hele Vman's platform, som vi bliver glade for på lang sigt.

Men, for at vi kan komme videre med noget mere nyt i spillet, har jeg valgt at justere udviklingsplanen. Det skriver jeg mere om længere nede.

2. Kun 1 fuldtidsansat

For de, som ikke ved det, så er jeg den eneste fuldtidsansatte her i butikken. Jeg er firmaets ejer, udvikler, bogholder, sekretær, kantinedame, designer, osv. osv. Derudover har jeg FC Apollyon, som arbejder nogle timer om ugen som administrator, og vores freelance-udvikler, som jeg hyrer ind i afgrænsede perioder.

Det sætter selvfølgelig en grænse for hvor hurtigt tingene kan gå, når jeg sidder alene med udviklingen det meste af tiden. Men, vores freelancer er netop vendt tilbage, og jeg har aftale med ham om at købe 300 timer over de næste 3 måneder.

3. Design er svært

Vi har måttet indse at design dælme er svært når man kommer ud i detaljerne, og vi ikke har nogen på holdet, som er specielt gode til det.

For mig betyder det at jeg ofte kommer til at sidde fast og bliver frustreret. Det resulterer ofte i at jeg giver op og i stedet laver backend-ting, som måske ikke er nødvendige lige nu og her.

Selvom jeg undersøger mulighederne for at hyre en designer ind til at kigge på et begrænset antal sider, så er det også nødvendigt at jeg selv bliver bedre til det.

Det er nemlig urealistisk at tro at vi kan få råd til at en designer kan lave det hele, for der er MANGE flere sider i Vman, end man skulle tro. Dags dato indeholder spillet 462 unikke sider og 240 partials (partials er brudstykker, som sættes ind på siderne og i nogle tilfælde genbruges flere steder).

Derfor har jeg påbegyndt et selvstudie i design, som gerne skulle gøre det nemmere for mig at redesigne en side uden at sidde fast. Dertil kommer at det helt naturligt vil gå hurtigere, jo flere sider vi bliver færdige med og opbygger et "katalog" af løsninger på UI-mæssige problemstillinger, der går igen flere steder.

4. Livets omstændigheder

Udover de ovenstående faktorer, så kommer vi heller ikke uden om det faktum at jeg ikke arbejder lige så effektivt, som dengang jeg startede i firmaet lige efter universitetet. Dengang sprøjtede der kode ud af mig, og jeg kunne ikke lade være med også at arbejde i min fritid, især da jeg fik opgaven at lave den nye kampmotor (den med ludo-brikkerne) som erstatning for den gamle tekst-baserede. Den udviklede vi forbløffende hurtigt på kun få måneder. Jeg lavede selve kampmotoren (backend, AI, osv.) mens spillets grundlægger, Rasmus (The Dudes), lavede den visuelle del.

Det skal dog siges, at noget af det hæsblæsende tempo, vi lagde for dagen i de første år efter jeg blev ansat, kom på bekostning af en vis teknisk gæld - en gæld som vi stadig betaler af på, bla. i form af alt det arbejde, vi pt. lægger i denne omfattende omskrivning.

Men tiden gik, og efter at have arbejdet her i 12 år, opkøbte jeg firmaet. I samme øjeblik ramte COVID-19, og mine planer om at genfinde inspirationen og arbejde fra eksotiske lokationer blev i stedet til at jeg bare sad og kukkelurede derhjemme. For mange års hjemmearbejde, et par langvarige sygdomsperioder og et slemt cykelstyrt, hvor jeg brækkede bækkenet, har efterladt mig med dårlige vaner og i dårlig fysisk form. "Doven og halvfed" ville nogle måske være frække nok til at sige, men jeg må indrømme at tingene bare går noget langsommere nu om dage.

Jeg var meget i tvivl om hvorvidt jeg skulle skrive dette afsnit, for jeg vil ikke have at det lyder som om jeg fisker efter medlidenhed. Det gør jeg ikke. Det er mine personlige udfordringer, og jeg er den eneste, der kan løse dem. Jeg inkluderede det alligevel af hensyn til dem, der ikke ville være tilfredse med mindre end den fuldstændige forklaring. Det er blot livets fakta, og det er altsammen noget jeg arbejder på at forbedre.

Planen over den næste tid

Det står klart at der er gået for lang tid uden mærkbare forbedringer i spillet. Derfor har jeg besluttet at vi stopper arbejdet på Milestone 1, og får afrundet de ting vi har gang i så hurtigt som muligt. De ting vi mangler på Milestone 1 bliver flyttet til et senere tidspunkt.

Derefter starter vi på Milestone 2, som bekendt handler om taktik-delen. Den har jeg skrevet om før, men kort fortalt så går det ud på at opsplitte og udskifte en række af de nuværende taktik-indstillinger med langt mere detaljerede indstillinger.

Det er en opgave, jeg har haft i tankerne og glædet mig til i flere år, og her er vi langt mere på hjemmebane end med design. I mellemtiden fortsætter jeg med at læse op på UI design, så jeg er bedre rustet når vi vender tilbage til det.

Et kig på ting i redesignet

...og lad os så tage et kig på nogle af de ting, vi har lavet på Milestone 1.

Klubhus

En af de første sider, vi redesignede var Klubhus -> Overblik.

Klubhus -> Overblik på store skærme

På denne side valgte vi den simple løsning og bibeholdt struktur og indhold fra den gamle, da det egentlig fungerer OK. Siden er genimplementeret i vores nye design-system, og vigtigst af alt, så er den responsiv; dvs. den tilpasser sig flydende til forskellige skærmstørrelser.

Efterhånden som skærmen bliver mindre, skrumper indholdet indtil pladsen bliver for trang til indholdet. Derefter bliver side- og top-navigationen gemt væk i folde-ud-menuen, hvilket giver plads til at vi kan bibeholde de 2 kolonner. Indholdsområdet skifter samtidigt over til at gå helt ud til kanterne af skærmen.

Klubhus -> Overblik på medium skærme

Når skærmen bliver endnu mindre, når vi til sidst et punkt, hvor de 2 kolonner klapper sammen til 1.

Klubhus -> Overblik på små skærme

Shoutbox

Som jeg også nævnte i sidste blogindlæg, så bliver ALT javascript kasseret og skrevet om på en måde, der fungerer med vores nye platform. Shoutboxen var vi derfor nødt at skrive om på ny. Den ligner sig selv, men er nu fuldt integreret i vores nye platform, og man kan f.eks scrolle mellem beskederne ved at swipe med fingeren på mobil.

Dark mode

Der er mange, der godt kunne tænke sig en dark mode på på Vman. Vi har før eksperimenteret med det internt, men det blev alt for rodet og usammenhængende, fordi det gamle site simpelthen ikke er bygget til det.

Med redesignet er dark mode bygget ind fra starten. I vores design-system er alle de centrale farver defineret som variabler, der er navngivet efter deres anvendelsesområde. Tekst- og baggrunds-farver defineret i sæt, der passer sammen, og har nok kontrast til at teksten altid er let læselig. Så i stedet for at angive at en sektion f.eks skal have sort tekst med grå baggrund, så angiver vi i stedet at den skal bruge farven "base-300" som baggrund og "base-content" som tekst-farve.

Det betyder at vi kan definere de navngivne farver i to versioner: light mode og dark mode - og dermed har vi løst problemet med at understøtte dark mode een gang for alle. I dark mode-paletten er de to navngivne farve-variabler så defineret som en næsten sort til baggrunden, og en lys grå til teksten.

Hvis vi bruger de navngivne farver konsekvent, behøver vi ikke at tænke dark mode ind på hver eneste side - det virker bare. En simpel javascript-komponent kan så blot skifte mellem 2 paletter i forhold til hvad du har valgt.

Klubhus -> Overblik i dark mode

Skarp fokus på performance

Som jeg fortalte i sidste blogindlæg, handler vores nuværende projekt ikke kun om nyt design. Det er en omfattende omskrivning af hele spillets platform, og centralt i det er et skarpt fokus på performance og lynhurtige responstider.

På mobil er 1-2 sekunders responstid simpelthen ikke godt nok. Vi skal ned under 500ms på de fleste sider, og helst endnu mindre. Det kræver at vi tænker performance ind i systemet fra top til bund, på en måde, der ikke var mulig på det gamle site.

For at opnå dette, er vi nødt til at sætte ind med optimering i alle led at kæden.

  • Databasen skal levere data så hurtigt som muligt, og skal skånes når vi kan.
  • Webserverne skal stykke siderne sammen lynhurtigt, hver gang du klikker.
  • Hvis du foretager handlinger, som er meget beregningstunge - f.eks træning - skal de udføres asynkront i baggrunden, du skal have øjeblikkelig feedback på at træningen er i gang, og så skal du sendes automatisk videre til resultatet, i det øjeblik det er klar.
  • Vi skal sende så lidt data til dig som muligt, hvilket især er vigtigt hvis du f.eks sidder i bussen og kører gennem et område med dårlig dækning.
  • Når du har modtaget sidens indhold skal vi sørge for at din enhed ikke skal bruge en masse tid på at parse og vise det. Igen er dette især vigtigt på mobil.

Caching

Caching er et af de vigtigste værktøjer, både til at skåne databasen og til at gøre det nemmere for webserverne at generere den side, som du har bedt om.

Førhen har vi tilføjet caching på enkelte problematiske sider for at fikse akutte problemer. Med redesignet bliver caching tænkt ind alle steder fra starten, og vi cacher så meget som muligt.

Den teknik, vi bruger, hedder fragment caching, og fungerer ved at vi gemmer brudstykker af siderne på en lynhurtig cache-server, således at vi slipper for at generere dem igen, så længe de data, de er lavet ud fra, ikke har ændret sig. På den måde skal både database og webservere bruge færre kræfter på at generere siderne, især hvis de cachede fragmenter deles af alle brugere.

Hvis vi tager kigger på Klubhus -> Overblik

Cachede elementer
  1. Topnavigationen
  2. Sidenavigationen
  3. Din klubs infoboks
  4. Ligatabellen
  5. Hver kamp i "Aktuelle kampe"
  6. Hver besked i shoutboksen
  7. Vifarank-udvikling

Der er mange faldgruber ved caching, og de fleste af dem har vi allerede erfaring med fra tidligere.

Den første faldgrube er at man nemt kan komme til at vise for gammel data. Vores system løser problemet ved at hvert cache-fragment har en nøgle, der indeholder det tidspunkt, som det data-objekt vi viser, sidst er blevet opdateret. Et konkret eksempel kan være kampene i sektionen "Aktuelle kampe". Hver kamp har et timestamp, som systemet automatisk opdaterer med "nu", hver gang noget ændrer sig. Det samme gør sig gældende for de fleste af de data-objekter du kan forestille dig, f.eks klubber, ligaer, spillere, hold, forum-indlæg, osv. osv.

Når webserveren skal stykke Overbliks-siden sammen, så tjekker den for hver kamp i listen om der findes et cachet fragment med en nøgle, hvor kampens sidste opdateringstidspunkt passer. Hvis der ikke gør det, bliver fragmentet renderet som normalt, men det bliver gemt i cachen, så det ligger klar til næste gang.

De forældede fragmenter ryddes automatisk op af cache-serveren, da den sletter de objekter som er blevet læst for længst tid siden, når den er ved at løbe tør for plads.

I virkeligheden er det mere komplekst end eksemplet. For vi skal jo også tage højde for forskellige. Derfor indgår en sprogkode også i alle cache-nøgler.

En stor problemstilling er omkring tidspunkter. For det første har forskellige sprog forskellige tids- og dato-formater. Dette problem er allerede løst i og med at sprogkoden indgår i alle cache-nøglerne.

Langt mere besværligt bliver det, når vi skal tage højde for tidszoner. Vi kunne godt lade tidszonen indgår som endnu en komponent i cache-nøglerne, men hver gang vi tilføjer noget mere i cache-nøglerne stiger antallet af forskellige versioner af fragmenter, vi skal gemme i cachen, med krydsproduktet. Og, vi vil jo helst have at så mange som muligt deles om de samme fragmenter i cachen.

Dertil kommer problemet med relative tider, f.eks når vi angiver et tidspunkt som "i går", "om ca. 5 minutter", osv. Det er et problem fordi ordlyden skal ændre sig løbende, uden at data-objektets tidspunkt ændrer sig - det er bare tiden der går. Så her har vi ikke engang mulighed for fikse det ved at tilføje noget mere til cache-nøglen.

Førhen har vi simpelthen bare undladt at cache tidspunkter, men med redesignet har jeg insisteret på at vi fandt en løsning, een gang for alle.

Det har vi gjort ved at implementere en måde at indsætte tidspunkter på på siderne, som indeholder tiden i UTC, sammen med instrukser til en Javascript-komponent om hvordan det skal formateres. Javascript kører på din egen maskine, og komponenten formaterer således tidspunktet ud fra din tidszone, hver gang du henter en side.

På den måde kan alle deles om det samme cache-fragment, selvom de sidder i forskellige tidszoner, og det løser også problemet med relative tider.

Navigationen cacher vi også. Som du allerede har set, så hopper navigationen ud i en folde-ud-menu i venstre side på små skærme. Denne navigation indeholder links til samtlige hovedsektioner inkl. undersider i en træstruktur, vi er nødt til at inkludere hele menuens indhold ved hver sidevisning, selvom det meste af den vil være skjult på store skærme. Det er vi, fordi den skal være tilgængelig med det samme, hvis du skifter skærmstørrelse, f.eks ved at du drejer din tablet fra vandret til lodret.

Den navigation, du ser i venstre side på store skærme, er faktisk den samme som ligger i folde-ud-menuen. Vi bruger blot styling til at placere den og gøre de irelevante sektioner midlertidigt usynlige. For at kunne cache navigationen, var vi nødt til at finde en løsning til at fremhæve linket til den side man pt. er på. På det gamle site er navigationen ikke cachet, så der bliver den genereret på serveren ved hver sidevisning, og fremhævningen bliver indsat direkte. Her dur det selvfølgelige ikke hvis vi skulle cache en version af navigationen for hver eneste mulige side, for at vi får den korrekte fremhævning med.

Det har krævet en ny navigations-backend og en ny Javascript komponent, der automatisk kan fremhæve det korrekte link i navigationen, styre hvilke sektioner, der skal være usynlige på store skærme, og samtidig sørge for at den relevante sektion altid er foldet ud i menuen på mobil.

Sidste eksempel er måden vi håndterer indhold, som skal se forskelligt ud afhængigt af hvilken klub, der ser på den. F.eks liga-tabellen. Her skal din egen klub fremhæves, og igen har vi måttet finde en løsning, som er cache-venlig, og gør vi kan sende det samme cachede fragment til alle, men samtidigt fremhæve din egen klub. Det er også gjort ved at indsætte ekstra data i ligatabellen ved hver klub, som en Javascript-komponent på din egen maskine så kan aflæse og sørge for at fremhæve din klub.

Væsentligt reduktion af CSS og Javascript

Med vores nye platform har vi også opnået en markant reduktion i mængden af CSS og Javascript, vi sender. Og selvom din browser automatisk cacher JS og CSS første gang du besøger sitet, så skal din enhed stadig bruge tid på at indlæse og parse hele baduljen ved hver sidevisning. På en desktop-maskine betyder det måske ikke så meget, men det er igen noget, som kan gøre oplevelsen dårligere på mobil.

En sammenligning af den gamle og nye version af Klubhus -> Overblik viser hvor store reduktioner, vi har opnået:

 Gammel sideNy side
CSS 852 kB155 kB
JS1239 kB545 kB

CSS er reduceret med 82% og Javascript er reduceret med 56%.

Disse tal inkluderer kun de ting, vi selv sender - ikke tredjeparts-komponenter, som f.eks Google Charts, der bruges til at vise VIFA udviklingen.

Dette var kun et par eksempler på det arbejde, vi ligger i at gøre spillets nye platform lynhurtig. Som jeg allerede har nævnt, så er re-designet en omfattende omstrukturering, hvor performance er helt centralt.

Den kommende tid

Som sagt, så er vi i gang med at afrunde de ting, vi har gang i på Milestone 1, så vi kan få den lukket ned og komme videre med taktik-delen. Jeg regner med at vi går i gang med taktikeditoren om 1-2 uger.

Jeg har ikke besluttet om jeg kommer til at skrive et blogindlæg om flere af de ting, vi har lavet i Milestone 1 inden da.

Giv jeres feedback her: Feedback: Opdatering på udviklingen