Twig: şablonlarının oluşturulmasını hızlandırın
Web ajansı » Dijital haberler » Twig: şablonlarının oluşturulmasını hızlandırın

Twig: şablonlarının oluşturulmasını hızlandırın

Son zamanlarda, bir nesnenin veya dizinin özelliklerine erişmek için Twig tarafından sunulan çözümler üzerinde düşünmeyi kendime sordum.

Bir nesnenin özelliğine erişme

Twig, şablonlarımızı hem kod hem de temizlik açısından basitleştirmek için tasarlandı. Ayrıca, entegratörlere, geliştirme bilgisine sahip olmayan kişilere, bir nesnenin veya diğerlerinin özelliklerine kolay erişim sağlamak için tasarlanmıştır. Bu, basitleştirilmiş bir sözdizimi sayesinde.

Ancak o zaman, her şeyden önce bir geliştirici olarak, bir nesnenin hangi yönteminin çağrılması gerektiğini belirlemek için kendime twig'in ne durumda olduğu sorusunu sordum.

Dal Sözdizimi

Aşağıdaki kodumda, aşağıdaki gibi bir sınıf kullandığımı varsayacağım.

1
2
3
4
5
6
7
8
9
10
11
12
13
sınıf nesne
{
özel $İsim;
halka açık $kullanıcı adı;
halka açık işlev getName() {
dönüş bu $->isim;
}
halka açık işlev getKullanıcı adı() {
dönüş bu $->kullanıcı adı;
}
}

Şablonumu bir Symfony denetleyicisinden bu şekilde arayacağım.

1
2
3
halka açık işlev indeksAksiyon() {
dönüş dizi("nesne" => $nesne);
}

Şimdiye kadar her şey açık. Nesnem tam olarak projelerimde kullanabileceğim nesnelere benziyor.

Twig'de bildirimleri ayrıştırma

1
{{ object.name }}

Bundan sonra, Twig'in çağrılarımızla nasıl çalıştığını göreceğiz. Burada Twig'den değeri almasını istiyoruz. isim Sonunda sadece basit bir PHP çağrısı olan Twig için bu değişkene erişilemez. Bu nedenle Twig, soyutlamak ve hangi özelliklerin ve yöntemlerin mevcut olduğunu görmek için bir proxy ekledi.

Bu nedenle Twig, aşağıdaki sırayla nesne üzerinde kontroller yapmasını isteyecektir.

  1. Eğer görürsen nesne bir dizidir ve eğer isim bir anahtardır;
  2. Eğer görürsen nesne bir nesnedir ve eğer isim erişilebilir bir niteliktir;
  3. Eğer görürsen nesne bir nesnedir ve eğer isim bir yöntemdir;
  4. Eğer görürsen nesne bir nesnedir ve eğer getName bir yöntemdir;
  5. Eğer görürsen nesne bir nesnedir ve eğer isName bir yöntemdir.
    Burada kullandığımız notasyon ile elementimize 4. koşulun gelmesini beklemek zorunda kaldık. Çünkü isim erişilebilir bir öznitelik veya bir yöntem değildir.

    1
    {{ object.username }}

Bu durumda, erişmeye çalışıyoruz kullanıcı adı. Bu öznitelik genel bir özniteliktir (Symfony'de bu durumla nadiren karşılaştım). 2. şartı beklemek zorundayız.

1
{{ object.getName() }}

Üçüncü durumumuzda, yöntemimi doğrudan çağırmaya çalışıyorum. Sonucumu daha hızlı olan üçüncü koşuldan alıyorum.

1
{{ object.getUsername() }}

Dördüncü ve son durumumuzda, yöntemimi doğrudan kullanmaya çalışıyorum. Sonucumu üçüncü koşuldan alıyorum. Bu durumda, değerime erişmek için ek bir koşul koyuyorum.

Twig şablonlarını yorumlama

Bu detaya baktığımda, Twig geliştiricilerinin şablonların önbelleğe alınmasını ve derlenmesini nasıl yapmış olabileceğini düşündüm. Şablon yöneticisinin sunduğu az bilgi ve özgürlükle, dosyalarımızın tamamen yapabildiğimize benzer bir şekilde PHP'ye kopyalandığı sonucuna varmam uzun sürmedi. Önbellek klasörünüze bakarak kendiniz de görebilirsiniz.

1
2
{# Şablon dalı #}
{{ object.name }}
PHP'de yorumlanan şablon
1
echo twig_escape_filter($this->env, $this->getAttribute((isset($context["nesne"]) ? $bağlam["nesne"] : $this->getContext($bağlam, "nesne")), “isim”), “html”, boş, doğru);

İlk blok dal şablonumda not ettiğimle eşleşiyor, ikinci blok önbellek klasöründe bulduğum çevrilmiş sürümle eşleşiyor.

Dalın PHP'ye çevrildiğini ancak hiçbir öğenin tam olarak hangi yöntemin çağrılması gerektiğini tahmin etmesine izin vermediğini not ediyoruz. yöntem şube_escape_filter bir proxy ile karşılaştırılabilir. Özniteliğe nasıl erişeceğimizi bu yöntemde belirleyeceğiz.

Sonuç

Dal şablonları Symfony tarafından otomatik olarak önbelleğe alınsa da, yalnızca PHP sürümü tutulur, ancak ne almak istediğinizi yorumlamadan tutulur. Teorik olarak, bu nedenle burada, aramaları ve şablonlarımızın üretim süresini optimize etmenin bir yolu vardır, çünkü doğrulama her aramada gerçekleştirilir.

kıyaslama

Yine de "" yerine yöntemleri çağırarak elde edilebilecek kazanımlar hakkında bir fikir sahibi olmak istedim. takma ad '.

İlk durumda, sırayla 10 takma ad çağıran aynı nesneyi 25 kez arayacak bir şablon çağırırım. Bu, 250 aramayı temsil eder. Sonuçlar, performans kazancına ilişkin doğru hesaplamalara izin vermek için 10'luk döngü ile büyütülür.

İkinci olarak, aynı nesneyi 10 kez arayacak ve sırayla 25 yöntemi çağıracak bir şablon çağırıyorum (her zaman takma adlar için aynı proxy aracılığıyla). Yine 250 oldu.

Bu şablonların her birini 5 kez aradım.

Yöntemlere çağrı yapan şablona yapılan tüm çağrıların daha hızlı olduğunu unutmayın. Ortalamaları alarak, takma ad kullanan şablonun 54,6 milisaniye (197.4 – 142.8) daha uzun olduğunu fark ettik.

Hızlı bir hesaplama yaparak, bunu genel bir duruma indirgersek, yöntem çağrılarını kullanan şablonun aynı veriler üzerinde ortalama olarak yaklaşık %26.7 daha hızlı olduğunu fark ettik. Bu, nesnelere çok sayıda çağrı yapıldığında ilgi çekici olabilir.

Bu ikinci makale, şablon oluşturmayı optimize etmek için hızlı çözümler sunan ilk gönderiyi takip ediyor. Gecikme oranı çok yüksek olan üretimdeki sitelerde halihazırda kullanılan optimizasyonun meyvesidir.

hepsini kullanıyoruz içerir de Dal görüşlerimizi değiştirmek veya çarpanlara ayırmak. Ancak, temel bir içerme mevcut bağlamdan değişkenleri devraldığında, neden parametreleri iletme yeteneğine sahip olduğumuzu belki de asla anlamadınız.

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

Genellikle bu gösterimi kullanırız. Bu durumda, içerme, tüm değişkenlerimizin bir kopyasını şablonumuza verecektir. Bu her zaman gerekli değildir ve tüm değişkenlerimizi kopyalamakla hata ederiz.

"Yalnızca" seçeneğin ilgisi

Bu seçeneğin amacının ne olduğunu uzun süre merak ettim. Ayrıca belgelerin çok fazla bilgi vermediğini de söylemek gerekiyor. Twig içerir belgelerine bir göz atabilirsiniz. Çok az unsur sağlar, ancak özellikle bir dezavantaj sağlar ve hiçbir avantaj sağlamaz: belirli değişkenler olmadan yapmak. Bu şekilde bakıldığında karlı değildir; neden bazı değişkenler olmadan yapmalıyım.

İçerdiklerimizi uygulayalım! Diyelim ki temel şablonumuzda 5 değişken var ve bu değişkenlerden yalnızca birini kullanan bir şablon ekliyorum, bu tercih edilecek notasyondur.

1
{% dahil Yalnızca %} {"object": myVar} ile "ProjectMyBundle:Sub:template.html.twig"

Bu şekilde, şablonumda yalnızca bir "nesne" değişkeni mevcut olacaktır. Bu, gereksiz değişkenlerin ve dolayısıyla bellek tahsisinin kopyalanmasını sınırlar (zamandan ve bellek tüketiminden tasarruf).

Kod ve kullanım örnekleri

1
2
3
4
5
6
// Denetleyici
// Burada, belirli bir tablo için tüm nesneleri içeren etkileyici bir değişken (bir koleksiyon) ileterek bir şablon oluşturur.
halka açık işlev testAksiyonu() {
$nesneler = bu $->konteyner->al("doctrine.orm.default_entity_manager")->getRepository("ProjectMyBundle:Test")->bul();
dönüş dizi("öğeler" => $nesneler);
}

Koleksiyonumuzun üzerinden geçiyoruz ve koleksiyonun her yinelemesinde şablona bir şablon veriyoruz. Bu durumda, bir şablonun entegrasyonunu her çağırdığımızda, tüm değişkenler ve birlikte geçirilenler kopyalanır. "ile" seçeneği. İlk durumumuzda, koleksiyonumuza (nesneler) ve mevcut yinelememize (nesne) erişmeyi çok iyi hayal edebiliriz.

1
2
3
4
5
{#Şablon 1#}
{% için %} nesnelerindeki nesne
{% dahil {"object": object} %} ile "ProjectMyBundle:Sub:template.html.twig"
{% sonu %}

İkinci durumumuzda, seçeneği etkinleştiriyorum bir tek bu, yalnızca parametre olarak iletilen değişkenleri kopyalamanıza izin verir. Kolay ?

1
2
3
4
5
{#Şablon 2#}
{% için %} nesnelerindeki nesne
{% dahil Yalnızca %} {"object": object} ile "ProjectMyBundle:Sub:template.html.twig"
{% sonu %}

kıyaslama

Testleri yukarıdaki bölümde verilen şablonlar ve kodlar ile gerçekleştirdim. Her ilk testten önce önbelleği boşaltmayı hatırlayarak, her şablonun 5 yinelemesiyle performans gösterdim.

Bu grafikle, seçeneği kullanmayanlar için yüklemenin genellikle daha uzun olduğunu görebiliriz. bir tek. Önbelleğe alma işleminden sonra fark azalma eğilimindedir. Bunun nedeni, şablonumun küçük olması ve az sayıda değişken kullanılmasıdır. Daha fazla uygulanan durumlarda ise %30'a varan kazançlar söz konusudur.

Burada değerlerin ortalamasını alırsak ortalama 9 ms (48,6 – 39,6 = 9) farka ulaşıyoruz. Bu nedenle, bizim durumumuzda perspektife oturtulacak olsa bile, yaklaşık %20'lik bir kazanç hesaplayabiliriz, çünkü ilk atış "" kullanılmadan çok uzundur. bir tek '.

★ ★ ★ ★ ★