Kullanıcı zamanlama API'si

Web uygulamanızı anlama

Alex Danilo

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. Geçtiğimiz birkaç yıl içinde tarayıcıda ağın performansını, yükleme sürelerini vb. analiz etmeye yardımcı olacak birçok farklı API göründü. Ancak bunlar, uygulamanızı yavaşlatan faktörleri bulmak için yeterli esneklikle birlikte ayrıntılı ayrıntılar vermeyebilir. Uygulamanızın nerede zaman harcadığını belirlemek üzere web uygulamanızı ayarlamak için 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 milisaniyelik doğruluk oranına sahip olduğunuzda iyi bir analiz için gereken hassasiyeti elde edemeyebilirsiniz. Modern tarayıcılarda yerleşik olarak bulunan yeni bir zamanlama türü olan Yüksek Çözünürlük Süresi'ni girin. Yüksek Çözünürlük Süresi, bize mikrosaniye çözünürlüğünde doğru olabilen kayan nokta zaman damgalarını sağlar. Bu, eskisinden bin kat daha iyidir.

Web uygulamanızdaki geçerli saati almak için now() yöntemini çağırın. Bu yöntem, Performans arayüzünün uzantısını oluşturur. 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 navigationStartzamanının geçtiği süreyi döndürür.

DOMHighResTimeStamp türü

Eskiden web uygulamalarını zamanlamaya çalışırken DOMTimeStamp döndüren Date.now() gibi bir değer kullanırsınız. DOMTimeStamp, değeri olarak milisaniye cinsinden 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ü

Artık 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() ile ilgili en kullanışlı özellik, zaman damgasını adlandırabilmemiz ve API'nin ad ile zaman damgasını tek bir birim olarak hatırlamasıdır.

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 istediğimiz zaman analiz edebiliriz.

Ölçümler measure() ile hesaplanıyor

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 uygulamanızın durumunun 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, ayarladığınız pek çok işaretten kurtulmanız yararlı olur. Örneğin, web uygulamanızda toplu çalıştırma yapıyorsanız 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 önlem kaldırılı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, verileri tekrar tekrar inceleyip işleyebiliriz. İşin güzel yanı, listelerin kronolojik olarak sıralanmasıdır. Böylece, işaretleri web uygulamanızda vurulma sıralarına göre görebilirsiniz.

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');

aldığımız tüm önlemlerin bir listesini bize 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, normalde XMLHttpRequest şö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 bunu kullanmak üzere genel 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 yaptıktan 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.