【问题标题】:jquery mobile listview too slowjquery mobile listview太慢了
【发布时间】:2014-03-18 18:55:12
【问题描述】:

这是我想要做的:在 phonegap android 应用程序中,使用 jquery listview 从我的静态 xml 动态创建 UL 并显示它。

为了创建一个可过滤的列表视图,我使用了来自 w3schools 的代码。
然后我在 HTML 正文的 onload() 方法中使用以下代码从我的 XML 动态添加元素:

function parseit() {
    alert("parseit");
    $.ajax({
    type: "GET",
    url: "catalog.xml",
    dataType: "xml",
    success: function(xml) {
        $(xml).find("Book").each(function(){
            var title = $(this).find('Name').text();
            console.log(title);
            var listItem = '<li> <a href="#">' +title + '</li>';
            $("#list").append(listItem).listview('refresh');
        });
    }
    });
}

我的 XML 文件的架构是这样的:

<Books>
   <Book>
      <Name> somename </Name>
      <Price> $1.00 </Price>
      <Details> asdfgh </Details>
   </Book>
   <Book> .....  1500 items of this kind...  </Book>
</Books>

我面临的几个问题:

  1. 虽然我正在调用刷新,但 Listview 不会立即显示新添加的项目。我在几个地方看到了有关删除 div 内容等的信息,但我没有使用它(请参阅我给出的链接中的代码)。很长一段时间后,我必须四处点击才能显示项目。 Jquery listview 太慢了。我添加的列表项的数量是 1500 左右。

  2. 添加的项目不属于已排序的标题(例如,以“A”开头的项目不会返回该部分,而是在底部创建一个新的“A”部分

我选择了 jquery 的 listview,因为它给了我免费的搜索功能。

【问题讨论】:

  • 你的意思是 console.log ?当然。忘了补充,parseit() 函数是用 onload 调用的。
    那么您是说要在视图中加载 1500 个项目?
  • 是的,我的 XML 有 1500 个项目,我正在使用上面的 parseit() 函数添加这些项目。我删除了 console.log 语句。应用仍然没有响应。
  • 为了更快的处理,首选 JSON 而不是 XML。它还大大减少了带宽的使用。见Why is everyone choosing JSON over XML for jQuery

标签: jquery listview cordova


【解决方案1】:

好吧,让我们讨论这个问题。根据我的个人经验,您不能指望浏览器专门在移动设备中处理那么多项目。在移动浏览器中运行的 js 存在各种性能问题以及 DOM 限制。您必须按照以下步骤找出性能缓慢的根本原因:

  1. 复制您的 XML 并将其缩减为 50 或 75 个项目

  2. 运行它,观察是否仍然出现相同的性能问题。

  3. 如果您仍然看到性能问题,那么您必须优化您的代码

  4. 如果性能问题得到解决,那么您应该找出一种按需解析的方法。例如:解析前几十个,然后 当用户输入时,搜索 XML 并按需解析。

您无法使用 DOM 和 JS 在移动设备中动态添加 1500 个项目并期望获得良好的性能。一旦我在桌面浏览器上动态创建了 600 个 div,它就超级慢。这是因为 DOM 如何处理动态内容,遍历层次结构以便将项目放置在正确的位置。您可能认为这是一个简单的过程,但整个遍历过程会消耗 CPU 和处理时间。如果有一种方法可以最小化解析并按需进行,那就太好了。

阅读代理设计模式,有时当您处理庞大的数据集时,您使用代理让用户感觉一切都已加载,但只有一小部分可用,而其余部分是虚拟的,等待按需检索。

希望我的建议对你有用。

http://en.wikipedia.org/wiki/Proxy_pattern

试试这个版本的 jquery,它可能会有所帮助,它适用于移动设备:http://jquerymobile.com/

【讨论】:

  • 是的,我在我的项目中使用它 - jquery-1.10.2.min.js、jquery.mobile-1.4.2.min.js、jquery.mobile-1.4.2.css。
  • 是的,我同意您的观点,即由于项目数量过多,性能可能会受到影响。但是,如果我不使用 JQuery,而只是将这些项目添加到纯 HTML 和 Javascript UL 中,那么它就没有问题了。在这种情况下,UI 看起来只是链接列表(书名和指向书详细信息的超链接)。
  • 如您所知,JQuery 是一个编写在 Javascript 之上的库,这意味着在底层使用了大量代码,以便用更少的代码为您提供更多的功能主义者,这提高了开发人员的工作效率,但代价是降低了优化代码的能力。
  • 例如,Hibernate 是一个 ORM 工具,它使 Java 开发人员可以非常轻松地以 OOP 方式使用传统数据库,但它会在后台创建一些性能低下的 sql 查询,从而牺牲性能以方便发展。如果您需要良好的性能,则需要为该特定部分编写自己的函数,或者了解更多关于您可以通过哪些其他方式来实现相同结果且性能影响较小的更多信息。
  • PS:你有没有考虑过使用 json 而不是 xml ? json 是 js 原生的,所以它的性能应该比 xml 更好。 XML 有标签,这使得它比 json 更庞大,如果你可以将你的 xml 转换为 json 格式并尝试一下,你可能会在解析方面看到一些改进。例如:utilities-online.info/xmltojson/#.Uymb5vldWVM
【解决方案2】:

人们错过了一件重要的事情——你正在刷新代码 1500 次......

您也在搜索#list,1500 次。

function parseit() 
{
   alert("parseit");
   $.ajax(
   {
      type: "GET",
      url: "catalog.xml",
      dataType: "xml",
      success: function(xml) 
      {
          var list = $("#list");
          $(xml).find("Book").each(function()
          {
              var title = $(this).find('Name').text();
              console.log(title);
              listItem = '<li> <a href="#">' +title + '</li>';
              //$("#list").append(listItem).listview('refresh'); - this line we dont want.
          });
         list.listview('refresh');
      }
   });
}

你甚至可以更进一步。

function parseit() 
{
   alert("parseit");
   $.ajax(
   {
      type: "GET",
      url: "catalog.xml",
      dataType: "xml",
      success: function(xml) 
      {
          var list = $("#list");
          var listItem = "";

          $(xml).find("Book").each(function()
          {
              var title = $(this).find('Name').text();
              console.log(title);
              listItem += '<li> <a href="#">' +title + '</li>';
              //$("#list").append(listItem).listview('refresh'); - this line we dont want.
          });
         list.append(listItem);
         list.listview('refresh');
      }
   });
}

如果您希望列表视图响应式添加项目。你需要让它更慢我很抱歉我的朋友。

第一步。

A.获取您要添加的图书列表。

B.使用 setTimeout 创建异步任务

C.在该 setTimeout 中添加一些项目,然后刷新列表。

D.使用 setTimeout 使函数再次调用自身,直到图书列表中的所有项目都被删除。

【讨论】:

    猜你喜欢
    相关资源
    最近更新 更多
    热门标签