zoukankan      html  css  js  c++  java
  • 提高ipad浏览器下大尺寸xml文件解析的性能

    昨天,客户报了个Bug过来:html5应用在ipad下卡住不动了。按照他发过来的地址,初步诊断是xml解析的性能问题。应用初始化时要加载几个xml配置文件,客户给的地址中,一个配置文件有800多K(文件A),另一个配置文件有400多K(文件B)。我修改了程序,在PC机上用Safari模拟ipad登录,解析文件A花了30多秒。一般来说,ipad2的性能是我的PC机的1/5,在ipad上解析这个xml文件至少要花150秒。这是不能接受的。同样的程序,在ie下测试,仅仅耗时160ms!我用的是haXe的xml库,在ie9和在safari上竟然有这么大的性能差距。

    又找了几个xml库,不是无法运行,就是执行失败。实在没有办法,只好用domparser来解析,当html文件处理。使用domparser可以极大的提高性能,还是以文件A为例子,在PC的safari上解析耗时降为1秒左右,这个时间是可以承受的。然而,使用domparser存在一个问题,就是无法提取出CData数据。http://stackoverflow.com/questions/5227592/extract-cdata-from-rss-xml-using-javascript 给出了一个解决方案:将CData数据用标签围住,这是一种思路。于是,修改程序,将<![CDATA[替换为<cdata>,将]]>替换成</cdata>。

    提取cdata标签的数据,当作XML文件的CData数据/。问题似乎解决了,经过多次测试,又发现了新的问题:

    CData中有很多字符没有转义。在CData中倒是无害,但在<cdata></cdata>中就变成有害了。这里又要表扬下ie9:ie9在这种情况下能够正确解析,Safari不能!

    既然问题出现在CData,那么我们就对CData数据进行预处理:
    (1),找到每个CData数据,为它编号;
    (2),对每个CData片段,用它的编号进行替换,这样就屏蔽了敏感字符;
    (3),将替换后的文本,用domparser解析。

    这样一来,当使用这个Dom时,碰到CData编号,再将它替换为对应的CData数据即可。因为文件A在ipad上无法解析成功,这里只对文件B的解析进行了都比。之前解析文件B耗时是13-16秒,使用新方法后,解析时间缩短为32毫秒,提高了约400倍。

    ====

    下面的代码是用haXe写的,haXe很容易读,就不详加解释了。
    CData类,存储键值对:

    class CData 
    {
     public var key:String;
     
     public var val:String;
     
     public function new() 
     {
     } 
    }

    Xml2Html类,对xml文本进行预处理,并存储CData信息:

    class Xml2Html 
    {
     private var map:Array<CData>;

     public function new() 
     {
     }
     
     public function getCData(key:String):String
     {
      if (map == nullreturn null;
      
      for (i in 0 ... map.length)
      {
       var item:CData = map[i];
       if (item.key == key)
       {
        return item.val;
       }
      }
      
      return null;
     }
     
     public function prepareXmlAsHtml(txt:String):String
     {
      map = new Array<CData>();
      txt = StringTools.replace(txt, "<![CDATA[""]]>");
      var lines:Array<String> = txt.split("]]>");
      if (lines.length == 0return txt;
      var buff:StringBuf = new StringBuf();
      var k:Int = 0;
      for (i in 0 ... lines.length)
      {
       var val:String = lines[i];
       if (i % 2 == 0// 正常内容
       {
        buff.add(val);
       }
       else
       {
        var key:String = Std.string(k);
        buff.add("<cdata>" + key + "</cdata>");
        var cdata:CData = new CData();
        cdata.key = key;
        cdata.val = val;
        map.push(cdata);
        k++;
       }
      }
      
      return buff.toString();
     }
    }

    下面是解析示例:

      var ctx:Xml2Html = new Xml2Html();
      searchInfo = dom.parseFromString(ctx.prepareXmlAsHtml(data), "text/xml");
        
      var dom:HtmlDom = searchInfo;
      var pages:HtmlCollection<HtmlDom> = dom.getElementsByTagName("page");
      for (i in 0 ... pages.length)
      {
       var node:HtmlDom = pages[i];
       var pageNumVal:String = node.getAttribute("pageNumber");
       var htmlText:String = null;
       var htmlTextDoms:HtmlCollection<HtmlDom> = node.getElementsByTagName("cdata");
       if (htmlTextDoms != null && htmlTextDoms.length > 0)
       {
        htmlText = StringTools.trim(htmlTextDoms[0].childNodes[0].nodeValue);
        htmlText = ctx.getCData(htmlText);
       }
       
       for (k in 0 ... book.pages.length)
       {
        var page:Page = book.pages[k];
        if (page.id == pageNumVal)
        {
         page.content = htmlText;
        }
       }
      }

    ====

    小结:

    (1)IE9很厉害!

    (2)haXe是好东东,用它写js程序很舒服。但因为是开源社区的作品,还不够成熟,需要使用者自己想办法来弥补其缺陷。

    版权所有,欢迎转载
  • 相关阅读:
    《你的灯还亮着吗》读后感1
    找"1"
    阅读计划---《梦断代码》3
    阅读计划---《梦断代码》2
    个人工作总结(10)
    个人工作总结(9)
    个人工作总结(8)
    个人工作总结(7)
    学习进度条
    个人工作总结(6)
  • 原文地址:https://www.cnblogs.com/xiaotie/p/2365453.html
Copyright © 2011-2022 走看看