Best practices voor een schone en performante hoekapplicatie

Ik werk nu al een paar jaar aan een grootschalige hoekapplicatie bij Trade Me, Nieuw-Zeeland. In de afgelopen jaren heeft ons team onze applicatie verfijnd, zowel op het gebied van codeerstandaarden als prestaties, zodat deze in de best mogelijke staat is.

Dit artikel schetst de praktijken die we in onze applicatie gebruiken en is gerelateerd aan Angular, Typescript, RxJ's en @ ngrx / store. We zullen ook enkele algemene coderingsrichtlijnen doornemen om de applicatie schoner te maken.

1) trackBy

Wanneer u ngFor gebruikt om over een array in sjablonen te lussen, gebruikt u deze met een trackBy-functie die voor elk item een ​​unieke identificatie retourneert.

Waarom?

Wanneer een array verandert, geeft Angular de hele DOM-structuur opnieuw weer. Maar als u trackBy gebruikt, weet Angular welk element is gewijzigd en worden alleen DOM-wijzigingen aangebracht voor dat specifieke element.

Raadpleeg dit artikel van Netanel Basal voor een gedetailleerde uitleg hierover.

Voordat

  • {{item}}
  • Na

    // in de sjabloon
  • {{item}}
  • // in de component
    trackByFn (index, item) {
       retour item.id; // unieke id die overeenkomt met het item
    }

    2) const vs let

    Gebruik bij het declareren van variabelen const wanneer de waarde niet opnieuw wordt toegewezen.

    Waarom?

    Het gebruik van let en const maakt waar nodig de bedoeling van de aangiften duidelijker. Het helpt ook bij het identificeren van problemen wanneer een waarde per ongeluk opnieuw wordt toegewezen aan een constante door een compilatietijdfout te maken. Het helpt ook de leesbaarheid van de code te verbeteren.

    Voordat

    let car = 'belachelijke auto';
    let myCar = `Mijn $ {car}`;
    let yourCar = `Uw $ {car};
    if (iHaveMoreThanOneCar) {
       myCar = `$ $ myCar} s`;
    }
    if (youHaveMoreThanOneCar) {
       yourCar = `$ $ youCar} s`;
    }

    Na

    // de waarde van auto wordt niet opnieuw toegewezen, dus we kunnen er een const van maken
    const car = 'belachelijke auto';
    let myCar = `Mijn $ {car}`;
    let yourCar = `Uw $ {car};
    if (iHaveMoreThanOneCar) {
       myCar = `$ $ myCar} s`;
    }
    if (youHaveMoreThanOneCar) {
       yourCar = `$ $ youCar} s`;
    }

    3) Leidingenoperatoren

    Gebruik pipeable-operators wanneer u RxJ's-operators gebruikt.

    Waarom?

    Pipeable-operatoren zijn boom-schudbaar, wat betekent dat alleen de code die we moeten uitvoeren zal worden opgenomen wanneer ze worden geïmporteerd.

    Dit maakt het ook gemakkelijk om ongebruikte operatoren in de bestanden te identificeren.

    Opmerking: dit heeft Angular versie 5.5+ nodig.

    Voordat

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

    Na

    import {map, take} van 'rxjs / operators';
    iAmAnObservable
        .pijp(
           map (waarde => waarde.item),
           nemen (1)
         );

    4) Isoleer API-hacks

    Niet alle API's zijn kogelvrij - soms moeten we wat logica in de code toevoegen om fouten in de API's te compenseren. In plaats van de hacks in componenten te hebben waar ze nodig zijn, is het beter om ze op één plaats te isoleren - zoals in een service en de service van de component te gebruiken.

    Waarom?

    Dit helpt de hacks "dichter bij de API" te houden, dus zo dicht mogelijk bij de plaats waar het netwerkverzoek wordt gedaan. Op deze manier heeft minder van uw code te maken met de niet-gehackte code. Het is ook een plek waar alle hacks live zijn en het is gemakkelijker om ze te vinden. Bij het oplossen van de bugs in de API's is het gemakkelijker om ze in één bestand te zoeken in plaats van te zoeken naar de hacks die over de codebase kunnen worden verspreid.

    Je kunt ook aangepaste tags maken zoals API_FIX vergelijkbaar met TODO en de fixes ermee taggen, zodat het gemakkelijker te vinden is.

    5) Abonneer u op een sjabloon

    Abonneer je niet op observables van componenten en abonneer je in plaats daarvan op de observables van de sjabloon.

    Waarom?

    async-pijpen melden zich automatisch uit en het maakt de code eenvoudiger doordat het niet langer nodig is om abonnementen handmatig te beheren. Het vermindert ook het risico dat u per ongeluk vergeet een abonnement op het abonnement op te zeggen, wat een geheugenlek zou veroorzaken. Dit risico kan ook worden beperkt door een lintregel te gebruiken om niet-geabonneerde waarnemingen te detecteren.

    Dit voorkomt ook dat componenten stateful zijn en bugs introduceren waarbij de gegevens buiten het abonnement worden gemuteerd.

    Voordat

    // sjabloon

    {{textToDisplay}}

    // component
    iAmAnObservable
        .pijp(
           map (waarde => waarde.item),
           takeUntil (this._destroyed $)
         )
        .subscribe (item => this.textToDisplay = item);

    Na

    // sjabloon

    {{textToDisplay $ | async}}

    // component
    this.textToDisplay $ = iAmAnObservable
        .pijp(
           map (waarde => waarde.item)
         );

    6) Abonnement opruimen

    Zorg er bij het abonneren op observables altijd voor dat u zich op de juiste manier afmeldt door operators te gebruiken zoals take, takeUntil, etc.

    Waarom?

    Als u zich niet afmeldt voor waarneembare gegevens, leidt dit tot ongewenste geheugenlekken wanneer de waarneembare stroom open blijft, mogelijk zelfs nadat een onderdeel is vernietigd / de gebruiker naar een andere pagina is genavigeerd.

    Nog beter, maak een lintregel voor het detecteren van waarneembare objecten die niet zijn afgemeld.

    Voordat

    iAmAnObservable
        .pijp(
           map (waarde => waarde.item)
         )
        .subscribe (item => this.textToDisplay = item);

    Na

    TakeUntil gebruiken wanneer je naar de veranderingen wilt luisteren totdat een andere waarneembare waarde uitzendt:

    private _destroyed $ = new Subject ();
    public ngOnInit (): void {
        iAmAnObservable
        .pijp(
           map (waarde => waarde.item)
          // We willen naar iAmAnObservable luisteren totdat het onderdeel is vernietigd,
           takeUntil (this._destroyed $)
         )
        .subscribe (item => this.textToDisplay = item);
    }
    public ngOnDestroy (): void {
        this._destroyed $ .next ();
        this._destroyed $ .complete ();
    }

    Het gebruik van een privé-onderwerp als dit is een patroon voor het beheren van het afmelden van veel observables in de component.

    Gebruik take als je alleen de eerste waarde wilt die wordt uitgezonden door het waarneembare:

    iAmAnObservable
        .pijp(
           map (waarde => waarde.item),
           nemen (1),
           takeUntil (this._destroyed $)
        )
        .subscribe (item => this.textToDisplay = item);

    Let op het gebruik van takeUntil met take hier. Dit om geheugenlekken te voorkomen die worden veroorzaakt wanneer het abonnement geen waarde heeft ontvangen voordat het onderdeel is vernietigd. Zonder takeUttil zou het abonnement blijven hangen totdat het de eerste waarde krijgt, maar omdat het component al vernietigd is, zal het nooit een waarde krijgen - wat leidt tot een geheugenlek.

    7) Gebruik geschikte operators

    Wanneer je afvlakoperators gebruikt met je observables, gebruik dan de juiste operator voor de situatie.

    switchMap: wanneer u de vorige emissies wilt negeren wanneer er een nieuwe emissie is

    mergeMap: wanneer u alle emissies tegelijkertijd wilt verwerken

    concatMap: wanneer u de emissies één voor één wilt behandelen wanneer ze worden uitgestoten

    exhaustMap: wanneer u alle nieuwe emissies wilt annuleren terwijl u een eerdere emissie verwerkt

    Raadpleeg dit artikel van Nicholas Jamieson voor een meer gedetailleerde uitleg hierover.

    Waarom?

    Wanneer mogelijk een enkele operator gebruikt in plaats van meerdere andere operators aan elkaar te koppelen om hetzelfde effect te bereiken, kan minder code naar de gebruiker worden verzonden. Het gebruik van de verkeerde operatoren kan leiden tot ongewenst gedrag, omdat verschillende operatoren op verschillende manieren met observables omgaan.

    8) Luie lading

    Probeer de modules in uw Angular-applicatie indien mogelijk lui te laden. Lui laden is wanneer u iets alleen laadt wanneer het wordt gebruikt, bijvoorbeeld een component alleen laden wanneer het moet worden gezien.

    Waarom?

    Dit verkleint de grootte van de te laden applicatie en kan de opstarttijd van de applicatie verbeteren door de niet-gebruikte modules niet te laden.

    Voordat

    // app.routing.ts
    {pad: 'niet-lui geladen', component: NotLazyLoadedComponent}

    Na

    // app.routing.ts
    {
      pad: 'lazy-load',
      loadChildren: 'lazy-load.module # LazyLoadModule'
    }
    // lazy-load.module.ts
    importeer {NgModule} uit '@ angular / core';
    import {CommonModule} uit '@ angular / common';
    import {RouterModule} uit '@ angular / router';
    import {LazyLoadComponent} uit './lazy-load.component';
    @NgModule ({
      invoer: [
        CommonModule,
        RouterModule.forChild ([
             {
                 pad: '',
                 component: LazyLoadComponent
             }
        ])
      ],
      verklaringen: [
        LazyLoadComponent
      ]
    })
    exportklasse LazyModule {}

    9) Vermijd abonnementen binnen abonnementen

    Soms wilt u waarden van meer dan één waarneembare om een ​​actie uit te voeren. Vermijd in dit geval een abonnement op een waarneembare in het inschrijfblok van een andere waarneembare. Gebruik in plaats daarvan geschikte kettingbedrijven. Chaining-operators werken op observables van de operator vóór hen. Sommige ketenoperators zijn: withLatestFrom, combinedLatest, etc.

    Voordat

    firstObservable $ .pipe (
       nemen (1)
    )
    .subscribe (firstValue => {
        secondObservable $ .pipe (
            nemen (1)
        )
        .subscribe (secondValue => {
            console.log (`Gecombineerde waarden zijn: $ {firstValue} & $ {secondValue}`);
        });
    });

    Na

    firstObservable $ .pipe (
        withLatestFrom (secondObservable $),
        eerste()
    )
    .subscribe (([firstValue, secondValue]) => {
        console.log (`Gecombineerde waarden zijn: $ {firstValue} & $ {secondValue}`);
    });

    Waarom?

    Codegeur / leesbaarheid / complexiteit: RxJ's niet volledig gebruiken, suggereert dat ontwikkelaar niet bekend is met het API-oppervlak van de RxJ's.

    Prestaties: als de waarnemers koud zijn, wordt deze geabonneerd op firstObservable, wacht totdat deze voltooid is en start dan het werk van de tweede waarneembare. Als dit netwerkverzoeken waren, zou dit worden weergegeven als synchroon / waterval.

    10) Vermijd elke; typ alles;

    Verklaar altijd variabelen of constanten met een ander type.

    Waarom?

    Bij het declareren van variabelen of constanten in Typescript zonder te typen, wordt het typen van de variabele / constante afgeleid door de waarde die eraan wordt toegewezen. Dit zal onbedoelde problemen veroorzaken. Een klassiek voorbeeld is:

    const x = 1;
    const y = 'a';
    const z = x + y;
    console.log (`Waarde van z is: $ {z}`
    // Uitgang
    De waarde van z is 1a

    Dit kan ongewenste problemen veroorzaken als u ook een nummer verwacht. Deze problemen kunnen worden voorkomen door de variabelen op de juiste manier te typen.

    const x: nummer = 1;
    const y: number = 'a';
    const z: nummer = x + y;
    // Dit geeft een compileerfout die zegt:
    Type '' a '' kan niet worden toegewezen aan type 'nummer'.
    const y: nummer

    Op deze manier kunnen we bugs voorkomen die worden veroorzaakt door ontbrekende typen.

    Een ander voordeel van goed typen in uw toepassing is dat refactoring eenvoudiger en veiliger wordt.

    Beschouw dit voorbeeld:

    public ngOnInit (): void {
        let myFlashObject = {
            naam: 'Mijn coole naam',
            leeftijd: 'Mijn coole leeftijd',
            loc: 'Mijn coole locatie'
        }
        this.processObject (myFlashObject);
    }
    public processObject (myObject: any): void {
        console.log (`Name: $ {myObject.name}`);
        console.log (`Age: $ {myObject.age}`);
        console.log (`Locatie: $ {myObject.loc}`);
    }
    // Uitgang
    Naam: mijn coole naam
    Leeftijd: mijn koele leeftijd
    Locatie: mijn coole locatie

    Laten we zeggen, we willen de eigenschap loc hernoemen naar locatie in myFlashObject:

    public ngOnInit (): void {
        let myFlashObject = {
            naam: 'Mijn coole naam',
            leeftijd: 'Mijn coole leeftijd',
            locatie: 'Mijn coole locatie'
        }
        this.processObject (myFlashObject);
    }
    public processObject (myObject: any): void {
        console.log (`Name: $ {myObject.name}`);
        console.log (`Age: $ {myObject.age}`);
        console.log (`Locatie: $ {myObject.loc}`);
    }
    // Uitgang
    Naam: mijn coole naam
    Leeftijd: mijn koele leeftijd
    Locatie: ongedefinieerd

    Als we geen typen op myFlashObject hebben, denkt het dat de eigenschap loc op myFlashObject gewoon niet is gedefinieerd in plaats van dat het geen geldige eigenschap is.

    Als we zouden typen voor myFlashObject, zouden we een mooie compilatietijdfout krijgen, zoals hieronder weergegeven:

    type FlashObject = {
        naam: string,
        leeftijd: string,
        locatie: string
    }
    public ngOnInit (): void {
        let myFlashObject: FlashObject = {
            naam: 'Mijn coole naam',
            leeftijd: 'Mijn coole leeftijd',
            // Compilatiefout
            Typ '{name: string; leeftijd: string; loc: string; } 'kan niet worden toegewezen aan het type' FlashObjectType '.
            Letterlijk object mag alleen bekende eigenschappen opgeven en 'loc' bestaat niet in het type 'FlashObjectType'.
            loc: 'Mijn coole locatie'
        }
        this.processObject (myFlashObject);
    }
    public processObject (myObject: FlashObject): void {
        console.log (`Name: $ {myObject.name}`);
        console.log (`Leeftijd: $ {myObject.age}`)
        // Compilatiefout
        Eigenschap 'loc' bestaat niet op type 'FlashObjectType'.
        console.log (`Locatie: $ {myObject.loc}`);
    }

    Als u een nieuw project start, is het de moeite waard om streng in te stellen: true in het bestand tsconfig.json om alle strikte opties voor tekstcontrole in te schakelen.

    11) Maak gebruik van pluisregels

    tslint heeft al verschillende opties ingebouwd zoals no-any, no-magic-nummers, no-console, enz. die u kunt configureren in uw tslint.json om bepaalde regels in uw codebasis af te dwingen.

    Waarom?

    Het hebben van pluisregels betekent dat je een mooie foutmelding krijgt wanneer je iets doet dat je niet zou moeten zijn. Dit zorgt voor consistentie in uw toepassing en leesbaarheid. Raadpleeg hier voor meer regels die u kunt configureren.

    Sommige pluisregels worden zelfs geleverd met oplossingen om de pluisfout op te lossen. Als u uw eigen aangepaste lintregel wilt configureren, kunt u dat ook doen. Raadpleeg dit artikel van Craig Spence voor het schrijven van uw eigen aangepaste lintregels met TSQuery.

    Voordat

    public ngOnInit (): void {
        console.log ('Ik ben een stout console-logbericht');
        console.warn ('Ik ben een ondeugende console waarschuwingsbericht');
        console.error ('Ik ben een ondeugende console-foutmelding');
    }
    // Uitgang
    Geen fouten, drukt het onderstaande af op consolevenster:
    Ik ben een stout consolebericht
    Ik ben een ondeugende console waarschuwingsbericht
    Ik ben een ondeugende console-foutmelding

    Na

    // tslint.json
    {
        "reglement": {
            .......
            "geen-console": [
                 waar,
                 "log", // geen console.log toegestaan
                 "warning" // geen console.warn toegestaan
            ]
       }
    }
    // ..component.ts
    public ngOnInit (): void {
        console.log ('Ik ben een stout console-logbericht');
        console.warn ('Ik ben een ondeugende console waarschuwingsbericht');
        console.error ('Ik ben een ondeugende console-foutmelding');
    }
    // Uitgang
    Lintfouten voor console.log- en console.warn-instructies en geen fout voor console.error omdat dit niet wordt vermeld in de configuratie
    Oproepen naar 'console.log' zijn niet toegestaan.
    Oproepen naar 'console.warn' zijn niet toegestaan.

    12) Kleine herbruikbare componenten

    Pak de stukken die in een component kunnen worden hergebruikt en maak er een nieuwe van. Maak het onderdeel zo dom mogelijk, want hierdoor werkt het in meer scenario's. Een component dom maken betekent dat de component geen speciale logica bevat en puur werkt op basis van de ingangen en uitgangen die eraan worden verstrekt.

    Als algemene regel geldt dat het laatste kind in de componentboom het domste van allemaal is.

    Waarom?

    Herbruikbare componenten verminderen duplicatie van code en maken het onderhoud en wijzigingen eenvoudiger.

    Domme componenten zijn eenvoudiger, dus ze hebben minder kans op bugs. Domme componenten zetten je aan het denken over de openbare component-API en helpen gemengde problemen op te lossen.

    13) Componenten moeten alleen omgaan met displaylogica

    Vermijd zoveel mogelijk andere logica dan displaylogica in uw component en laat de component alleen omgaan met de displaylogica.

    Waarom?

    Componenten zijn ontworpen voor presentatiedoeleinden en bepalen wat de weergave moet doen. Eventuele bedrijfslogica moet worden geëxtraheerd in zijn eigen methoden / diensten waar nodig, waarbij bedrijfslogica wordt gescheiden van viewlogica.

    Bedrijfslogica is meestal gemakkelijker om te testen wanneer deze naar een service wordt uitgepakt, en kan worden hergebruikt door andere componenten die dezelfde bedrijfslogica moeten toepassen.

    14) Vermijd lange methoden

    Lange methoden geven in het algemeen aan dat ze teveel dingen doen. Probeer het Single Responsibility Principle te gebruiken. De methode zelf als geheel kan één ding doen, maar er zijn een paar andere bewerkingen die kunnen gebeuren. We kunnen die methoden in hun eigen methode extraheren en ze één ding elk laten doen en in plaats daarvan gebruiken.

    Waarom?

    Lange methoden zijn moeilijk te lezen, te begrijpen en te onderhouden. Ze zijn ook gevoelig voor bugs, omdat het veranderen van één ding van invloed kan zijn op veel andere dingen in die methode. Ze maken ook refactoring (wat een sleutelbegrip in elke toepassing is) moeilijk.

    Dit wordt soms gemeten als "cyclomatische complexiteit". Er zijn ook enkele TSLint-regels om cyclomatische / cognitieve complexiteit te detecteren, die u in uw project kunt gebruiken om bugs te voorkomen en codegeuren en onderhoudsproblemen te detecteren.

    15) DROOG

    Herhaal jezelf niet. Zorg ervoor dat niet dezelfde code naar verschillende plaatsen in de codebase wordt gekopieerd. Pak de herhalende code uit en gebruik deze in plaats van de herhaalde code.

    Waarom?

    Het hebben van dezelfde code op meerdere plaatsen betekent dat als we de logica in die code willen veranderen, we het op meerdere plaatsen moeten doen. Dit maakt het moeilijk te onderhouden en is ook vatbaar voor bugs waarbij we het in alle gevallen zouden kunnen missen het bij te werken. Het duurt langer om wijzigingen aan te brengen in de logica en het testen ervan is ook een langdurig proces.

    Pak in dat geval de herhalende code uit en gebruik deze in plaats daarvan. Dit betekent slechts één plaats om te veranderen en één ding om te testen. Als er minder dubbele code naar gebruikers wordt verzonden, is de toepassing sneller.

    16) Voeg cachemechanismen toe

    Bij API-oproepen veranderen de antwoorden van sommige niet vaak. In die gevallen kunt u een cachemechanisme toevoegen en de waarde van de API opslaan. Wanneer een ander verzoek voor dezelfde API wordt gedaan, controleert u of er een waarde voor is in de cache en zo ja, gebruikt u deze. Maak anders de API-aanroep en cache het resultaat.

    Als de waarden veranderen, maar niet vaak, kunt u een cachetijd invoeren waarin u kunt controleren wanneer deze voor het laatst in de cache is opgeslagen en kunt beslissen of u de API wilt oproepen.

    Waarom?

    Het hebben van een cachemechanisme betekent het vermijden van ongewenste API-aanroepen. Door alleen de API-aanroepen uit te voeren wanneer dit nodig is en duplicatie te voorkomen, verbetert de snelheid van de applicatie omdat we niet op het netwerk hoeven te wachten. Het betekent ook dat we niet steeds dezelfde informatie downloaden.

    17) Vermijd logica in sjablonen

    Als u enige vorm van logica in uw sjablonen heeft, zelfs als het een eenvoudige &&-clausule is, is het goed om het uit te pakken in zijn component.

    Waarom?

    Het hebben van logica in de sjabloon betekent dat het niet mogelijk is om de eenheid te testen en daarom is het gevoeliger voor fouten bij het wijzigen van sjablooncode.

    Voordat

    // sjabloon
    

    Status: ontwikkelaar

    // component
    public ngOnInit (): void {
        this.role = 'ontwikkelaar';
    }

    Na

    // sjabloon
    

    Status: ontwikkelaar

    // component
    public ngOnInit (): void {
        this.role = 'ontwikkelaar';
        this.showDeveloperStatus = true;
    }

    18) Strings moeten veilig zijn

    Als u een variabele van het type string hebt dat alleen een set waarden kan hebben, in plaats van het als een stringtype te declareren, kunt u de lijst met mogelijke waarden als het type declareren.

    Waarom?

    Door het type van de variabele correct aan te geven, kunnen we fouten voorkomen tijdens het schrijven van de code tijdens het compileren in plaats van tijdens de uitvoering.

    Voordat

    privé myStringValue: string;
    if (itShouldHaveFirstValue) {
       myStringValue = 'First';
    } anders {
       myStringValue = 'Tweede'
    }

    Na

    privé myStringValue: 'First' | 'Tweede';
    if (itShouldHaveFirstValue) {
       myStringValue = 'First';
    } anders {
       myStringValue = 'Overig'
    }
    // Dit geeft de onderstaande foutmelding
    Type '"Other"' kan niet worden toegewezen aan type '"First" | "Tweede"'
    (eigenschap) AppComponent.myValue: "First" | "Tweede"

    Grotere geheel

    Staatsmanagement

    Overweeg het gebruik van @ ngrx / store voor het handhaven van de status van uw applicatie en @ ngrx / effects als het neveneffectmodel voor store. Statuswijzigingen worden beschreven door de acties en de wijzigingen worden uitgevoerd door pure functies die reducers worden genoemd.

    Waarom?

    @ ngrx / store isoleert alle toestandsgerelateerde logica op één plaats en zorgt voor consistentie in de toepassing. Het heeft ook een memo-mechanisme voor toegang tot de informatie in de winkel die leidt tot een performantere applicatie. @ ngrx / store gecombineerd met de veranderingsdetectiestrategie van Angular leidt tot een snellere toepassing.

    Onveranderlijke staat

    Als u @ ngrx / store gebruikt, kunt u overwegen ngrx-store-freeze te gebruiken om de status onveranderlijk te maken. ngrx-store-freeze voorkomt dat de status wordt gemuteerd door een uitzondering te maken. Dit voorkomt onbedoelde mutatie van de staat die leidt tot ongewenste gevolgen.

    Waarom?

    Muterende status in componenten leidt ertoe dat de app zich inconsistent gedraagt, afhankelijk van de volgorde waarin componenten worden geladen. Het breekt het mentale model van het redux-patroon. Wijzigingen kunnen worden opgeheven als de winkelstatus verandert en opnieuw wordt verzonden. Scheiding van zorgen - componenten zijn beeldlaag, ze moeten niet weten hoe ze van toestand kunnen veranderen.

    Grap

    Jest is het eenheidstestingskader van Facebook voor JavaScript. Het maakt het testen van eenheden sneller door testruns over de codebasis te parallelliseren. Met de horlogemodus worden alleen de tests met betrekking tot de gemaakte wijzigingen uitgevoerd, waardoor de feedbacklus voor het testen veel korter wordt. Jest biedt ook codedekking van de tests en wordt ondersteund door VS Code en Webstorm.

    U kunt een voorinstelling voor Jest gebruiken die het meeste zware werk voor u doet wanneer u Jest in uw project instelt.

    Karma

    Karma is een testloper ontwikkeld door AngularJS team. Het vereist een echte browser / DOM om de tests uit te voeren. Het kan ook op verschillende browsers worden uitgevoerd. Jest heeft geen Chrome headless / phantomjs nodig om de tests uit te voeren en het draait in pure Node.

    universeel

    Als u uw app niet tot een universele app heeft gemaakt, is dit een goed moment om het te doen. Met Angular Universal kunt u uw Angular-toepassing op de server uitvoeren en server-side rendering (SSR) uitvoeren die statische vooraf gerenderde html-pagina's bedient. Dit maakt de app supersnel omdat het vrijwel onmiddellijk inhoud op het scherm toont, zonder te hoeven wachten tot JS-bundels zijn geladen en ontleed, of voor Angular tot bootstrap.

    Het is ook SEO-vriendelijk, omdat Angular Universal statische inhoud genereert en het voor webcrawlers gemakkelijker maakt om de applicatie te indexeren en doorzoekbaar te maken zonder JavaScript uit te voeren.

    Waarom?

    Universal verbetert de prestaties van uw applicatie drastisch. We hebben onlangs onze applicatie bijgewerkt om server side rendering te doen en de laadtijd van de site ging van enkele seconden tot tientallen milliseconden !!

    Hiermee kan uw site ook correct worden weergegeven in voorbeeldfragmenten van sociale media. De eerste betekenisvolle verf is echt snel en maakt inhoud zichtbaar voor de gebruikers zonder ongewenste vertragingen.

    Gevolgtrekking

    Het bouwen van applicaties is een constante reis en er is altijd ruimte om dingen te verbeteren. Deze lijst met optimalisaties is een goede plek om te beginnen en het consequent toepassen van deze patronen zal uw team gelukkig maken. Uw gebruikers zullen ook van u houden voor de leuke ervaring met uw minder buggy en performante applicatie.

    Bedankt voor het lezen! Als je dit artikel leuk vond, aarzel dan niet om en anderen te helpen het te vinden. Aarzel niet om uw mening te geven in het commentaar hieronder. Volg mij op Medium of Twitter voor meer artikelen. Gelukkige coderingsmensen !! ️