提高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類,存儲鍵值對:
{
?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?==?null)?return?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?==?0)?return?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程序很舒服。但因為是開源社區的作品,還不夠成熟,需要使用者自己想辦法來彌補其缺陷。
總結
以上是生活随笔為你收集整理的提高ipad浏览器下大尺寸xml文件解析的性能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#学习笔记(二)运算符 乘方 判断语句
- 下一篇: 2017年html5行业报告,云适配发布