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转换事件非常慢的主要内容,如果未能解决你的问题,请参考以下文章

原始 iPad、CSS3 转换以及 RAM 导致的成像限制

ffmpeg - 转换非常慢

将 cupy 转换为 numpy 非常慢

如何将子视图上的触摸事件的坐标转换为其父视图中的坐标?

隐藏Safari ios上的方向转换

将 MS Access 2000 转换为 2010