Web uygulamanızı anlama
Yüksek performanslı web uygulamaları, mükemmel bir kullanıcı deneyimi için çok önemlidir. Web uygulamaları giderek daha karmaşık hale geldikçe, ilgi çekici bir deneyim oluşturmak için performans üzerindeki etkiyi anlamak çok önemlidir. Son birkaç yıldır, ağın performansını, yükleme sürelerini vb. analiz etmeye yardımcı olmak için tarayıcıda çeşitli farklı API'ler ortaya çıktı. Ancak bu API'ler, uygulamanızı yavaşlatan öğeyi bulmak için yeterli esneklikle ayrıntılı bilgi sağlamaz. Uygulamanızın zamanını nerelerde harcadığını belirlemek için web uygulamanızı enstrümante etmek üzere kullanabileceğiniz bir mekanizma sağlayan User Timing API'yi girin. Bu makalede, API'nin yanı sıra API'nin nasıl kullanılacağına dair örnekler ele alınmaktadır.
Ölçemediğiniz unsurları optimize edemezsiniz
Yavaş bir web uygulamasını hızlandırmanın ilk adımı, zamanın nerede harcandığını belirlemektir. JavaScript kodunun zaman etkisini ölçmek, performansı iyileştirmenin ilk adımı olan yoğun noktaları belirlemenin ideal yoludur. Neyse ki User Timing API, JavaScript'inizin farklı bölümlerine API çağrıları eklemenize ve ardından optimizasyona yardımcı olmak için kullanılabilecek ayrıntılı zamanlama verileri ayıklamanıza olanak tanır.
Yüksek çözünürlüklü zaman ve now()
Doğru zaman ölçümünün temel bir parçası hassasiyettir. Eskiden milisaniye ölçümüne dayalı bir zamanlama kullanıyorduk. Bu iyi bir şeydi ancak takılmayan 60 FPS'lik bir site oluşturmak için her karenin 16 milisaniyede çizilmesi gerekir. Bu nedenle, yalnızca milisaniye doğruluğuna sahip olduğunuzda iyi analizler için gereken hassasiyet eksiktir. Modern tarayıcılarda yerleşik olarak bulunan yeni bir zamanlama türü olan Yüksek Çözünürlüklü Zaman'ı girin. Yüksek Çözünürlüklü Zaman, mikrosaniye çözünürlüğünde doğruluk sağlayabilen kayan noktalı zaman damgaları sağlar. Bu, öncekinden bin kat daha iyidir.
Web uygulamanızdaki mevcut saati almak için Performans arayüzünün uzantı oluşturan now()
yöntemini çağırın. Aşağıdaki kodda bunun nasıl yapılacağı gösterilmektedir:
var myTime = window.performance.now();
Web uygulamanızın nasıl yüklendiğiyle ilgili çeşitli farklı zamanlar sağlayan PerformanceTiming adlı başka bir arayüz de vardır. now()
yöntemi, PerformanceTiming etkinliğindeki navigationStart
zamanının geçtiği süreyi döndürür.
DOMHighResTimeStamp türü
Geçmişte web uygulamalarını zamanlamaya çalışırken DOMTimeStamp döndüren Date.now()
gibi bir işlev kullanırdınız. DOMTimeStamp, değeri olarak milisaniye cinsinden bir tam sayı döndürür. Yüksek çözünürlüklü zaman için gereken daha yüksek doğruluğu sağlamak amacıyla DOMHighResTimeStamp adlı yeni bir tür kullanıma sunuldu. Bu tür, zamanı milisaniye cinsinden de döndüren bir kayan nokta değeridir. Ancak kayan nokta olduğundan değer, kesirli milisaniyeleri temsil edebilir ve bu nedenle milisaniyenin binde biri kadar doğruluk sağlayabilir.
Kullanıcı Zamanlaması Arayüzü
Yüksek çözünürlüklü zaman damgalarımız olduğuna göre, zamanlama bilgilerini almak için Kullanıcı Zamanlaması arayüzünü kullanalım.
Kullanıcı Zamanlaması arayüzü, uygulamamızdaki farklı yerlerdeki yöntemleri çağırmamıza olanak tanıyan işlevler sağlar. Bu işlevler, zaman harcama noktalarını izlememize olanak tanıyan Hansel ve Gretel tarzı bir içerik haritası sağlayabilir.
mark()
kullanılıyor
mark()
yöntemi, zamanlama analizi araç kitimizdeki ana araçtır. mark()
, bizim için bir zaman damgası depolar. mark()
parametresinin en kullanışlı özelliği, zaman damgasını adlandırabilmemizdir. API, adı ve zaman damgasını tek bir birim olarak hatırlar.
Uygulamanızın çeşitli yerlerinde mark()
çağrısı yaparak web uygulamanızda bu "noktaya" ulaşmanızın ne kadar sürdüğünü hesaplayabilirsiniz.
Spesifikasyonda, ilgi çekici olabilecek ve adından ne olduğu anlaşılan mark_fully_loaded
, mark_fully_visible
,mark_above_the_fold
gibi çeşitli marka adları önerilir.
Örneğin, aşağıdaki kodu kullanarak uygulamanın tamamen yüklendiği bir işaret belirleyebiliriz:
window.performance.mark('mark_fully_loaded');
Web uygulamamızda adlandırılmış işaretler ayarlayarak bir sürü zamanlama verisi toplayabilir ve uygulamanın ne zaman ne yaptığını öğrenmek için bu verileri dilediğimiz zaman analiz edebiliriz.
measure()
ile ölçümleri hesaplama
Birkaç zaman işareti belirledikten sonra, bunlar arasında geçen süreyi öğrenmek istersiniz. Bunu yapmak için measure()
yöntemini kullanırsınız.
measure()
yöntemi, işaretler arasındaki geçen süreyi hesaplar ve işaretiniz ile PerformanceTiming arayüzündeki bilinen etkinlik adlarından herhangi biri arasındaki süreyi de ölçebilir.
Örneğin, aşağıdaki gibi bir kod kullanarak DOM'un tamamlanmasından uygulama durumunuzun tamamen yüklenmesine kadar geçen süreyi hesaplayabilirsiniz:
window.performance.measure('measure_load_from_dom', 'domComplete', 'mark_fully_loaded');
measure()
işlevini çağırdığınızda, sonucu belirlediğiniz işaretlerden bağımsız olarak depolar. Böylece, daha sonra bu işaretleri alabilirsiniz. Uygulamanız çalışırken zamanları saklayarak uygulamanın duyarlı kalmasını sağlayabilirsiniz. Uygulamanız bir işi tamamladıktan sonra tüm verileri dışarı aktararak daha sonra analiz edebilirsiniz.
clearMarks()
ile işaretleri silme
Bazen, belirlediğiniz bir grup işareti kaldırmak yararlı olabilir. Örneğin, web uygulamanızda toplu çalıştırma yapıyor olabilirsiniz ve bu nedenle her çalıştırma işlemini sıfırdan başlatmak isteyebilirsiniz.
clearMarks()
tuşuna basarak belirlediğiniz işaretleri kolayca kaldırabilirsiniz.
Aşağıdaki örnek kod, mevcut tüm işaretlerinizi siler. Böylece, isterseniz zamanlama çalıştırması ayarlayabilirsiniz.
window.performance.clearMarks();
Elbette, tüm işaretlerinizi temizlemek istemeyeceğiniz bazı senaryolar vardır. Bu nedenle, belirli işaretleri kaldırmak istiyorsanız kaldırmak istediğiniz işaretin adını iletmeniz yeterlidir. Örneğin, aşağıdaki kod:
window.performance.clearMarks('mark_fully_loaded');
ilk örnekte belirlediğimiz işareti kaldırır ve belirlediğimiz diğer işaretleri olduğu gibi bırakır.
Aldığınız önlemleri de kaldırmak isteyebilirsiniz. Bunun için clearMeasures()
adlı bir yöntem vardır. clearMarks()
ile aynı şekilde çalışır ancak yaptığınız ölçümler üzerinde çalışır. Örneğin, aşağıdaki kod:
window.performance.clearMeasures('measure_load_from_dom');
yukarıdaki measure()
örneğinde yaptığımız ölçümü kaldırır. Tüm ölçümleri kaldırmak istiyorsanız clearMarks()
ile aynı şekilde çalışır. Yani clearMeasures()
'u bağımsız değişken olmadan çağırırsınız.
Zamanlama verilerini alma
İşaret belirlemek ve aralıkları ölçmek iyidir ancak bir noktada bazı analizler yapmak için bu zamanlama verilerine erişmek istersiniz. Bu da oldukça basittir. Tek yapmanız gereken PerformanceTimeline
arayüzünü kullanmaktır.
Örneğin, getEntriesByType()
yöntemi, tüm işaretleme zamanlarımızı veya tüm ölçüm zamanlarımızı liste halinde almamızı sağlar. Böylece, bu verileri iteratif olarak inceleyip işleyebiliriz. Listenin kronolojik sırayla döndürülmesinin avantajı, işaretleri web uygulamanızda isabet sırasına göre görebilmenizdir.
Aşağıdaki kod:
var items = window.performance.getEntriesByType('mark');
web uygulamamızda isabet alan tüm işaretlerin listesini döndürür. Bu kod:
var items = window.performance.getEntriesByType('measure');
bize yaptığımız tüm önlemlerin listesini döndürür.
Ayrıca, onlara verdiğiniz belirli adı kullanarak girişlerin listesini de alabilirsiniz. Örneğin, aşağıdaki kod:
var items = window.performance.getEntriesByName('mark_fully_loaded');
startTime
mülkünde "mark_fully_loaded" zaman damgasını içeren tek bir öğe içeren bir liste döndürür.
XHR isteğinin zamanlaması (örnek)
User Timing API hakkında iyi bir fikir sahibi olduğumuza göre, web uygulamamızdaki tüm XMLHttpRequests ne kadar sürdüğünü analiz etmek için bu API'yi kullanabiliriz.
Öncelikle, tüm send()
isteklerimizi, işaretleri ayarlayan bir işlev çağrısı gönderecek şekilde değiştiririz ve aynı zamanda başarı geri çağırma işlevlerimizi, başka bir işaret ayarlayan ve ardından isteğin ne kadar sürdüğünü ölçen bir işlev çağrısıyla değiştiririz.
Dolayısıyla, XMLHttpRequest'imiz genellikle şöyle görünür:
var myReq = new XMLHttpRequest();
myReq.open('GET', url, true);
myReq.onload = function(e) {
do_something(e.responseText);
}
myReq.send();
Örneğimizde, istek sayısını izlemek ve yapılan her istek için bir ölçüm depolamak amacıyla global bir sayaç ekleyeceğiz. Bunu yapmak için kullanacağınız kod şu şekildedir:
var reqCnt = 0;
var myReq = new XMLHttpRequest();
myReq.open('GET', url, true);
myReq.onload = function(e) {
window.performance.mark('mark_end_xhr');
reqCnt++;
window.performance.measure('measure_xhr_' + reqCnt, 'mark_start_xhr', 'mark_end_xhr');
do_something(e.responseText);
}
window.performance.mark('mark_start_xhr');
myReq.send();
Yukarıdaki kod, gönderdiğimiz her XMLHttpRequest için benzersiz bir ad değeri içeren bir ölçüm oluşturur. İstekler sırayla çalıştırılır. Sıralı olmayan istekleri işlemek için paralel isteklerin kodunun biraz daha karmaşık olması gerekir. Bu konuyu okuyucuya bırakıyoruz.
Web uygulaması bir dizi istek gönderdikten sonra aşağıdaki kodu kullanarak bunların tümünü konsola aktarabiliriz:
var items = window.performance.getEntriesByType('measure');
for (var i = 0; i < items.length; ++i) {
var req = items[i];
console.log('XHR ' + req.name + ' took ' + req.duration + 'ms');
}
Sonuç
User Timing API, web uygulamanızın herhangi bir yönüne uygulayabileceğiniz birçok mükemmel araç sunar. Uygulamanızdaki yoğun noktaları daraltmak için web uygulamanıza API çağrıları ekleyerek ve zaman harcama durumuna dair net bir resim oluşturmak için oluşturulan zamanlama verilerini son işleme tabi tutarak bunu kolayca yapabilirsiniz. Peki tarayıcınız bu API'yi desteklemiyorsa ne olur? Sorun değil. API'yi gerçekten iyi taklit eden ve webpagetest.org ile de iyi çalışan harika bir polyfill burada bulabilirsiniz. Daha ne bekliyorsunuz? Kullanıcı Zamanlaması API'sini uygulamalarınızda hemen deneyin. Uygulamalarınızı nasıl hızlandıracağınızı öğrenirsiniz ve kullanıcılarınız deneyimlerini çok daha iyi hale getirdiğiniz için size teşekkür eder.