javascript - event transisi CSS sangat lambat di IOS


Saya sedang mengembangkan aplikasi Javascript satu halaman yang berjalan di browser desktop dan juga di perangkat seluler melalui Cordova/Phonegap.

Saya memiliki menu geser yang diimplementasikan menggunakan transisi CSS. Saya memperhatikan bahwa itu bekerja dengan baik di browser desktop dan Android. Namun, di iOS ada masalah kinerja yang serius. Transisi tampaknya tidak mulai tepat waktu, tetapi begitu mulai, rendering dan durasinya terlihat baik. Waktu antara dimulainya transisi dan event transitionend jauh lebih lama di iOS dibandingkan platform lain. Misalnya, durasi transisi adalah 300ms tetapi saya tidak menerima event transitionend hingga 1500ms. Di semua platform lain, saya menerima event transitionend dalam 325-350ms.

Peristiwa Transitionend:

  • Diharapkan: 350ms
  • Sebenarnya: 1500ms

Platform :

  • Cordova 6.3.1
  • Xcode 8.1 Benih GM
  • IOS 10.1

Berikut adalah CSS untuk div menu. Untuk menggeser keluar menu, saya menambahkan kelas 'open'. Untuk menutup menu, saya menghapus kelas 'open'. Saya telah mencoba transisi pada properti 'left' dan properti 'transform', tetapi hasilnya sama saja.

/* Nav Menu */

#navmenu {
    position: absolute;
    top: 0;
    width: 90%;
    max-width: 400px;
    z-index: 20;
    height: auto;
    background-color: white;
    /*
    -webkit-transform: translate3d(-100%,0,0);
       -moz-transform: translate3d(-100%,0,0);
        -ms-transform: translate3d(-100%,0,0);
            transform: translate3d(-100%,0,0);
    -webkit-transition: -webkit-transform 300ms ease;
       -moz-transition:    -moz-transform 300ms ease;
        -ms-transition:     -ms-transform 300ms ease;
         -o-transition:      -o-transform 300ms ease;
            transition:         transform 300ms ease;
    */
    left: -100%;
    -webkit-transition: left 300ms ease;
       -moz-transition: left 300ms ease;
        -ms-transition: left 300ms ease;
         -o-transition: left 300ms ease;
            transition: left 300ms ease;
}

#navmenu.open {
    /*
    -webkit-transform: translate3d(0,0,0);
       -moz-transform: translate3d(0,0,0);
        -ms-transform: translate3d(0,0,0);
            transform: translate3d(0,0,0);
    -webkit-transition: -webkit-transform 300ms ease;
       -moz-transition:    -moz-transform 300ms ease;
        -ms-transition:     -ms-transform 300ms ease;
         -o-transition:      -o-transform 300ms ease;
            transition:         transform 300ms ease;
    */
    left: 0;
    -webkit-transition: left 300ms ease;
       -moz-transition: left 300ms ease;
        -ms-transition: left 300ms ease;
         -o-transition: left 300ms ease;
            transition: left 300ms ease;
}

Pertanyaan: Apa yang mungkin menyebabkan keterlambatan dalam memulai transisi, hanya di platform IOS? Apakah ada solusi yang diketahui untuk mengatasi masalah ini atau mempercepatnya? Saya memiliki transisi lain dalam aplikasi yang membutuhkan lebih dari 5 detik untuk memulai, membuat aplikasi tidak dapat digunakan. Saya berharap solusi menu dapat diterapkan di seluruh aplikasi. Terima kasih atas bantuan atau ide yang dapat Anda berikan.

Berikut adalah kode Javascript yang diinstrumentasi yang saya gunakan untuk membuka/menutup menu...

utilities.addEventListeners(navMenuButtonDiv, function () {
    var start = Date.now();
    var menuDiv = navMenu.getDiv();
    if (menuDiv.classList.contains('open')) {
        menuDiv.classList.remove('open');
    } else {
        menuDiv.classList.add('open');
    }
    var handler = function (event) {
        console.log('Transition: ' + (Date.now() - start));
        menuDiv.removeEventListener('webkitTransitionEnd', handler, true);
    };
    menuDiv.addEventListener('webkitTransitionEnd', handler, true);
 };

Jawaban #1

Saat memindahkan elemen di sekitar layar, Anda ingin memaksimalkan kinerja. Alih-alih mengubah properti left, sebaiknya gunakan translasi. Dengan menggunakan translasi, perangkat akan menggunakan GPU-nya untuk merender perubahan di layar, pada lapisan di atas DOM. Ini akan menghasilkan transisi yang lebih mulus dan berkinerja lebih baik.

Lihat contoh ini. Selain menggunakan transform daripada mengubah properti left, perhatikan bahwa saya menghapus sedikit redundansi. Anda tidak perlu mendeklarasikan kembali transisi pada state aktif.

var open = document.getElementById("open"),
    close = document.getElementById("close"),
    nav = document.getElementById("navmenu");

open.addEventListener("click", function() {
  nav.classList.add("open");
}); 

close.addEventListener("click", function() {
  nav.classList.remove("open");
});
#navmenu {
  position: absolute;
  top: 0;
  left: 0;
  width: 90%;
  max-width: 400px;
  z-index: 20;
  height: auto;
  background-color: white;
  transform: translate3d(-100%, 0, 0);
  -webkit-transition: transform 300ms ease-in-out;
     -moz-transition: transform 300ms ease-in-out;
      -ms-transition: transform 300ms ease-in-out;
       -o-transition: transform 300ms ease-in-out;
          transition: transform 300ms ease-in-out;
}

#navmenu.open {
  transform: translate3d(0, 0, 0);
}

button {
  margin-top: 100px;
}
<div id="navmenu">stuff in here</div>
<button id="open">Open Menu</button>
<button id="close">Close Menu</button>