Så, du skal refaktorere en kodebase. Hva nå? - Lær deg å leve med jQuery

Her er Kristoffer Nordströms beste tips og råd for å holde liv i en gammel frontend.

- I hvilken ende begynner du å kutte opp grisen? 📸: Kristoffer Nordström
- I hvilken ende begynner du å kutte opp grisen? 📸: Kristoffer Nordström Vis mer

Så, du har nok en gang arvet en kodebase, et prosjekt som har gått over i vedlikehold.

Kanskje er koden ny, kanskje er den gammel? Kanskje den til og med er skrevet av deg selv! Uansett er den full av teknisk gjeld og med liten plan om å bli skrevet om i nærmeste fremtid…

Hvordan går du frem for å forbedre dette produktet, forbedre for sluttbrukeren og ikke minst for deg selv og andre utviklere som er tvunget til å jobbe med det?

Her vil du få noen tilnærminger som jeg vanligvis bruker selv når jeg befinner meg i den situasjonen. I hvilken ende begynner du å kutte opp grisen?

Lær å leve med parasitten

I utallige prosjekter jeg har vært en del av har det vært snakk om å skrive seg bort ifra jQuery. Heldigvis er disse prosjektene minkende. Men du støter ofte på dem når du minst venter det.

Jeg har ennå ikke sett et vellykket forsøk på å helt bli kvitt jQuery, uten å omskrive hele kodebasen. Lær deg heller å leve med jQuery-parasitten og gjør forbedringer på andre områder, det vil komme sluttbrukeren raskere til gode.

Med tiden vil du skrive om alt fra bunnen av uansett.

Kartlegg terrenget

Start med å kartlegge terrenget ordentlig:

Hvordan ser kodebasen ut, hvordan er koden satt sammen, hvilke tredjepartsavhengigheter har du, hvilke tester og kvalitetssikringer finnes?

Målbare mål

Lag målbare mål slik at du kan se at arbeidet ditt har en effekt.

Lighthouse fra Google er innebygd i Chrome Devtools, men finnes også som en CLI hvis du ønsker å automatisere overvåkingen. Her kan du få en baselinje for ytelse med responstider, Web Vitals, tilgjengelighet og søkemotoroptimalisering — og noen tips om hvordan du kan forbedre disse.

Testresultater fra Lighthouse, før refaktorering
Testresultater fra Lighthouse, før refaktorering Vis mer

Men du kan også gjerne sette andre mål, for eksempel hvor lang tid bygget ditt tar og dermed stjeler fra arbeidstiden din, antall tredjepartsavhengigheter og deres størrelse.

Blame game

“Det var en gang en CSS-selector…”*

Fra en 200 linjer lang CSS-selector
Fra en 200 linjer lang CSS-selector Vis mer

Når du møter en to hundre linjer lang CSS-selector er det lett å ty til stygge ord og umiddelbart skrive git blame.

Prøv å ikke skylde på mennesket bak koden — vi gjør alle så godt vi kan, under de forutsetninger vi har — sjansene er stor for at det er navnet ditt i margen. Det er få mennesker som alltid gjør 100% rett, for å lage 1 feil trenger du bare å gjøre 1 feil en gang.

I en kultur hvor man ikke har lov til å gjøre feil uten å bli hengt ut vil ingen innrømme en feil, da kan de allerede ha gjort enda mer skade enn om man turte å si ifra.

*Basert på en sann historie, én linje med kode og en halvhjertet code review genererte to hundre linjer med kompilert kode. Moralen i historien: undersøk hvilken effekt endringene dine har på din bundle.

Finn enkle feil

Hvis det ikke allerede er satt linting opp bør du få det på plass så snart som mulig. Det hjelper deg å finne enkle feil og unngå å introdusere nye. Fokuser på regler som bidrar til å forhindre enkle feil.

For JavaScript/TypeScript finnes det ESLint og for CSS finnes det Stylelint. På kort sikt kan dette skape bugs av tidligere “features”, men på litt lengre sikt hindrer det nye bugs i å oppstå.

Bli enige om en formatering i gruppen, eller om å følge en fastsatt standard for eksempel med Prettier som er et godt verktøy for å gjøre koden lettere å lese.

Finn og fjern duplikatkode med for eksempel jscpd:

npx jscpd --pattern "src/**/*.js"

Testing

Hvis du er heldig, har en snill sjel skrevet tester som lar deg gjøre endringer med selvtillit. Men sjansen er stor for at det ikke er en eneste test, eller kanskje bare en eneste…**

it('sums numbers', () => {
  expect(3).toEqual(3);
  expect(4).not.toEqual(3);
});

Stikk knyttneven i lommen og husk det med blame game.

Hvis du skal gjøre store omskrivinger av CSS kan du sette opp automatisk visuell testing med Playwright og Sitemapper for raskt å kontrollere uventede stilfeil.

const { test, expect } = require('@playwright/test');

let sites;

test.beforeAll(async () => {
  const Sitemapper = require('sitemapper');
  const sitemap = new Sitemapper({
    url: 'https://www.yourdomain.com/sitemap.xml'
  });
  sites = await sitemap.fetch().then(({ sites }) => sites);
});

test('sitemap visual comparison', async ({ page }) => {
  for (let site of sites) {
    await page.goto(site);
    expect(await page.screenshot()).toMatchSnapshot();
  }
});

Funksjonell testing med Playwright eller Cypress er også en effektiv måte å få på plass testing av kritiske deler av systemet som mangler testing fra før av.

**Basert på en sann historie. Moralen i historien: Undersøk testdekningen din og om de kritiske delene av systemet faktisk har tester.

Tilgjengelighet

Å sørge for tilgjengelighet er et must! Ofte reproduseres den samme feilen på tvers av flere deler av applikasjonen og ved å utføre automatisk analyse av alle sider kan du få en liste over hvilke feil som finnes, og spore hvordan endringene dine forbedrer opplevelsen for alle.

Du kan gjøre det med Pa11y CI, men ikke glem at disse analysene bare finner en liten del av alle feil:

pa11y-ci --sitemap http://www.yourdomain.com/sitemap.xml

Lavthengende frukt

Hvordan ser JavaScript- og CSS-bundles dine ut? Undersøk dem med for eksempel Webpack Bundle Analyzer for å se hvilke deler som er størst, slik at du kan finne ut hva som bør prioriteres for videre etterforskning.

Inneholder de unødvendig store tredjepartsavhengigheter eller pakker som er ukjente for deg? Da er det på tide at du erstatter dem med lettere pakker eller egenskrevet kode.

Gjør det til en vane å undersøke pakker med Bundlephobia før du tar ditt endelige valg om å legge til en ny import.

Nye filformater

Oppdatering av gamle filformater kan være en rask måte å forkorte responstidene.

Konverter skrifttype til WOFF2, video til WebM, og bilder til WebP og AVIF. Bare sørg for å ha en reserve for nettlesere som ennå ikke støtter disse formatene.

<picture>
  <source srcset="photo.avif" type="image/avif" />
  <source srcset="photo.webp" type="image/webp" />
  <img src="photo.jpg" alt="photo" />
</picture>

Latskap (en dødssynd?)

Pass på at ikke-kritiske bilder og andre mediefiler ikke lastes inn umiddelbart, men bare når de faktisk er nødvendige.

<picture>
  <source srcset="photo.avif" type="image/avif" />
  <source srcset="photo.webp" type="image/webp" />
  <img src="photo.jpg" alt="photo" loading="lazy" decoding="async" />
</picture>

Unngå at henting av skrifttype blokkerer rendring og vis i stedet en fallback.

:root {
  font-family: 'MyCustomSerif', serif;
  font-display: swap;
}

Hvis bygget ditt produserer store filer med JavaScript kan du dele disse opp i mindre biter slik at bitene kan lastes ned parallelt, bare når de trengs eller ikke i det hele tatt hvis de ikke brukes på en gitt side.

Et godt eksempel på dette er kart- eller videobiblioteker som både er store og ofte kun brukes på enkeltsider. Nøyaktig hvordan du gjør dette avhenger av hvilket byggesystem du bruker til å pakke sammen koden din (tips: søk etter code splitting og lazy loading).

Testresultater fra Lighthouse, etter refaktorisering***
Testresultater fra Lighthouse, etter refaktorisering*** Vis mer

Resultater

Husk å kontinuerlig se tilbake på dine tidligere fastsatte mål og målepunkter for å se og kunne sammenligne effekten endringene dine har!

Vis frem resultatene dine til teamet og feir den raskere responstiden, byggetid, tilgjengelighet eller hva du klarte å forbedre…

Belønning etter hardt arbeid
Belønning etter hardt arbeid Vis mer

Lykke til med refaktorering, jeg vet at du klarer det! 🤗

***Basert på en sann historie. Moralen i historien: Det er alltid håp om å blåse nytt liv i gamle kodebaser.