IOS上的CSS转换事件非常慢
Posted
技术标签:
【中文标题】IOS上的CSS转换事件非常慢【英文标题】:CSS transition events extremely slow on IOS 【发布时间】:2017-03-10 21:33:27 【问题描述】:我正在开发一个单页 javascript 应用程序,它可以在桌面浏览器上运行,也可以通过 Cordova/Phonegap 在移动设备上运行。
我有一个使用 CSS 过渡实现的滑出式菜单。我注意到它在桌面浏览器和 android 上运行良好。但是,在 ios 上存在严重的性能问题。过渡似乎没有按时开始,但一旦开始渲染和持续时间看起来很好。在 IOS 上,开始转换和 transitionend 事件之间的时间比其他平台要长得多。例如,转换的持续时间是 300 毫秒,但我在 1500 毫秒内没有收到 transitionend 事件。在所有其他平台上,我在 325-350 毫秒内收到了 transitionend 事件。
Transitionend 事件:
预计:350 毫秒 实际:1500 毫秒平台:
科尔多瓦 6.3.1 Xcode 8.1 GM 种子 IOS 10.1这是菜单 div 的 CSS。为了滑出菜单,我添加了“开放”类。要关闭菜单,我删除了“打开”类。我尝试过在“left”属性和“transform”属性上进行转换,但结果是相同的。
/* 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;
问题:仅在 IOS 平台上,可能是什么导致了开始转换的延迟?是否有任何已知的解决方案来规避问题或加快速度?我在应用程序中有其他过渡需要 5 秒才能启动,导致应用程序无法使用。我希望菜单解决方案将适用于整个应用程序。感谢您提供的任何帮助或想法。
这是我用来打开/关闭菜单的检测 Javascript 代码...
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);
;
【问题讨论】:
更新:IOS (10.1.1) 的最新更新似乎大大加剧了这个问题。即使在将 top/left 移植到转换转换之后,它仍然是一个问题。 iPhone5 上的任何过渡都开始得很晚,有时在按钮单击/触摸后超过 5 秒。 iPhone6 的性能要好一些,这让我相信这是内存问题,也许是为了让人们摆脱旧 iPhone 的计划过时。在sizzlescene.comsizzlescene.com 上试用旧 iPhone 上的应用进行演示。 【参考方案1】:在屏幕上移动元素时,您希望最大限度地提高性能。与其转换left
属性,不如使用翻译。使用翻译,设备将使用其 GPU 在 DOM 上方的层上呈现屏幕变化。这将带来更平滑、更高效的过渡。
看看这个例子。除了使用transform
而不是更改left
属性之外,请注意我删除了一些冗余。您无需重新声明活动状态的转换。
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>
【讨论】:
感谢安迪霍夫曼的回复。是的,不需要“开放”类中的过渡复制。谢谢。您的更改在桌面上确实有效,但在移动设备上,点击事件需要转换为 touchstart...touchend 以避免内置的 300 毫秒延迟以允许双击检测。但是,即使您进行了更改,过渡开始的延迟仍然会发生……仅在 IOS 上。我还发现删除转换并弹出导航菜单仍然存在问题。因此,在将“开放”类添加到元素之后,某些事情会导致延迟。知道如何配置文件吗? Andy Hoffman 的回答是最有帮助的,尽管在更新课程列表和反映 UI 更改之间我仍然有一些未知的活动。看看 WKWebView 作为 UIWebView 的替代品。以上是关于IOS上的CSS转换事件非常慢的主要内容,如果未能解决你的问题,请参考以下文章