JavaScript yürütmesini optimize edin

JavaScript genellikle görsel değişiklikleri tetikler. Bu, bazen doğrudan stil değişiklikleri, bazen de verileri arama veya sıralama gibi görsel değişikliklerle sonuçlanan hesaplamalar yoluyla yapılır. Yanlış zamanlanmış veya uzun süre çalışan JavaScript, performans sorunlarının yaygın bir nedenidir. Mümkün olduğunda bu değişikliğin etkisini en aza indirmeye çalışmalısınız.

Paul Lewis

JavaScript genellikle görsel değişiklikleri tetikler. Bu, bazen doğrudan stil değişiklikleri, bazen de verileri arama veya sıralama gibi görsel değişikliklerle sonuçlanan hesaplamalar yoluyla yapılır. Kötü zamanlanmış veya uzun süre çalışan JavaScript, performans sorunlarının yaygın bir nedenidir. Mümkün olduğunda bu değişikliğin etkisini en aza indirmeye çalışmalısınız.

Yazdığınız JavaScript, aslında yürütülen koda hiç benzemediğinden JavaScript performansı profillemesi bir sanat dalı olabilir. Modern tarayıcılar, size mümkün olan en hızlı yürütmeyi sunmak için JIT derleyicileri ve her türlü optimizasyonu ve hileyi kullanır. Bu da kodun dinamiklerini önemli ölçüde değiştirir.

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

Özet

  • Görsel güncellemeler için setTimeout veya setInterval işlevlerini 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örevler kullanın.
  • JavaScript'in etkisini değerlendirmek için Chrome Geliştirici Araçları'nın Zaman Çizelgesi ve JavaScript Profilleyici'yi kullanın.

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

Ekranda görsel değişiklikler gerçekleşirken çalışmanızı tarayıcı için doğru zamanda, yani çerçevenin tam başında 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, animasyon gibi görsel değişiklikler yapmak için setTimeout veya setInterval kullanabilir. Ancak bu durumda geri çağırma işlevi, karenin bir noktasında (muhtemelen en sonunda) çalışır. Bu da genellikle bir kareyi kaçırmamıza neden olarak takılmalara yol açabilir.

setTimeout, tarayıcının bir kareyi kaçırmasına neden oluyor.

Aslında jQuery, animate davranışı için setTimeout kullanıyordu. 3. sürümde requestAnimationFrame olarak değiştirildi. jQuery'nin eski bir sürümünü kullanıyorsanız requestAnimationFrame kullanacak şekilde düzeltme yapabilirsiniz. Bunu yapmanız önemle tavsiye edilir.

Karmaşıklığı azaltın veya Web İşleyicileri kullanın

JavaScript, stil hesaplamaları, düzen ve çoğu durumda boyamanın hemen yanında, tarayıcının ana iş parçacığında çalışır. JavaScript'iniz uzun süre boyunca çalışırsa bu diğer görevleri engeller ve karelerin atlanması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 ideal olarak JavaScript'inizi 3-4 ms civarında tutmaya çalışmalısınız. Bu sürenin uzaması, çok fazla zaman harcamanıza neden olabilir. Boş bir dönemdeyseniz süre konusunda daha rahat olabilirsiniz.

Örneğin, DOM erişimi gerektirmiyorsa birçok durumda salt hesaplama işlerini Web İşleyiciler'e taşıyabilirsiniz. Verileri sıralama veya arama gibi veri değiştirme veya tarama işlemleri, yükleme ve model oluşturma gibi işlemler genellikle bu model için 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 uygun değildir: Web işçilerinin DOM erişimi yoktur. Çalışmanızın ana iş parçacığında olması gerektiğinde, daha büyük görevi her biri birkaç milisaniyeden uzun sürmeyen mikro görevlere böldüğünüz ve her karede requestAnimationFrame işleyicilerinin içinde çalıştırdığınız bir gruplandırma yaklaşımı kullanabilirsiniz.

Bu yaklaşımın kullanıcı deneyimi ve kullanıcı arayüzü açısından sonuçları vardır. Bir ilerleme veya etkinlik göstergesi kullanarak kullanıcının bir görevin işlendiğinden haberdar olmasını sağlamanız gerekir. Bu yaklaşım, uygulamanızın ana mesaj dizisini boş tutarak kullanıcı etkileşimlerine duyarlı kalmasına yardımcı olur.

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

Bir çerçeveyi, kitaplığı veya kendi kodunuzu değerlendirirken JavaScript kodunun kare kare çalıştırılmasının ne kadar maliyetli olduğunu değerlendirmeniz önemlidir. Bu, özellikle geçiş veya kaydırma gibi performans açısından kritik animasyon çalışmaları yaparken önemlidir.

JavaScript'inizin maliyetini ölçmenin en iyi yolu Chrome Geliştirici Araçları'nın Performans panelini kullanmaktır. Genellikle aşağıdaki gibi düşük düzey kayıtlar alırsınız:

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

Ana bölümünde, 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 alev grafiği sunulur.

Bu bilgilerle, JavaScript'in uygulamanız üzerindeki performans etkisini değerlendirebilir ve işlevlerin yürütülmesinin çok uzun sürdüğü tüm sıcak noktaları bulup düzeltmeye başlayabilirsiniz. Daha önce de belirtildiği gibi, uzun süre çalışan JavaScript'i kaldırmayı veya mümkün değilse ana iş parçacığının diğer görevlere devam edebilmesi için bir Web İşleyici'ye taşımayı denemeniz gerekir.

Performans panelini nasıl kullanacağınızı öğrenmek için Çalışma Süresi Performansını Analiz Etmeye Başlama başlıklı makaleyi inceleyin.

JavaScript'inizi mikro optimizasyondan kaçının

Tarayıcının bir öğenin offsetTop değerini istemenin getBoundingClientRect() değerini hesaplamaktan daha hızlı olduğu gibi bir öğenin bir sürümünü diğerinden 100 kat daha hızlı yürütebileceğini bilmek ilginç olabilir. Ancak bu tür işlevleri kare başına yalnızca birkaç kez çağıracağınız neredeyse her zaman doğrudur. Bu nedenle, JavaScript'in performansının bu yönüne odaklanmak genellikle boşuna çabadır. Genellikle yalnızca milisaniyenin kesirleri kadar tasarruf edersiniz.

Bir oyun veya hesaplama açısından pahalı bir uygulama geliştiriyorsanız genellikle tek bir karede çok fazla hesaplama yapacağınız için bu kılavuzdaki bilgiler sizin için geçerli olmayabilir. Bu durumda her şey işinize yarayabilir.

Özetlemek gerekirse, mikro optimizasyonlar genellikle geliştirdiğiniz uygulama türüne karşılık gelmeyeceği için bu optimizasyonlardan çok dikkatli bir şekilde yararlanmanız gerekir.