Sunucu Zamanlaması ile Performansı Ölçme
Yayınlanan: 2022-03-10Herhangi bir performans optimizasyonu çalışması üstlenirken öğrendiğimiz ilk şeylerden biri, performansı iyileştirmeden önce onu ölçmeniz gerektiğidir. Bir şeyin çalışma hızını ölçmeden, yapılan değişikliklerin performansı iyileştirip iyileştirmediğini, hiçbir etkisinin olmadığını veya hatta işleri daha da kötüleştirdiğini söyleyemeyiz.
Birçoğumuz bir düzeyde bir performans sorunu üzerinde çalışmaya aşina olacağız. Bu, sayfanızdaki JavaScript'in neden yeterince kısa sürede devreye girmediğini veya resimlerin neden kötü otel wifi'sinde görünmesinin çok uzun sürdüğünü anlamaya çalışmak kadar basit bir şey olabilir. Bu tür soruların yanıtı genellikle çok tanıdık bir yerde bulunur: tarayıcınızın geliştirici araçları.
Yıllar içinde geliştirici araçları, uygulamalarımızın ön ucunda bu tür performans sorunlarını gidermemize yardımcı olmak için geliştirildi. Tarayıcılarda artık yerleşik performans denetimleri bile var. Bu, ön uç sorunlarının izlenmesine yardımcı olabilir, ancak bu denetimler tarayıcıda düzeltemeyeceğimiz başka bir yavaşlık kaynağı gösterebilir. Bu sorun, yavaş sunucu yanıt süreleridir.
“İlk Bayt Zamanı”
Sunucuda oluşturulması yavaş olan bir sayfayı geliştirmek için yapılabilecek çok az tarayıcı optimizasyonu vardır. Bu maliyet, tarayıcının dosya için talepte bulunması ile yanıtı alması arasında tahakkuk ettirilir. Geliştirici araçlarında ağ şelale grafiğinizi incelemek, bu gecikmeyi “Bekleme (TTFB)” kategorisi altında gösterecektir. Bu, tarayıcının istekte bulunmak ve yanıtı almak arasında ne kadar süre beklediğidir.
Performans açısından bu, İlk Bayt Süresi olarak bilinir - sunucunun tarayıcının çalışmaya başlayabileceği bir şey göndermeye başlaması için geçen süre. Bu bekleme süresi, sunucunun sayfayı oluşturmak için yapması gereken her şeyi kapsar. İsteği uygulamanın doğru bölümüne yönlendirmeyi, isteğin kimliğini doğrulamayı, veritabanları gibi arka uç sistemlerine birden çok çağrı yapmayı içerebilen tipik bir site için. Şablonlama sistemleri aracılığıyla içerik çalıştırmayı, üçüncü taraf hizmetlere API çağrıları yapmayı ve hatta e-posta gönderme veya görüntüleri yeniden boyutlandırma gibi şeyleri içerebilir. Sunucunun bir isteği tamamlamak için yaptığı herhangi bir çalışma, kullanıcının tarayıcısında deneyimlediği TTFB beklemesine sıkıştırılır.
Peki bu süreyi nasıl kısaltırız ve sayfayı kullanıcıya daha hızlı teslim etmeye nasıl başlarız? Bu büyük bir soru ve cevabı başvurunuza bağlı. Bu, performans optimizasyonunun kendisinin işidir. İlk yapmamız gereken, herhangi bir değişikliğin faydasının değerlendirilebilmesi için performansı ölçmektir .
Sunucu Zamanlama Başlığı
Sunucu Zamanlamasının işi, sunucunuzdaki etkinliği gerçekten zamanlamanıza yardımcı olmak değildir. Arka uç platformunuzun size sunduğu araç setini kullanarak zamanlamayı kendiniz yapmanız gerekir. Bunun yerine, Sunucu Zamanlamasının amacı, bu ölçümlerin tarayıcıya nasıl iletilebileceğini belirtmektir.
Bunun yapılma şekli çok basittir, kullanıcı için şeffaftır ve sayfa ağırlığınız üzerinde minimum etkiye sahiptir. Bilgi, basit bir HTTP yanıt başlığı seti olarak gönderilir.
Server-Timing: db;dur=123, tmpl;dur=56
Bu örnek, db
ve tmpl
adlı iki farklı zamanlama noktasını iletir. Bunlar, spesifikasyonun bir parçası değil - bunlar, bu durumda sırasıyla bazı veritabanı ve şablon zamanlamalarını temsil etmek için seçtiğimiz adlardır.
dur
özelliği, işlemin tamamlanması için geçen milisaniye sayısını belirtir. Developer Tools'un Network bölümündeki isteğe bakarsak zamanlamaların grafiğe eklendiğini görebiliriz.
Server-Timing
başlığı, virgülle ayrılmış birden çok ölçüm alabilir:
Server-Timing: metric, metric, metric
Her metrik üç olası özelliği belirtebilir
- Metrik için kısa bir isim (örneğimizdeki
db
gibi) - Milisaniye cinsinden bir süre (
dur=123
olarak ifade edilir) - Bir açıklama (
desc="My Description"
olarak ifade edilir)
Her özellik, sınırlayıcı olarak noktalı virgülle ayrılır. Örneğimize şu şekilde açıklamalar ekleyebiliriz:
Server-Timing: db;dur=123;desc="Database", tmpl;dur=56;desc="Template processing"
Gerekli olan tek özellik name
. dur
ve desc
isteğe bağlıdır ve gerektiğinde isteğe bağlı olarak kullanılabilir. Örneğin, diğerinde değil de bir sunucuda veya veri merkezinde meydana gelen bir zamanlama sorununda hata ayıklamanız gerekiyorsa, bu bilgiyi ilişkili bir zamanlama olmadan yanıta eklemek yararlı olabilir.
Server-Timing: datacenter;desc="East coast data center", db;dur=123;desc="Database", tmpl;dur=56;desc="Template processing”
Bu daha sonra zamanlamalarla birlikte ortaya çıkar.
Fark edebileceğiniz bir şey, zamanlama çubuklarının şelale deseninde görünmediğidir. Bunun nedeni, Sunucu Zamanlamasının zamanlama sırasını iletmeye çalışmaması, yalnızca ham metriklerin kendilerinin olmasıdır.
Sunucu Zamanlamasını Uygulama
Kendi uygulamanızdaki kesin uygulama, özel durumunuza bağlı olacaktır, ancak ilkeler aynıdır. Adımlar her zaman şöyle olacaktır:
- Zaman bazı işlemler
- Zamanlama sonuçlarını bir araya toplayın
- HTTP başlığını çıkar
Sözde kodda, yanıt üretimi şöyle görünebilir:
startTimer('db') getInfoFromDatabase() stopTimer('db') startTimer('geo') geolocatePostalAddressWithAPI('10 Downing Street, London, UK') endTimer('geo') outputHeader('Server-Timing', getTimerOutput())
Bu satırlar boyunca bir şeyler uygulamanın temelleri, herhangi bir dilde basit olmalıdır. Çok basit bir PHP uygulaması, zamanlama işlemleri için microtime()
işlevini kullanabilir ve aşağıdaki satırlar boyunca bir şeye benzeyebilir.
class Timers { private $timers = []; public function startTimer($name, $description = null) { $this->timers[$name] = [ 'start' => microtime(true), 'desc' => $description, ]; } public function endTimer($name) { $this->timers[$name]['end'] = microtime(true); } public function getTimers() { $metrics = []; if (count($this->timers)) { foreach($this->timers as $name => $timer) { $timeTaken = ($timer['end'] - $timer['start']) * 1000; $output = sprintf('%s;dur=%f', $name, $timeTaken); if ($timer['desc'] != null) { $output .= sprintf(';desc="%s"', addslashes($timer['desc'])); } $metrics[] = $output; } } return implode($metrics, ', '); } }
Bir test betiği onu aşağıdaki gibi kullanır, burada tamamlanması zaman alan bir işlemi simüle etmek için betiğin çalışmasında yapay olarak bir gecikme yaratmak için usleep()
işlevini kullanır.
$Timers = new Timers(); $Timers->startTimer('db'); usleep('200000'); $Timers->endTimer('db'); $Timers->startTimer('tpl', 'Templating'); usleep('300000'); $Timers->endTimer('tpl'); $Timers->startTimer('geo', 'Geocoding'); usleep('400000'); $Timers->endTimer('geo'); header('Server-Timing: '.$Timers->getTimers());
Bu kodu çalıştırmak şuna benzeyen bir başlık oluşturdu:
Server-Timing: db;dur=201.098919, tpl;dur=301.271915;desc="Templating", geo;dur=404.520988;desc="Geocoding"
Mevcut Uygulamalar
Sunucu Zamanlamasının ne kadar kullanışlı olduğunu düşünürsek, bulabildiğim nispeten az uygulama var. Sunucu zamanlaması NPM paketi, Düğüm projelerinden Sunucu Zamanlamasını kullanmanın uygun bir yolunu sunar.
Ara yazılım tabanlı bir PHP çerçevesi kullanıyorsanız tuupola/server-timing-middleware de kullanışlı bir seçenek sunar. Bunu birkaç aydır Notist'te prodüksiyonda kullanıyorum ve vahşi bir örnek görmek isterseniz her zaman birkaç temel zamanlamayı etkin bırakıyorum.
Tarayıcı desteği için gördüğüm en iyi şey Chrome DevTools'da ve bu makaledeki ekran görüntüleri için kullandığım şey bu.
Hususlar
Sunucu Zamanlamasının kendisi, kablo üzerinden geri gönderilen HTTP yanıtına çok az ek yük ekler. Başlık çok azdır ve yalnızca dahili kullanıcıları hedefleme endişesi olmadan gönderilmesi genellikle güvenlidir. Yine de, gereksiz ek yük eklememek için adları ve açıklamaları kısa tutmaya değer.
Daha fazla endişe kaynağı, sayfanızı veya uygulamanızı zamanlamak için sunucuda yapıyor olabileceğiniz fazladan çalışmadır. Ekstra zamanlama ve günlüğe kaydetmenin kendisi performans üzerinde bir etkiye sahip olabilir, bu nedenle gerektiğinde bunu açıp kapatmanın bir yolunu uygulamaya değer.
Bir Sunucu Zamanlama başlığı kullanmak, uygulamanızın hem ön ucundan hem de arka ucundan gelen tüm zamanlama bilgilerinin tek bir yerden erişilebilir olmasını sağlamanın harika bir yoludur. Uygulamanızın çok karmaşık olmaması koşuluyla, uygulaması kolay olabilir ve çok kısa bir süre içinde çalışmaya başlayabilirsiniz.
Sunucu Zamanlaması hakkında daha fazla bilgi edinmek isterseniz, aşağıdakileri deneyebilirsiniz:
- W3C Sunucu Zamanlaması Belirtimi
- Sunucu Zamanlaması'ndaki MDN sayfası, tarayıcı desteğinin örneklerine ve güncel ayrıntılarına sahiptir.
- BBC iPlayer ekibinden Sunucu Zamanlamasını kullanımlarıyla ilgili ilginç bir yazı.