Bedste fremgangsmåder til en ren og udførende vinkel applikation

Jeg har arbejdet med en storskala vinkel applikation hos Trade Me, New Zealand i et par år nu. I løbet af de sidste par år har vores team forfinet vores anvendelse både med hensyn til kodningsstandarder og ydeevne for at gøre det i sin bedst mulige tilstand.

Denne artikel skitserer den praksis, vi bruger i vores applikation og er relateret til Angular, Typescript, RxJs og @ ngrx / store. Vi gennemgår også nogle generelle retningslinjer for kodning for at hjælpe med at gøre applikationen renere.

1) trackBy

Når du bruger ngFor til at sløjfe over en matrix i skabeloner, skal du bruge den med en trackBy-funktion, der returnerer en unik identifikator for hvert element.

Hvorfor?

Når en matrix ændres, gengives Angular hele DOM-træet. Men hvis du bruger trackBy, vil Angular vide, hvilket element der er ændret og kun foretage DOM-ændringer for det pågældende element.

For en detaljeret forklaring herom henvises til denne artikel af Netanel Basal.

Før

  • {{item}}
  • Efter

    // i skabelonen
  • {{item}}
  • // i komponenten
    trackByFn (indeks, vare) {
       retur vare.id; // unikt id svarende til varen
    }

    2) const vs let

    Når du deklarerer variabler, skal du bruge const når værdien ikke skal tildeles igen.

    Hvorfor?

    Brug af let og const, hvor det er relevant, gør erklæringenes intention mere klar. Det vil også hjælpe med at identificere problemer, når en værdi tildeles til en konstant ved et uheld ved at kaste en kompileringstidsfejl. Det hjælper også med at forbedre kodens læsbarhed.

    Før

    lad bil = 'latterlig bil';
    lad myCar = `Min $ {bil}`;
    lad dinCar = `Din $ {bil};
    if (iHaveMoreThanOneCar) {
       myCar = `$ {myCar} s`;
    }
    if (youHaveMoreThanOneCar) {
       yourCar = `$ {youCar} s`;
    }

    Efter

    // værdien af ​​bilen ikke tildeles igen, så vi kan gøre det til en konst
    const car = 'latterlig bil';
    lad myCar = `Min $ {bil}`;
    lad dinCar = `Din $ {bil};
    if (iHaveMoreThanOneCar) {
       myCar = `$ {myCar} s`;
    }
    if (youHaveMoreThanOneCar) {
       yourCar = `$ {youCar} s`;
    }

    3) Rørbare operatører

    Brug pipeable operatører, når du bruger RxJs-operatører.

    Hvorfor?

    Rørbare operatører kan rystes med træ, hvilket betyder, at kun den kode, vi har brug for at udføre, vil blive inkluderet, når de importeres.

    Dette gør det også nemt at identificere ubrugte operatører i filerne.

    Bemærk: Dette har brug for Angular version 5.5+.

    Før

    import 'rxjs / add / operator / map';
    import 'rxjs / add / operator / take';
    iAmAnObservable
        .map (value => value.item)
        .Tage (1);

    Efter

    import {map, take} fra 'rxjs / operators';
    iAmAnObservable
        .rør(
           kort (værdi => værdi.item),
           tage (1)
         );

    4) Isoler API-hacks

    Ikke alle API'er er skudsikker - nogle gange er vi nødt til at tilføje en vis logik i koden for at kompensere for fejl i API'erne. I stedet for at have hacks i komponenter, hvor de er nødvendige, er det bedre at isolere dem et sted - som i en service og bruge tjenesten fra komponenten.

    Hvorfor?

    Dette hjælper med at holde hacks "tættere på API", så tæt på hvor netværksanmodningen er foretaget som muligt. På denne måde handler mindre af din kode med den ikke-hacket kode. Det er også et sted, hvor alle hacks bor, og det er lettere at finde dem. Når du løser fejlene i API'erne, er det lettere at kigge efter dem i én fil i stedet for at se efter hacks, der kunne være spredt over kodebasen.

    Du kan også oprette brugerdefinerede tags som API_FIX svarende til TODO og tag rettelserne med det, så det er lettere at finde.

    5) Abonner i skabelon

    Undgå at abonnere på observerbare ting fra komponenter, og abonner i stedet på observerbare ting fra skabelonen.

    Hvorfor?

    async-rør afmelder sig selv automatisk, og det gør koden enklere ved at fjerne behovet for manuelt at administrere abonnementer. Det reducerer også risikoen for ved et uheld at glemme at afmelde et abonnement på komponenten, hvilket kan forårsage en hukommelseslækage. Denne risiko kan også afhjælpes ved at bruge en fnugregel til at detektere ubeskrevne observerbare ting.

    Dette forhindrer også komponenter i at være tilstede og introducere fejl, hvor dataene bliver muterede uden for abonnementet.

    Før

    // skabelon

    {{textToDisplay}}

    // komponent
    iAmAnObservable
        .rør(
           kort (værdi => værdi.item),
           takeUntil (this._destroyed $)
         )
        .subscribe (item => this.textToDisplay = item);

    Efter

    // skabelon

    {{textToDisplay $ | async}}

    // komponent
    this.textToDisplay $ = iAmAnObservable
        .rør(
           kort (værdi => værdi.item)
         );

    6) Opryd abonnementer

    Når du abonnerer på observerbare ting, skal du altid sørge for at afmelde dem korrekt ved hjælp af operatører som take, takeUntil osv.

    Hvorfor?

    Undladelse af at afmelde sig fra observerbare ting vil føre til uønskede hukommelseslækager, da den observerbare strøm bliver åben, muligvis også efter at en komponent er blevet ødelagt / brugeren har navigeret til en anden side.

    Endnu bedre, lav en fnugregel for at opdage observerbare ting, der ikke er afmeldt.

    Før

    iAmAnObservable
        .rør(
           kort (værdi => værdi.item)
         )
        .subscribe (item => this.textToDisplay = item);

    Efter

    Brug af takeUntil, når du vil lytte til ændringerne, indtil en anden observerbar udsender en værdi:

    privat _ ødelagt $ = nyt Emne ();
    public ngOnInit (): ugyldig {
        iAmAnObservable
        .rør(
           kort (værdi => værdi.item)
          // Vi ønsker at lytte til iAmAnObservable, indtil komponenten er ødelagt,
           takeUntil (this._destroyed $)
         )
        .subscribe (item => this.textToDisplay = item);
    }
    public ngOnDestroy (): annulleret {
        this._destroyed $ .next ();
        this._destroyed $ .complete ();
    }

    Brug af et privat emne som dette er et mønster til at håndtere afmelding af mange observerbare ting i komponenten.

    Brug af take, når du kun vil have den første værdi, der udsendes af den observerbare:

    iAmAnObservable
        .rør(
           kort (værdi => værdi.item),
           tage (1),
           takeUntil (this._destroyed $)
        )
        .subscribe (item => this.textToDisplay = item);

    Bemærk brugen af ​​takeUntil med take her. Dette er for at undgå hukommelseslækager, der er forårsaget, når abonnementet ikke har modtaget en værdi, før komponenten blev ødelagt. Uden takeUntil her, ville abonnementet stadig hænge, ​​indtil det får den første værdi, men da komponenten allerede er blevet ødelagt, vil det aldrig få en værdi - hvilket fører til en hukommelseslækage.

    7) Brug passende operatører

    Når du bruger udfladning af operatører med dine observerbare ting, skal du bruge den relevante operatør til situationen.

    switchMap: når du vil ignorere de tidligere emissioner, når der er en ny emission

    mergeMap: når du samtidig vil håndtere alle emissioner

    concatMap: når du vil håndtere emissionerne efter hinanden, når de udsendes

    exhaustMap: når du vil annullere alle de nye emissioner, mens du behandler en tidligere emission

    For en mere detaljeret forklaring herom henvises til denne artikel af Nicholas Jamieson.

    Hvorfor?

    Brug af en enkelt operatør, når det er muligt, i stedet for at kæde sammen flere andre operatører for at opnå den samme effekt kan medføre, at mindre kode sendes til brugeren. Brug af forkerte operatører kan føre til uønsket opførsel, da forskellige operatører håndterer observerbare ting på forskellige måder.

    8) Lazy belastning

    Forsøg, når det er muligt, dovne indlæsning af modulerne i din vinkel applikation. Lat indlæsning er, når du kun indlæser noget, når det bruges, f.eks. Indlæsning af en komponent kun, når det skal ses.

    Hvorfor?

    Dette reducerer størrelsen på det program, der skal indlæses, og kan forbedre programmets starttid ved ikke at indlæse de moduler, der ikke bruges.

    Før

    // app.routing.ts
    {sti: 'ikke-doet-ladet', komponent: NotLazyLoadedComponent}

    Efter

    // app.routing.ts
    {
      sti: 'doven belastning'
      loadChildren: 'lazy-load.module # LazyLoadModule'
    }
    // lazy-load.module.ts
    import {NgModule} fra '@ vinkel / kerne';
    import {CommonModule} fra '@ vinkel / almindelig';
    import {RouterModule} fra '@ vinkel / router';
    import {LazyLoadComponent} fra './lazy-load.component';
    @NgModule ({
      import: [
        CommonModule,
        RouterModule.forChild ([
             {
                 sti: '',
                 komponent: LazyLoadComponent
             }
        ])
      ],
      erklæringer: [
        LazyLoadComponent
      ]
    })
    eksportklasse LazyModule {}

    9) Undgå at have abonnementer inde i abonnementer

    Undertiden kan du måske ønske, at værdier fra mere end en observerbar kan udføre en handling. I dette tilfælde skal du undgå at abonnere på en observerbar i abonnementsblokken til en anden observerbar. Brug i stedet passende kædeledere. Kædeledere kører på observerbare ting fra operatøren foran dem. Nogle kædeledere er: withLatestFrom, combineLatest osv.

    Før

    firstObservable $ .pipe (
       tage (1)
    )
    .subscribe (firstValue => {
        secondObservable $ .pipe (
            tage (1)
        )
        .subscribe (secondValue => {
            console.log (`Kombinerede værdier er: $ {firstValue} & $ {secondValue}`);
        });
    });

    Efter

    firstObservable $ .pipe (
        withLatestFrom (secondObservable $),
        først()
    )
    .subscribe (([[firstValue, secondValue]) => {
        console.log (`Kombinerede værdier er: $ {firstValue} & $ {secondValue}`);
    });

    Hvorfor?

    Kodelugt / læsbarhed / kompleksitet: Anvender ikke RxJs i sin fulde udstrækning, antyder, at udvikler ikke er bekendt med RxJs API-overfladeareal.

    Ydeevne: Hvis de observerbare ting er koldt, abonnerer det på firstObservable, venter på, at det er afsluttet, og start derefter det andet observerbare arbejde. Hvis dette var netværksanmodninger, ville det vises som synkron / vandfald.

    10) Undgå noget; skriv alt;

    Angiv altid variabler eller konstanter med en anden type end nogen anden.

    Hvorfor?

    Når deklarerer variabler eller konstanter i Typescript uden at indtaste, vil indtastningen af ​​variablen / konstanten blive afledt af den værdi, der får tildelt den. Dette vil forårsage utilsigtede problemer. Et klassisk eksempel er:

    const x = 1;
    const y = 'a';
    const z = x + y;
    console.log (`Værdi af z er: $ {z}`
    // Output
    Værdien af ​​z er 1a

    Dette kan forårsage uønskede problemer, når du forventer, at du også er et tal. Disse problemer kan undgås ved at indtaste variablerne korrekt.

    const x: tal = 1;
    const y: tal = 'a';
    const z: tal = x + y;
    // Dette giver en kompilationsfejl, der siger:
    Skriv '' a '' kan ikke tildeles type 'nummer'.
    const y: antal

    På denne måde kan vi undgå fejl, der er forårsaget af manglende typer.

    En anden fordel ved at have gode typografier i din ansøgning er, at det gør refactoring lettere og sikrere.

    Overvej dette eksempel:

    public ngOnInit (): ugyldig {
        lad myFlashObject = {
            navn: 'Mit seje navn',
            alder: 'Min seje alder',
            loc: 'Min seje placering'
        }
        this.processObject (myFlashObject);
    }
    public processObject (myObject: any): ugyldig {
        console.log (`Navn: $ {myObject.name}`);
        console.log (`Alder: $ {myObject.age}`);
        console.log (`Location: $ {myObject.loc}`);
    }
    // Output
    Navn: Mit seje navn
    Alder: Min seje alder
    Sted: Min seje placering

    Lad os sige, vi ønsker at omdøbe ejendommen loc til placering i myFlashObject:

    public ngOnInit (): ugyldig {
        lad myFlashObject = {
            navn: 'Mit seje navn',
            alder: 'Min seje alder',
            placering: 'Min seje placering'
        }
        this.processObject (myFlashObject);
    }
    public processObject (myObject: any): ugyldig {
        console.log (`Navn: $ {myObject.name}`);
        console.log (`Alder: $ {myObject.age}`);
        console.log (`Location: $ {myObject.loc}`);
    }
    // Output
    Navn: Mit seje navn
    Alder: Min seje alder
    Placering: udefineret

    Hvis vi ikke har en indtastning på myFlashObject, mener den, at egenskaben loc på myFlashObject bare er udefineret snarere end at det ikke er en gyldig egenskab.

    Hvis vi havde en maskinskrivning til myFlashObject, ville vi få en dejlig kompileringstidsfejl som vist nedenfor:

    type FlashObject = {
        navn: streng,
        alder: streng,
        placering: streng
    }
    public ngOnInit (): ugyldig {
        lad myFlashObject: FlashObject = {
            navn: 'Mit seje navn',
            alder: 'Min seje alder',
            // Kompilationsfejl
            Skriv '{name: string; alder: streng; loc: streng; } 'kan ikke tildeles typen' FlashObjectType '.
            Objekt bogstavelig kan kun specificere kendte egenskaber, og 'loc' findes ikke i typen 'FlashObjectType'.
            loc: 'Min seje placering'
        }
        this.processObject (myFlashObject);
    }
    public processObject (myObject: FlashObject): ugyldig {
        console.log (`Navn: $ {myObject.name}`);
        console.log (`Alder: $ {myObject.age}`)
        // Kompilationsfejl
        Egenskab 'loc' findes ikke på typen 'FlashObjectType'.
        console.log (`Location: $ {myObject.loc}`);
    }

    Hvis du starter et nyt projekt, er det værd at indstille streng: sandt i filen tsconfig.json for at aktivere alle strenge typekontrolindstillinger.

    11) Gør brug af lofteregler

    tslint har forskellige indbyggede indbygget allerede som ingen, ingen magi-numre, ingen konsol osv., som du kan konfigurere i din tslint.json til at håndhæve visse regler i din kodebase.

    Hvorfor?

    At have fyldingsregler på plads betyder, at du får en dejlig fejl, når du laver noget, som du ikke skulle være. Dette vil håndhæve konsistensen i din ansøgning og læsbarhed. Se her for flere regler, som du kan konfigurere.

    Nogle fnugregler leveres endda med rettelser til at løse fnugfejlen. Hvis du vil konfigurere din egen tilpassede fnugregel, kan du også gøre det. Se denne artikel af Craig Spence om, hvordan du skriver dine egne tilpassede fnugregler ved hjælp af TSQuery.

    Før

    public ngOnInit (): ugyldig {
        console.log ('Jeg er en fræk konsolelogbesked');
        console.warn ('Jeg er en fræk advarselsmeddelelse om konsol');
        console.error ('Jeg er en uartig konsolfejlmeddelelse');
    }
    // Output
    Ingen fejl, udskriver nedenunder i konsolvinduet:
    Jeg er en fræk konsolbesked
    Jeg er en fræk advarselsmeddelelse for konsol
    Jeg er en uartig konsolfejlmeddelelse

    Efter

    // tslint.json
    {
        "regler": {
            .......
            "ingen konsol": [
                 rigtigt,
                 "log", // ingen konsol.log tilladt
                 "advare" // ingen konsol. tilladt
            ]
       }
    }
    // ..component.ts
    public ngOnInit (): ugyldig {
        console.log ('Jeg er en fræk konsolelogbesked');
        console.warn ('Jeg er en fræk advarselsmeddelelse om konsol');
        console.error ('Jeg er en uartig konsolfejlmeddelelse');
    }
    // Output
    Fudfejl til console.log og console.warn-udsagn og ingen fejl for console.error, da det ikke er nævnt i config
    Opkald til 'console.log' er ikke tilladt.
    Opkald til 'konsol.warn' er ikke tilladt.

    12) Små genanvendelige komponenter

    Ekstraher de stykker, der kan genbruges i en komponent, og gør den til en ny. Gør komponenten så stum som muligt, da det vil gøre det arbejde i flere scenarier. At gøre en komponent stum betyder, at komponenten ikke har nogen speciel logik i sig og fungerer rent baseret på de input og output, der er leveret til den.

    Som en generel regel vil det sidste barn i komponenttræet være det dummeste af alle.

    Hvorfor?

    Genanvendelige komponenter reducerer duplikering af kode, hvilket gør det lettere at vedligeholde og foretage ændringer.

    Stomme komponenter er enklere, så de er mindre tilbøjelige til at have fejl. Stomme komponenter får dig til at tænke hårdere over den offentlige komponent-API og hjælpe med at sniffe blandede bekymringer.

    13) Komponenter skal kun beskæftige sig med displaylogik

    Undgå at have nogen anden logik end displaylogik i din komponent, når du kan, og få komponenten kun til at handle med displaylogikken.

    Hvorfor?

    Komponenter er designet til præsentationsformål og styrer, hvad visningen skal gøre. Enhver forretningslogik skal udtrækkes til dets egne metoder / tjenester, hvor det er relevant, og adskille forretningslogik fra visningslogik.

    Forretningslogik er normalt lettere at enhedsteste, når den udvindes til en tjeneste, og kan genbruges af alle andre komponenter, der har brug for den samme forretningslogik, der anvendes.

    14) Undgå lange metoder

    Lange metoder indikerer generelt, at de gør for mange ting. Prøv at bruge princippet om enkeltansvar. Selve metoden som helhed gør muligvis en ting, men inde i den er der et par andre operationer, der kunne ske. Vi kan udtrække disse metoder til deres egen metode og få dem til at gøre en ting hver og bruge dem i stedet.

    Hvorfor?

    Lange metoder er svære at læse, forstå og vedligeholde. De er også tilbøjelige til bugs, da ændring af én ting kan påvirke en masse andre ting i denne metode. De vanskeliggør også refactoring (hvilket er en nøglein ting i enhver applikation).

    Dette måles undertiden som ”cyklomatisk kompleksitet”. Der er også nogle TSLint-regler til at detektere cyklomatisk / kognitiv kompleksitet, som du kunne bruge i dit projekt til at undgå fejl og opdage kodens lugt og vedligeholdelsesproblemer.

    15) TØRR

    Gentag ikke dig selv. Sørg for, at du ikke har den samme kode, der er kopieret forskellige steder i kodebasen. Ekstraher den gentagne kode og brug den i stedet for den gentagne kode.

    Hvorfor?

    At have den samme kode flere steder betyder, at hvis vi ønsker at ændre logikken i den kode, er vi nødt til at gøre det flere steder. Dette gør det vanskeligt at vedligeholde og er også udsat for fejl, hvor vi kunne gå glip af at opdatere det i alle tilfælde. Det tager længere tid at foretage ændringer i logikken, og testning af det er også en langvarig proces.

    I disse tilfælde skal du trække den gentagne kode ud og bruge den i stedet. Dette betyder kun et sted at skifte og en ting at teste. At have mindre duplikatkode sendt til brugerne betyder, at applikationen vil være hurtigere.

    16) Tilføj cachemekanismer

    Når du foretager API-opkald, ændres svar fra nogle af dem ikke ofte. I disse tilfælde kan du tilføje en cache-mekanisme og gemme værdien fra API'en. Når der fremsættes en anden anmodning til det samme API, skal du kontrollere, om der er en værdi for det i cachen, og hvis det er tilfældet, så brug det. Ellers foretages API-opkald og cache resultatet.

    Hvis værdierne ændres, men ikke ofte, kan du introducere en cache-tid, hvor du kan kontrollere, hvornår den sidst blev cache, og beslutte, om du vil kalde API'en eller ej.

    Hvorfor?

    At have en cachemekanisme betyder at man undgår uønskede API-opkald. Ved kun at foretage API-opkald, når det kræves og undgå duplikering, forbedres applikationens hastighed, da vi ikke behøver at vente på netværket. Det betyder også, at vi ikke downloader de samme oplysninger igen og igen.

    17) Undgå logik i skabeloner

    Hvis du har nogen form for logik i dine skabeloner, selvom det er en enkel && klausul, er det godt at udpakke den ud i dens komponent.

    Hvorfor?

    At have logik i skabelonen betyder, at det ikke er muligt at enhedsteste den, og at den derfor er mere tilbøjelig til fejl, når skiftekoden ændres.

    Før

    // skabelon
    

    Status: Developer

    // komponent
    public ngOnInit (): ugyldig {
        this.role = 'udvikler';
    }

    Efter

    // skabelon
    

    Status: Udvikler

    // komponent
    public ngOnInit (): ugyldig {
        this.role = 'udvikler';
        this.showDeveloperStatus = sandt;
    }

    18) Strenge skal være sikre

    Hvis du har en variabel af typen streng, der kun kan have et sæt værdier, i stedet for at erklære det som en strengtype, kan du erklære listen over mulige værdier som typen.

    Hvorfor?

    Ved at angive variabeltypen korrekt, kan vi undgå fejl under skrivning af koden under kompileringstid snarere end under kørselstid.

    Før

    privat myStringValue: streng;
    if (itShouldHaveFirstValue) {
       myStringValue = 'Første';
    } andet {
       myStringValue = 'Andet'
    }

    Efter

    privat myStringValue: 'Første' | 'Anden';
    if (itShouldHaveFirstValue) {
       myStringValue = 'Første';
    } andet {
       myStringValue = 'Andet'
    }
    // Dette giver nedenstående fejl
    Type '"Andet"' kan ikke tildeles til at skrive '' Først '| "Anden"'
    (egenskab) AppComponent.myValue: "First" | "Anden"

    Større billede

    Statsledelse

    Overvej at bruge @ ngrx / store til at opretholde status for din applikation og @ ngrx / effects som bivirkningsmodel for butik. Tilstandsændringer er beskrevet af handlingerne, og ændringerne udføres af rene funktioner, der kaldes reduktionsmaskiner.

    Hvorfor?

    @ ngrx / store isolerer al tilstandsrelateret logik ét sted og gør den konsistent på tværs af applikationen. Det har også memoiseringsmekanisme på plads, når man får adgang til oplysningerne i butikken, der fører til en mere performant applikation. @ ngrx / store kombineret med ændringsdetekteringsstrategien for Angular fører til en hurtigere applikation.

    Uændret tilstand

    Når du bruger @ ngrx / store, skal du overveje at bruge ngrx-store-freeze for at gøre staten uforanderlig. ngrx-store-freeze forhindrer, at staten muteres ved at kaste en undtagelse. Dette undgår utilsigtet mutation af staten, hvilket fører til uønskede konsekvenser.

    Hvorfor?

    Mutationstilstand i komponenter fører til, at appen opfører sig inkonsekvent, afhængigt af rækkefølgen, komponenterne er indlæst. Det bryder den mentale model for reduxmønsteret. Ændringer kan ende med at blive tilsidesat, hvis butikstilstanden ændres og genudsendes. Adskillelse af bekymringer - komponenter er visningslag, de skal ikke vide, hvordan man ændrer tilstand.

    jest

    Jest er Facebooks enhedstestningsramme for JavaScript. Det gør enhedstest hurtigere ved at parallelisere testkørsler på tværs af kodebasen. Med sin overvågningstilstand køres kun testene, der er relateret til de foretagne ændringer, hvilket gør feedback loop til testning kortere. Jest giver også kodedækning af testene og understøttes på VS-kode og webstorm.

    Du kan bruge en forudindstilling til Jest, der vil gøre det meste af den tunge løft for dig, når du opsætter Jest i dit projekt.

    Karma

    Karma er en testløber udviklet af AngularJS team. Det kræver en rigtig browser / DOM for at køre testene. Det kan også køre på forskellige browsere. Jest har ikke brug for kromhovedløs / phantomjs for at køre testene, og den kører i ren node.

    Universel

    Hvis du ikke har gjort din app til en Universal-app, er det nu et godt tidspunkt at gøre det. Angular Universal giver dig mulighed for at køre din Angular-applikation på serveren og udføre server-side rendering (SSR), der serverer statiske forudindgivne html-sider. Dette gør appen super hurtig, da den viser indhold på skærmen næsten øjeblikkeligt uden at skulle vente på, at JS-bundter indlæses og analyseres, eller til Angular starter bootstrap.

    Det er også SEO venligt, da Angular Universal genererer statisk indhold og gør det lettere for webcrawlerne at indeksere applikationen og gøre det søgbart uden at udføre JavaScript.

    Hvorfor?

    Universal forbedrer ydeevnen for din applikation drastisk. Vi har for nylig opdateret vores ansøgning om gengivelse af serversiden, og belastningen på webstedet gik fra flere sekunder til titusinder af millisekunder !!

    Det tillader også, at dit websted vises korrekt i eksempler på sociale medier. Den første meningsfulde maling er virkelig hurtig og gør indholdet synligt for brugerne uden uønskede forsinkelser.

    Konklusion

    At opbygge applikationer er en konstant rejse, og der er altid plads til at forbedre tingene. Denne liste med optimeringer er et godt sted at starte, og at anvende disse mønstre konsekvent vil gøre dit team lykkeligt. Dine brugere vil også elske dig for den dejlige oplevelse med din mindre buggy og performante applikation.

    Tak fordi du læste! Hvis du nød denne artikel, er du velkommen til og hjælpe andre med at finde den. Tøv ikke med at dele dine tanker i kommentarfeltet nedenfor. Følg mig på Medium eller Twitter for flere artikler. Gode ​​kodning folkens !! ️