Twig: akselerer genereringen av malene
Webbyrå » Digitale nyheter » Twig: akselerer genereringen av malene

Twig: akselerer genereringen av malene

Nylig spurte jeg meg selv om å reflektere over løsningene som tilbys av Twig for å få tilgang til egenskapene til et objekt eller en matrise.

Tilgang til en egenskap til et objekt

Twig ble designet for å forenkle malene våre, både når det gjelder kode og når det gjelder renslighet. Den ble også designet for å tillate integratorer, personer som ikke alle har utviklingskunnskap, enkel tilgang til egenskapene til et objekt eller andre. Dette takket være en forenklet syntaks.

Først da, som utvikler fremfor alt, stilte jeg meg selv spørsmålet om hvordan twig gjorde for å bestemme hvilken metode for et objekt som skulle kalles.

Kvistsyntaks

I min følgende kode vil jeg anta at jeg bruker en klasse som nedenfor.

1
2
3
4
5
6
7
8
9
10
11
12
13
klasse Objekt
{
privat $navn;
offentlig $brukernavn;
offentlig funksjon getName() {
retur $ dette->navn;
}
offentlig funksjon get brukernavn() {
retur $ dette->brukernavn;
}
}

Dette er hvordan jeg vil kalle malen min fra en Symfony-kontroller.

1
2
3
offentlig funksjon indekshandling() {
retur matrise("gjenstand" => $objekt);
}

Så langt er alt klart. Objektet mitt ser akkurat ut som objektene jeg kan bruke i prosjektene mine.

Parsing erklæringer i kvist

1
{{ object.name }}

Fra nå av vil vi se hvordan Twig fungerer med samtalene våre. Her ber vi Twig ta verdien navn av objektet mitt, bortsett fra at for Twig som bare er et enkelt PHP-kall til slutt, er denne variabelen utilgjengelig. Twig har derfor lagt til en proxy for å abstrahere og se hvilke egenskaper og metoder som finnes.

Twig vil derfor be i rekkefølgen under om å foreta kontroller på objektet.

  1. Se om objekt er en matrise og hvis navn er en nøkkel;
  2. Se om objekt er et objekt og hvis navn er et tilgjengelig attributt;
  3. Se om objekt er et objekt og hvis navn er en metode;
  4. Se om objekt er et objekt og hvis getName er en metode;
  5. Se om objekt er et objekt og hvis er navn er en metode.
    Her, med notasjonen vi brukte, måtte vi vente på at den 4. betingelsen skulle komme til vårt element. Fordi navn er ikke et tilgjengelig attributt, og heller ikke en metode.

    1
    {{ object.username }}

I dette tilfellet prøver vi å få tilgang brukernavn. Dette attributtet er et offentlig attributt (i Symfony møtte jeg sjelden dette tilfellet). Vi må vente på den andre betingelsen.

1
{{ object.getName() }}

I vårt tredje tilfelle prøver jeg å ringe metoden min direkte. Jeg får resultatet fra den tredje tilstanden, som er en raskere tilstand.

1
{{ object.getUsername() }}

I vårt fjerde og siste tilfelle prøver jeg å bruke metoden min direkte. Jeg får resultatet fra den tredje tilstanden. I dette tilfellet setter jeg en ekstra betingelse for å få tilgang til verdien min.

Tolking av kvistmaler

Da jeg så på denne detaljen, tenkte jeg på hvordan utviklerne av Twig kunne ha gjort bufringen og kompileringen av malene. Det tok ikke lang tid før jeg kom til den konklusjonen at med den lille informasjonen og friheten som malbehandleren tilbyr, blir filene våre ganske enkelt transkribert til PHP på en lignende måte som vi helt kunne gjøre. Du kan også se selv ved å se i cache-mappen din.

1
2
{# Malgren #}
{{ object.name }}
Mal tolket i PHP
1
echo twig_escape_filter($this->env, $this->getAttribute((isset($context["object"]) ? $context["object"] : $this->getContext($context, "object")), "navn"), "html", null, sant);

Den første blokken samsvarer med det jeg noterte i kvistmalen min, den andre blokken samsvarer med den oversatte versjonen jeg fant i cache-mappen.

Vi legger merke til at grenen er oversatt til PHP, men at ingen elementer har tillatt den å forutsi hvilken metode som nøyaktig skal kalles. Metoden branch_escape_filter kan sammenlignes med en proxy. Det er i denne metoden vi bestemmer hvordan vi får tilgang til attributtet.

konklusjonen

Selv om kvistmaler automatisk bufres av Symfony, er det kun PHP-versjonen som beholdes, men uten tolkning av hva du ønsker å hente. I teorien er det derfor her midler til å optimalisere samtaler og genereringstid for malene våre fordi verifiseringen utføres ved hver samtale.

benchmark

Jeg ønsket fortsatt å ha en idé om gevinstene som kan oppnås ved å kalle metodene i stedet for " alias '.

I et første tilfelle kaller jeg en mal som kaller 10 ganger det samme objektet som igjen kaller 25 aliaser. Dette tilsvarer 250 anrop. Resultatene forstørres med løkken på 10 for å tillate nøyaktige beregninger av ytelsesforsterkningen.

For det andre kaller jeg en mal som kaller det samme objektet 10 ganger og som igjen kaller 25 metoder (alltid via samme proxy som for aliasene). Det er 250 igjen.

Jeg ringte disse malene 5 ganger hver.

Merk at alle anrop til malen som ringer til metoder er raskere. Ved å ta gjennomsnittene legger vi merke til at malen som bruker aliaser er lengre med 54,6 millisekunder (197.4 – 142.8).

Ved å gjøre en rask beregning, legger vi merke til at hvis vi reduserte det til et generelt tilfelle, er malen som bruker kall til metoder raskere i gjennomsnitt på samme data med omtrent 26.7 %. Dette kan være interessant når du ringer mange objekter.

Denne andre artikkelen følger et første innlegg som gir raske løsninger for å optimalisere genereringen av maler. Det er frukten av optimalisering som allerede er brukt på nettsteder i produksjon som hadde for høy ventetid.

Vi bruker alle inkluderer de Kvist å endre eller faktorisere våre synspunkter. Men kanskje du aldri forsto hvorfor vi hadde muligheten til å sende parametere, når en grunnleggende inkluderer arver variabler fra den gjeldende konteksten.

1
{% inkludere "ProjectMyBundle:Sub:template.html.twig" %}

Ofte bruker vi denne notasjonen. I dette tilfellet vil include gi en kopi av alle variablene våre til malen vår. Dette er ikke alltid nødvendig, og vi tar feil når vi kopierer alle variablene våre.

Interesse for det "bare" alternativet

Jeg lurte lenge på hva som var poenget med dette alternativet. Dessuten skal det sies at dokumentasjonen ikke gir mye informasjon. Du kan ta en titt på dokumentasjonen som følger med Twig. Det gir lite element, men det gir spesielt en ulempe og ingen fordel: å klare seg uten visse variabler. Slik sett er det ikke lønnsomt; hvorfor jeg burde klare meg uten noen variabler.

La oss implementere våre inkluderer! La oss si at grunnmalen vår har 5 variabler og jeg inkluderer en mal som bare bruker én av disse variablene, dette er notasjonen som vil være å foretrekke.

1
{% inkludere "ProjectMyBundle:Sub:template.html.twig" med bare {"object": myVar} %}

På denne måten vil bare en "objekt"-variabel være tilgjengelig i malen min. Dette begrenser kopieringen av ubrukelige variabler, og derfor av minneallokering (sparer tid og minneforbruk).

Kode og bruk tilfeller

1
2
3
4
5
6
// Kontroller
// Her genererer den en mal ved å sende en imponerende variabel (en samling) som inneholder alle objektene for en gitt tabell
offentlig funksjon testAction() {
$objekter = $ dette->beholder->få(«doctrine.orm.default_entity_manager»)->getRepository("ProjectMyBundle:Test")->finnAlle();
retur matrise("varer" => $objekter);
}

Vi går over samlingen vår og gir en mal hver iterasjon av samlingen til malen. I dette tilfellet, hver gang vi krever integrasjon av en mal, blir alle variablene kopiert, så vel som de som sendes med alternativet "med".. I vårt første tilfelle kunne vi godt tenke oss å få tilgang til samlingen vår (objekter) så vel som vår nåværende iterasjon (objekt).

1
2
3
4
5
{#Mal 1#}
{% forum objekt i objekter %}
{% inkludere "ProjectMyBundle:Sub:template.html.twig" med {"object": object} %}
{% endfor %}

I vårt andre tilfelle aktiverer jeg alternativet bare som lar deg kopiere bare variablene som sendes som parametere. Lett ?

1
2
3
4
5
{#Mal 2#}
{% forum objekt i objekter %}
{% inkludere "ProjectMyBundle:Sub:template.html.twig" med bare {"object": object} %}
{% endfor %}

benchmark

Jeg utførte testene med malene og koden gitt i delen ovenfor. Jeg utførte med 5 iterasjoner av hver mal, og husket å tømme cachen før hver første test.

Med denne grafen kan vi se at lastingen generelt er lengre for de som ikke bruker alternativet bare. Forskjellen har en tendens til å reduseres etter caching. Dette skyldes at malen min er liten og få variabler brukes. I mer anvendte tilfeller er det gevinster på opptil 30 %.

Her, hvis vi midler verdiene, når vi en gjennomsnittlig forskjell på 9 ms (48,6 – 39,6 = 9). Vi kan derfor beregne en tilnærmet gevinst på 20 % selv om dette skal settes i perspektiv i vårt tilfelle siden det første skuddet er fryktelig langt uten bruk av “ bare '.

★ ★ ★ ★ ★