javascript - CSS-overgangshendelser ekstremt langsomme på IOS
Jeg utvikler en enkelt-side Javascript-applikasjon som kjører på skrivebordsnettlesere og også på mobile enheter via Cordova/Phonegap.
Jeg har en skyve-meny som er implementert ved hjelp av CSS-overganger. Jeg har lagt merke til at den fungerer bra på stasjonære nettlesere og Android. Imidlertid er det alvorlige ytelsesproblemer på iOS. Overgangen ser ikke ut til å starte i tide, men når den først starter, ser gjengivelsen og varigheten bra ut. Tiden mellom å starte overgangen og transitionend-hendelsen er mye lengre på iOS enn på andre plattformer. For eksempel er varigheten av overgangen 300 ms, men jeg får ikke transitionend-hendelsen før etter 1500 ms. På alle andre plattformer får jeg transitionend-hendelsen innen 325-350 ms.
Transitionend-hendelse:
- Forventet: 350 ms
- Faktisk: 1500 ms
Plattformer :
- Cordova 6.3.1
- Xcode 8.1 GM Seed
- IOS 10.1
Her er CSS-en for menydelen. For å skyve ut menyen, legger jeg til klassen 'open'. For å lukke menyen, fjerner jeg klassen 'open'. Jeg har prøvd å bruke overgang på 'left'-egenskapen og 'transform'-egenskapen, men resultatene er identiske.
/* 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;
}
Spørsmål: Hva kan være årsaken til forsinkelsen i å starte overgangen, bare på IOS-plattformer? Finnes det noen kjente løsninger for å omgå problemet eller få ting til å gå raskere? Jeg har andre overganger i appen som tar over 5 sekunder å starte, noe som gjør appen ubrukelig. Jeg håper at meny-løsningen vil gjelde for hele appen. Takk for all hjelp eller ideer du kan gi.
Her er den instrumenterte Javascript-koden jeg bruker for å åpne/lukke menyen...
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);
};
Svar #1
Når du flytter elementer rundt på skjermen, ønsker du å maksimere ytelsen. I stedet for å animere left-egenskapen, er det bedre å bruke transformasjon. Ved å bruke transformasjon vil enheten bruke GPU-en sin til å gjengi endringen på skjermen, på et lag over DOM. Dette vil resultere i en jevnere og mer ytelseseffektiv overgang.
Ta en titt på dette eksemplet. I tillegg til å bruke en transform i stedet for å endre left-egenskapen, legg merke til at jeg fjernet litt overflødighet. Du trenger ikke å erklære overgangen på nytt i den aktive tilstanden.
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>