JavaScript yürütmesini optimize edin

JavaScript genellikle görsel değişiklikleri tetikler. Bu işlem bazen doğrudan stil manipülasyonları üzerinden bazen de hesaplamalar aracılığıyla (ör. arama ya da veri sıralama) yapılır. Kötü zamanlanmış veya uzun çalışan JavaScript, performans sorunlarının yaygın bir nedenidir. Etkisini mümkün olduğunca en aza indirmeye çalışmalısınız.

Ali Lewis
Paul Lewis

JavaScript genellikle görsel değişiklikleri tetikler. Bu işlem bazen doğrudan stil manipülasyonlarıyla, bazen de hesaplamalar aracılığıyla (ör. arama ya da veri sıralama gibi) görsel değişikliklere yol açar. Kötü zamanlanmış veya uzun çalışan JavaScript, performans sorunlarının yaygın nedenlerinden biridir. Etkisini mümkün olduğunca en aza indirmeye çalışmalısınız.

Yazdığınız JavaScript, gerçekte yürütülen koddan farklı olmadığı için JavaScript performans profili oluşturma çalışması sanat eseri olabilir. Modern tarayıcılar, size mümkün olan en hızlı yürütmeyi sağlamak için JIT derleyicilerini, her türlü optimizasyon ve ipucunu kullanır. Bu da kodun dinamiklerini önemli ölçüde değiştirir.

Bununla birlikte, uygulamalarınızın JavaScript'i iyi bir şekilde yürütmesine yardımcı olmak için kesinlikle yapabileceğiniz bazı şeyler var.

Özet

  • Görsel güncellemeler için setTimeout veya setInterval kullanmaktan kaçının; bunun yerine her zaman requestAnimationFrame işlevini kullanın.
  • Uzun süre çalışan JavaScript'i ana iş parçacığından Web Çalışanlarına taşıyın.
  • Birkaç karede DOM değişiklikleri yapmak için mikro görevleri kullanın.
  • JavaScript'in etkisini değerlendirmek için Chrome Geliştirici Araçları Zaman Çizelgesi ve JavaScript Profil Aracı'nı kullanın.

Görsel değişiklikler için requestAnimationFrame kullanın

Ekranda görsel değişiklikler meydana geldiğinde tarayıcı için doğru zamanda (karenin hemen başında) işinizi yapmak istersiniz. JavaScript'inizin bir karenin başında çalışacağını garanti etmenin tek yolu requestAnimationFrame kullanmaktır.

/**
    * If run as a requestAnimationFrame callback, this
    * will be run at the start of the frame.
    */
function updateScreen(time) {
    // Make visual updates here.
}

requestAnimationFrame(updateScreen);

Çerçeveler veya örnekler, animasyonlar gibi görsel değişiklikler yapmak için setTimeout veya setInterval kullanabilirler ancak bu sorun, geri çağırma işleminin çerçeve içinde bir noktada, muhtemelen sonda gerçekleşmesi ve genellikle bir kareyi atlamamıza neden olarak duraklamaya yol açabilmesidir.

setTimeout, tarayıcının bir kareyi atlamasına neden oluyor.

Aslında jQuery, animate davranışı için setTimeout kullanıyordu. Sürüm 3'te requestAnimationFrame kullanılacak şekilde değiştirildi. jQuery'nin eski sürümünü kullanıyorsanız requestAnimationFrame kullanmak için yama uygulayabilirsiniz, bu da kesinlikle önerilir.

Karmaşıklığı azaltın veya Web İşçilerini kullanın

JavaScript, tarayıcının ana iş parçacığında, stil hesaplamaları, düzen ve çoğu durumda boyama ile birlikte çalışır. JavaScript'iniz uzun süre çalışırsa bu diğer görevleri engelleyerek karelerin kaçırılmasına neden olabilir.

JavaScript'in ne zaman ve ne kadar süreyle çalışacağı konusunda taktiksel olmalısınız. Örneğin, kaydırma gibi bir animasyondaysanız JavaScript'inizi 3-4 ms aralığında tutmaya çalışmanız önerilir. Bu süreyi aşarsanız çok fazla zaman kaybetme riskiniz olur. Boşta kalırsanız süre konusunda daha rahat olabilirsiniz.

Çoğu durumda, örneğin DOM erişimi gerektirmiyorsa, salt bilişimsel çalışmayı Web Çalışanları'na taşıyabilirsiniz. Sıralama veya arama gibi veri manipülasyonu ya da geçişi, yükleme ve model oluşturma gibi bu model için çoğu zaman uygundur.

var dataSortWorker = new Worker("sort-worker.js");
dataSortWorker.postMesssage(dataToSort);

// The main thread is now free to continue working on other things...

dataSortWorker.addEventListener('message', function(evt) {
    var sortedData = evt.data;
    // Update data on screen...
});

Tüm çalışmalar bu modele sığmayabilir: Web İşçilerinin DOM erişimi yoktur. Çalışmanızın ana iş parçacığında olması gereken durumlarda, büyük görevi her biri birkaç milisaniyeden uzun olmayan mikro görevlere ayırdığınız ve her karede requestAnimationFrame işleyicinin içinde çalışacağınız toplu işlem yaklaşımını düşünün.

Bu yaklaşımın kullanıcı deneyimi ve kullanıcı arayüzü sonuçları vardır ve bir ilerleme durumu veya etkinlik göstergesi kullanarak kullanıcının bir görevin işlenmekte olduğunu bilmesini sağlamanız gerekir. Her durumda bu yaklaşım, uygulamanızın ana ileti dizisini serbest bırakarak kullanıcı etkileşimlerine duyarlı olmasına yardımcı olur.

JavaScript'inizin "çerçeve vergisini" öğrenin

Bir çerçeveyi, kitaplığı veya kendi kodunuzu değerlendirirken JavaScript kodunu tek tek çalıştırmanın maliyetini de değerlendirmeniz önemlidir. Bu, özellikle geçiş veya kaydırma gibi performans açısından kritik animasyon işleri yaparken önemlidir.

Chrome Geliştirici Araçları'nın Performans paneli, JavaScript'inizin maliyetini ölçmenin en iyi yoludur. Genellikle aşağıdaki gibi alt düzey kayıtlar alırsınız:

Chrome Geliştirici Araçları'ndaki performans kaydı

Ana bölüm, tam olarak hangi işlevlerin çağrıldığını ve her birinin ne kadar sürdüğünü analiz edebilmeniz için JavaScript çağrılarının bir flame grafiğini sağlar.

Bu bilgiler sayesinde JavaScript'in uygulamanız üzerindeki performans etkisini değerlendirebilir ve işlevlerin yürütülmesinin çok uzun sürdüğü hotspot'ları bulup düzeltmeye başlayabilirsiniz. Daha önce de belirtildiği gibi, uzun süre çalışan JavaScript'i kaldırmaya çalışmanız veya bu mümkün değilse ana iş parçacığını serbest bırakarak diğer görevlere devam etmek için bir web çalışanına taşımanız gerekir.

Performans panelini nasıl kullanacağınızı öğrenmek için Çalışma Zamanı Performansını Analiz Etmeye Başlayın bölümüne bakın.

JavaScript'inizi mikro düzeyde optimize etmekten kaçının

Tarayıcının bir şeyin bir sürümünü diğerinden 100 kat daha hızlı çalıştırabildiğini bilmek güzel olabilir. Örneğin, bir öğenin offsetTop öğesini istemek getBoundingClientRect() hesaplamasından daha hızlıdır, ancak bunun gibi işlevleri kare başına yalnızca birkaç kez çağıracağınız hemen hemen her zaman doğrudur. Bu nedenle, normalde JavaScript'in performansının bu yönüne odaklanmak boşa çaba harcar. Genellikle yalnızca milisaniyeler içinde tasarruf edersiniz.

Bir oyun geliştiriyorsanız veya işlem maliyeti yüksek bir uygulama yapıyorsanız bu kılavuzda büyük olasılıkla bir istisna olursunuz. Çünkü genellikle tek bir kareye çok fazla hesaplama yaparsınız ve bu durumda her şey işe yarar.

Kısacası, mikro optimizasyonlar, oluşturduğunuz uygulama türüyle eşleşmeyeceğinden çok dikkatli olmalısınız.