Wish You Were Here

← Artiklar

Hur stor del av produktkoden är gränssnitt?

29 produkter med öppen källkod. 40 741 analyserade pull requests. I medianprodukten ligger 52,4 procent av den ändrade produktionskoden i gränssnittslagret.

Frågan är äldre än vi trodde

Vi arbetar med digitala gränssnitt och började fundera på hur stor del av utvecklingen av en digital produkt som faktiskt sker där.

Det visade sig att någon redan hade försökt svara på frågan.

1992 publicerade Brad Myers och Mary Beth Rosson Survey on User Interface Programming. De fick in 74 svar från utvecklingsprojekt och fann att i genomsnitt 48 procent av koden ägnades åt användargränssnittet. De uppskattade dessutom att gränssnittet stod för omkring 50 procent av implementationstiden.

Det var en intressant siffra. Problemet var bara att undersökningen gjordes 1992.

Då handlade modern gränssnittsutveckling om saker som Motif, Macintosh, HyperCard och interface builders. Sedan dess har webben, mobiltelefonen, React, API:er, designsystem och helt andra sätt att bygga digitala produkter förändrat förutsättningarna ganska ordentligt.

Så vi bestämde oss för att ställa samma grundfråga igen, med moderna produkter och faktisk kod.

Vår undersökning mäter inte exakt samma sak som Myers och Rossons. De frågade utvecklingsprojekt hur stor del av koden som hörde till användargränssnittet. Vi mäter vilka delar av produktionskoden som faktiskt förändras över tid. Siffrorna ska därför inte läsas som en direkt jämförelse.

Men resultatet hamnade ändå påfallande nära.

Ungefär hälften

I medianprodukten ligger 52,4 procent av den ändrade produktionskoden i gränssnittslagret.

Vi har alltså inte räknat hur stor del av hela kodbasen som är frontend. Vi har tittat på förändringen: vilka filer som läggs till, tas bort och byggs om när riktiga produkter utvecklas under ett år.

Mätningen säger inte heller hur lång tid arbetet tar eller vad det kostar.

Den säger något enklare: var i produkten förändringen sker.

Och i medianprodukten sker ungefär hälften av den förändringen i gränssnittet.

52,4 %

av den ändrade produktionskoden ligger i gränssnittet, median över produkterna

56,5 %

av produkt-PR:erna rör gränssnittet

18 av 29

produkter har mer än halva kodändringen i gränssnittet

0,43

samändring mellan lagren, median — under 1 betyder att de ändras var för sig

29 produkter, samma fråga

Vi valde etablerade produkter med öppen källkod där det gick att skilja gränssnitt från backend på ett rimligt sätt. Materialet innehåller allt från kommunikationsverktyg och affärssystem till analysverktyg, utvecklarprodukter och konsumenttjänster.

Skillnaderna mellan produkterna är stora. Det är också helt väntat.

I vissa produkter ligger nästan allt användaren gör i ett grafiskt gränssnitt. I andra ligger en större del av arbetet i databehandling, integrationer, API:er eller annan backendfunktionalitet.

Poängen är därför inte att alla digitala produkter består till 52,4 procent av gränssnitt.

Det intressanta är hur ofta gränssnittet utgör en mycket stor del av den kod som faktiskt förändras.

Stapeln visar
Sorts produkt

    Lagren ändras var för sig

    Man skulle kunna föreställa sig att frontend framför allt förändras som en konsekvens av backend. Någon bygger en ny funktion eller ändrar datamodellen och därefter behöver gränssnittet anpassas.

    Men sambandet är inte särskilt starkt.

    Samändringen mellan lagren är 0,43 i vårt material. Måttet är hur ofta en pull request rör både gränssnitt och backend, delat med hur ofta det skulle ske om lagren ändrades oberoende av varandra — under 1 betyder alltså att de ändras var för sig oftare än slumpen. Stora förändringar i backend behöver inte innebära stora förändringar i gränssnittet, och tvärtom.

    Det stämmer också ganska väl med hur digitala produkter faktiskt utvecklas. Ett flöde kan förenklas, information flyttas, navigation göras om eller en interaktion förbättras utan att motsvarande mängd backendkod behöver förändras.

    Gränssnittet verkar alltså inte bara vara det sista steget i en backendförändring. Det är ett utvecklingsområde i sig.

    Så gjorde vi

    Materialet består av pull requests som mergades mot huvudgrenen under ett år i 29 produkter med öppen källkod. Det är produkter som används i verkligheten, inte ramverk, bibliotek eller exempelprojekt.

    Totalt analyserades 40 741 pull requests.

    Varje förändrad fil klassificerades efter vilket lager den tillhörde: gränssnitt, backend eller delad kod. Reglerna sattes per repository och utifrån kodens ansvar, inte enbart utifrån filändelse eller programmeringsspråk.

    Tester, dokumentation, genererad kod, automatiska dependency-uppdateringar och andra förändringar som inte representerar produktionskod räknades bort.

    Måttet är kodvolym: rader produktionskod som lagts till eller tagits bort. Därför ska resultatet läsas som ett mått på var förändringen sker, inte på arbetstid eller kostnad.

    Vi använde Claude som stöd i analysarbetet och som en oberoende kontroll av klassificeringen. Ett stickprov på 580 filer klassificerades av Claude utan tillgång till den första klassificeringen. Överensstämmelsen blev 0,93 mätt med Cohens kappa.

    Det betyder inte att metoden är perfekt. Gränsen mellan gränssnitt, backend och delad kod är ibland en bedömningsfråga. Därför tycker vi att det är viktigare att beskriva hur vi har räknat än att ge siffrorna en precision de inte har.

    rules/getsentry__sentry.py
    RULES = [
        # Tester — undantagen först, första träffen vinner
        (r"^tests/(js|acceptance)/",   "test_ui"),
        (r"^tests/",                   "test_backend"),
        (r"^static/app/stories/",      "test_ui"),
        # Frontend
        (r"^static/",                  "ui"),
        (r"^src/sentry/templates/",    "ui"),
        (r"^src/sentry/web/frontend/", "shared"),
        # Backend
        (r"^src/sentry/",              "backend"),
        (r"^api-docs/",                "nonproduct"),
    ]
    Reglerna för Sentry, förkortade. Ordningen är en del av regeln: eftersom första träffen vinner räknas komponentkatalogen under static/app/stories/ som test och inte som gränssnitt, trots att den ligger i frontend-katalogen. web/frontend/ är Django-vyer som renderar React-skalet — varken det ena eller det andra, och därför delad kod.

    Gränssnittet är inte det tunna lagret ovanpå produkten

    Vi började med en enkel fråga: hur stor del av en modern digital produkt utgörs egentligen av gränssnittet?

    Vi kan fortfarande inte svara på hur mycket av hela produkten som är gränssnitt. Men vi kan säga att i de produkter vi undersökte ligger ungefär halva den förändrade produktionskoden där.

    Det gör det åtminstone svårt att beskriva gränssnittet som ytan ovanpå det egentliga arbetet.

    Det är en stor del av det egentliga arbetet.

    gränssnitt 52,4 % övrig produktionskod 47,6 %

    Bilden visar medianprodukten: den som hamnar i mitten när alla 29 produkter ställs i ordning efter hur stor del av kodändringen som ligger i gränssnittet. 14 produkter ligger över den och 14 under. Det är alltså inte ett snitt av de 29 — den lägsta ligger på 30,8 procent och den högsta på 85,7.

    En sista fråga

    Vi har bara räknat kod.

    Ett produktbolag består samtidigt av väldigt mycket som inte är produktkod: design och research, men också innehåll, marknad, försäljning, support, organisation och allt annat som krävs för att en produkt ska existera och nå sina användare.

    Så om ungefär hälften av den produktionskod som förändras ligger i gränssnittet, blir nästa fråga större än den vi ställde:

    Hur stor del av ett produktbolags immateriella tillgångar är egentligen produktionskod?

    Begreppen

    Pull request (PR)
    Ett förslag på en kodändring. När det godkänns och mergas blir ändringen en del av produkten. Vi räknar en mergad pull request som en förändring.
    Huvudgren
    Den gren koden lever i när den är klar. Pull requests mot release-grenar och bakåtportar räknas inte, för att samma ändring inte ska räknas två gånger.
    Produktionskod
    Koden som utgör produkten. Tester, dokumentation, byggskript, översättningsfiler och genererad kod räknas inte hit.
    Gränssnitt, backend, delad kod
    De tre lager varje förändrad fil klassificerades i. Gränssnittet är det användaren ser och gör något i, backend är data och logik bakom, delad kod hör till båda.
    Kodvolym (churn)
    Rader som lagts till plus rader som tagits bort. Ett mått på hur mycket som förändras, inte på hur stor kodbasen är.
    Median
    Värdet i mitten när produkterna ställs i ordning. Används i stället för medelvärde eftersom enstaka ytterligheter annars drar siffran.
    Percentil
    Var ett värde ligger i ordningen. 95:e percentilen är det värde som 95 procent av pull requesterna ligger under.
    Winsorisering
    De största värdena dras ner till 95:e percentilen innan de räknas ihop. En enda mycket stor pull request kan annars ensam avgöra en produkts siffra. Värdet finns kvar i materialet, det blir bara inte större än gränsen.
    Konfidensintervall (KI 95 %)
    Spannet siffran rimligen ligger i. Ett 95-procentigt intervall skulle innehålla det sanna värdet i ungefär 19 fall av 20 om mätningen gjordes om.
    Samändring (lift)
    Hur ofta en pull request rör både gränssnitt och backend, delat med hur ofta det skulle ske om lagren ändrades oberoende av varandra. 1 betyder oberoende, under 1 att lagren ändras var för sig.
    Viktat stickprov
    I repon med väldigt många pull requests läste vi ett urval och räknade upp varje pull request till hur många den representerar, månad för månad.
    Cohens kappa
    Ett mått på hur väl två oberoende klassificeringar stämmer överens, justerat för hur ofta de skulle hamna lika av en slump. 1 är full överensstämmelse, 0 är slumpnivå.

    Vad ska vi göra tillsammans?

    KONTAKT

    Vill du jobba med oss?

    hello@wishyouwerehere.se

    Adress

    Kyrkogatan 26, 411 15 Göteborg

    Telefon

    Det går ofta fortast att bara ringa.

    [#] RING 070-949 87 60