javascript - Los eventos de transición CSS son extremadamente lentos en IOS
Estoy desarrollando una aplicación de Javascript de una sola página que se ejecuta en navegadores de escritorio y también en dispositivos móviles a través de Cordova/Phonegap.
Tengo un menú desplegable que está implementado usando transiciones CSS. Noté que funciona bien en navegadores de escritorio y en Android. Sin embargo, en iOS hay problemas de rendimiento serios. La transición no parece comenzar a tiempo, pero una vez que comienza, el renderizado y la duración se ven bien. El tiempo entre el inicio de la transición y el evento transitionend es mucho mayor en iOS que en otras plataformas. Por ejemplo, la duración de la transición es de 300 ms, pero no recibo el evento transitionend hasta los 1500 ms. En todas las demás plataformas, recibo el evento transitionend entre 325 y 350 ms.
Evento transitionend:
- Esperado: 350 ms
- Actual: 1500 ms
Plataformas :
- Cordova 6.3.1
- Xcode 8.1 GM Seed
- IOS 10.1
Aquí está el CSS para el div del menú. Para desplegar el menú, agrego la clase 'open'. Para cerrar el menú, quito la clase 'open'. He intentado hacer la transición sobre la propiedad 'left' y sobre la propiedad 'transform', pero los resultados son idénticos.
/* 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;
}
Pregunta: ¿Qué podría estar causando el retraso en el inicio de la transición, solo en las plataformas IOS? ¿Existen soluciones conocidas para evitar el problema o acelerar el proceso? Tengo otras transiciones en la aplicación que tardan más de 5 segundos en comenzar, lo que hace que la aplicación sea inutilizable. Espero que la solución del menú se aplique en toda la aplicación. Gracias por cualquier ayuda o ideas que pueda proporcionar.
Aquí está el código Javascript instrumentado que utilizo para abrir/cerrar el menú...
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);
};
Respuesta #1
Al mover elementos por la pantalla, deseas maximizar el rendimiento. En lugar de hacer la transición de la propiedad left, es mejor usar la traducción. Usando la traducción, el dispositivo utilizará su GPU para renderizar el cambio en pantalla, en una capa sobre el DOM. Esto resultará en una transición más suave y con mejor rendimiento.
Echa un vistazo a este ejemplo. Además de usar un transform en lugar de cambiar la propiedad left, observa que eliminé un poco de redundancia. No necesitas redeclarar la transición en el estado activo.
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>