Dom'u requestanimationframe'de manipüle edersek ne olur?

0

Soru

Anladığım kadarıyla, bir DOM öğesi eklemek gibi bazı DOM manipülasyonları olduğunda, bir yeniden akışı tetikleyecek ve büyük olasılıkla bir yeniden boyama izleyecektir. Yanılıyorsam düzelt lütfen. MDN Web Dokümanlarından Alıntı Yapma,

Windows.requestAnimationFrame () yöntemi tarayıcıya bir animasyon gerçekleştirmek istediğinizi söyler ve tarayıcının bir sonraki yeniden boyamadan önce animasyonu güncellemek için belirtilen bir işlevi çağırmasını ister

requestAnimationFrame (a.k.a. aAF) geri arama, tarayıcı yeniden boyamak üzere hemen önce çağrılır. Yani bu, bir şekilde bu rAF içinde bir DOM manipülasyonu yapmayı başarırsak (düzenleme: ve sonunda başka bir rAF da sıraya koyarsak), her seferinde bir yeniden akışı tetikleyen ve böylece yeniden boyayacağımız anlamına mı geliyor? Aslında ekranda hiçbir şey oluşturmadan sonsuz bir döngüde sıkışıp kalacağız.

Yoksa tarayıcı yeniden boyamaya karar verdikten sonra, ona bağlı kalacak ve bir sonraki yeniden boyamada RAF geri aramasında meydana gelen güncellemeleri uygulayacak mı?

dom javascript reflow repaint
2021-11-21 07:17:28
1

En iyi cevabı

1

bir DOM öğesi eklemek gibi bazı DOM manipülasyonları olduğunda, bir yeniden akışı tetikleyecek ve büyük olasılıkla bir yeniden boyama izleyecektir

Boyama eylemi eşzamansız olarak gerçekleşir, bu nedenle" tetikleyici " bu şekilde anlaşılmalıdır. İlk önce JavaScript kodunuz gerçekten gerçekleşmeden önce bitecektir.

bir şekilde bu rafın içinde bir DOM manipülasyonu yapmayı başarırsak (düzenleme: ve sonunda başka bir rAF da sıraya koyarsak), her seferinde bir yeniden akışı tetikler ve böylece bir yeniden boyama yaparsak, ekranda hiçbir şey oluşturmadan sonsuz bir döngüde sıkışıp kalırız.

Yeniden boyama ihtiyaçları birikir ve eşzamanlı olarak yerine getirilmez. Önce kodunuz çağrı yığını boşalana kadar tamamlanmalıdır. Yani burada sonsuz bir döngü yok.

Yoksa tarayıcı yeniden boyamaya karar verdikten sonra, ona bağlı kalacak ve bir sonraki yeniden boyamada RAF geri aramasında meydana gelen güncellemeleri uygulayacak mı?

Evet. RAF geri çağrısı çağrıldığında, bu kod, boyama için daha fazla gereksinim biriktirebilecek DOM güncelleştirmelerini yapmak için son bir şans alır. Bu geri aramada Raf'a başka bir geri arama da kaydederseniz, o zaman yürütülmez, ancak daha sonra: bir dahaki sefere tarayıcı yeniden boyama görevini hazırlayacaktır-yani geçerli olanı değil.

Basitleştirilmiş örnek

Bu koda sahip olduğunuzu varsayalım:

requestAnimationFrame(update);

myElement.style.backgroundColor = "silver"; // This queues a need for repaint

function update() {
    // This queues a need for repaint
    myElement.style.width = Math.floor(Math.random() * 100) + "px";
    requestAnimationFrame(update);
}

Bu yürütüldüğünde, aşağıdaki sırayı alırız:

  1. update geri arama olarak kaydedilir
  2. Arka plan değişikliği, yeniden boyama ihtiyacını zamanlıyor
  3. Callstack boş olur
  4. Tarayıcı yeniden boyama işini başlatır, ancak kayıtlı bir geri arama olduğunu dikkate alır. Bu yüzden bu kaydı kaldırır (çünkü yalnızca bir kez çalıştırılmalıdır) ve yürütür update başka bir şey yapmadan önce.
  5. Genişlik değişikliği, yeniden boyama ihtiyacını planlar. Değişikliklerin listesi artık arka plan değişikliğini ve bu genişlik değişikliğini ve hesaplanan basamaklama efektlerini içerir. (Bunun nasıl temsil edildiği tarayıcıya bağlıdır)
  6. Bu update işlev tekrar geri arama olarak kaydedilir.
  7. Tarayıcı artık bu yeniden boyama işinin bir parçası olarak ne yapması gerektiğini kontrol ediyor ve arka plan ve genişlik değişikliklerinin etkilerini görselleştirmek için gereken her şeyi gerçekleştiriyor.
  8. Boya işi bitiyor. Geriye kalan tek şey kayıtlı update çağrı.
  9. Tarayıcı bir sonraki boyama döngüsünü gerçekleştirdiğinde, 4. adımdan itibaren yeniden başlarız, ancak artık sıraya alınmış bir arka plan değişikliği yoktur. Gerisi için aynı süreç olacak.
2021-11-21 12:57:10

"4. Tarayıcı mizanpaj/yeniden boyama işini başlatır, " bu oldukça kafa karıştırıcı bir formülasyon, "tarayıcı oluşturmayı güncellemeye başlar" demenin biraz daha az kafa karıştırıcı olacağını düşünüyorum. Düzen ve yeniden boyama ayrılır, bir düzeni kullanıcı arazi kodundan eşzamanlı olarak çok iyi zorlayabilirsiniz, yeniden boyamaya zorlayamazsınız, bu her zaman oluşturma adımlarının son adımı olacaktır. Ayrıca, ilk noktalara verilen cevapların, başlangıçtan itibaren bunu hatırlatarak çok daha kolay olacağını hissediyorum raf(()=>raf(fn2)) zamanlayacaktır fn2 bir sonraki kareye ateş etmek için. Aksi halde bu cevap doğrudur.
Kaiido

@Kaiido, yorumunuz için teşekkürler. "bir düzeni kullanıcı arazi kodundan eşzamanlı olarak çok iyi zorlayabilirsiniz": düzende kullanıcı tarafından algılanabilir bir değişiklik mi demek istiyorsunuz? bunun bir kod örneğini verebilir misiniz?
trincot

Her neyse, mizanpaj referansını kaldırdım.
trincot

gist.github.com/paulirish/5d52fb081b3570c81e3a Düzeni neyin tetiklediğinin bir listesi ve evet, "kullanıcı tarafından algılanabilir": stackoverflow.com/questions/55134528/...
Kaiido

Pekala, Kaiido!
trincot

Diğer dillerde

Bu sayfa diğer dillerde

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................