黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

OpenLaszlo學(xué)習(xí)筆記(一)

系統(tǒng) 2334 0

? 1. OpenLaszlo簡介

在Web應(yīng)用越來越關(guān)注用戶體驗的今天,傳統(tǒng)的HTML應(yīng)用已經(jīng)不能滿足開發(fā)人員和終端用戶的需求。OpenLaszlo作為當(dāng)今主流的RIA(Rich Internet Application)的應(yīng)用平臺,在進入開源社區(qū)之后顯示出了更大的活力。Laszlo的技術(shù)基于XML和JavaScript來構(gòu)建RIA程序,為Web開發(fā)人員提供了一種簡潔快速的編程模式,并且給終端用戶以更加動態(tài)的交互式體驗。

OpenLaszlo的SDK(Standard Development Kit)由一個用Java編寫的編譯器、一個運行時的JavaScript庫和一個可選的Java Servlet構(gòu)成,如圖1.1所示。開發(fā)OpenLaszlo的步驟非常簡單:編輯、保存和刷新源文件即可。開發(fā)人員可以使用任何文本編輯器來編輯源文件,并且將其對應(yīng)的URL鍵入瀏覽器。OpenLaszlo服務(wù)器自動地將文件編譯成一個Flash文件,然后瀏覽器將其展示出來。


?
?

OpenLaszlo應(yīng)用由LZX的文件組成。LZX是一種標準驅(qū)動的XML和JavaScript描述性的語言,它使得上述聲明式的(declarative)、基于文本的開發(fā)流程變?yōu)榭赡堋A斜?.2展示了一段簡單的OpenLaszlo程序代碼,它定義了一個按鈕,用戶在按下之后該按鈕的位置會向右移動一段固定的距離。


列表1.2 一個簡單的OpenLaszlo應(yīng)用

            <canvas height="30">
  <button onclick="animate('x', 100, 1000, true)">
    Move me
  </button>
</canvas>
          

?

在下一章,我們將根據(jù)OpenLaszlo官方的開發(fā)指南,構(gòu)建一個數(shù)據(jù)驅(qū)動的應(yīng)用程序,并對其進行深入的分析和調(diào)試。

?


?

?

?

為了更加清楚地說明我們的主題,我們根據(jù)OpenLaszlo的官方軟件開發(fā)指南[1],擴展了其中通訊錄的示例。這個應(yīng)用提供了一個功能齊全的聯(lián)系人列表,它列出了所有的聯(lián)系人,并允許用戶對聯(lián)系人添加、刪除和更新。唯一不同的是,我們的程序為用戶提供了更多的選項,包含了更多的數(shù)據(jù)。圖2.1展示了該程序的界面。


圖2.1 一個通訊錄的應(yīng)用
圖2.1 一個通訊錄的應(yīng)用

由于聯(lián)系人的功能和教程上的基本相同,我們使用了和OpenLaszlo指南中相同的方法來實現(xiàn)它。列表2.2描述了應(yīng)用中一個類contactview的部分代碼。


列表2.2 聯(lián)系人視圖(contactview)的源代碼

            <class name="contactview" extends="view" visible="false" x="20"
height="180">
    <simplelayout axis="y" spacing="5" />
    <view layout="axis:x; spacing: 10">
        <text y="10">First Name:</text>
        <edittext name="firstName" datapath="firstName/text()" y="10"/>
        <text y="10">Last Name:</text>
        <edittext name="lastname" datapath="lastName/text()" y="10"/> 
  
    </view>
    <view>
        <text x="0" y="10">Gender:</text>
        <radiogroup layout="axis: x" x="80" y="12" datapath="gender" >    
           <attribute name="genderv" type="string" value="$path{'text()'}"
     />
           <method event="ondata">
              this.selectItem(this.getAttribute('genderv'));
           </method>            
           <radiobutton value="'M'" text="Male" />
           <radiobutton value="'F'" text="Female"/>
        </radiogroup>
        <text x="195" y="10">Country:</text>
        <mycombobox x="275" y="10" width="105" 
            datapath="country/text()">
            <textlistitem value="${this.text}" 
                datapath="timedata:/time/day/item/text()"/>
        </mycombobox>
    </view>
</class>
          

?

此外,雖然應(yīng)用的數(shù)據(jù)存儲在本地機器的XML文件中,但如列表2.3所示,我們對數(shù)據(jù)集的type和request屬性做了設(shè)置,使應(yīng)用程序在運行時才能夠得到數(shù)據(jù)。在這種情況下,我們能夠模擬OpenLaszlo的客戶端從遠程的服務(wù)器中獲得數(shù)據(jù)的情景。


列表2.3 數(shù)據(jù)集的設(shè)置

            <dataset name="countrydata" request="true" type="http" src="countries.xml"/>
          

?

2.2 系統(tǒng)瓶頸

完成上述應(yīng)用之后,性能問題迅速地顯現(xiàn)出來。系統(tǒng)主要在以下三方面表現(xiàn)出了性能的瓶頸:

1. 程序初始化的時間很長。當(dāng)列表達到30個聯(lián)系人條目的規(guī)模時,程序就會花費很長時間來顯示整個列表。在程序裝載的過程中,這些條目逐條緩慢地顯示出來。而在此期間,用戶幾乎不可能進行任何操作。

2. 下拉框(combobox)的初始化時間長度令人難以接受。當(dāng)下拉框的選項非常多時,由于控件會等待列表初始化完畢后才變?yōu)榭梢姡@將會耗費大量的時間和內(nèi)存。

3. 刪除功能的表現(xiàn)也不盡如人意,尤其在用戶嘗試刪除位于頂端的條目。當(dāng)一個條目被刪除時,在其之下的條目將會被完全地刷新。這樣的重畫界面也引發(fā)了嚴重的性能問題。鑒于以上的性能問題,我們將逐步討論如何解決這些問題。在第三章中,我們會闡述一些能夠提高性能的普遍原則,并應(yīng)用到本章所演示的程序里。進一步的,第四章將描述本文所涉及的實驗方法,并且向讀者展現(xiàn)比較實驗的結(jié)果。

?



回頁首

?

3. 優(yōu)化OpenLaszlo程序的原則

3.1 延緩初始化時間

在默認情況下,OpenLaszlo會在加載頁面時對所有的元素全部進行初始化。無論這些元素是可見或不可見的,它們都會被實例化。同時,OpenLaszlo提供了initstage屬性來控制何時執(zhí)行節(jié)點的init方法以及發(fā)送oninit事件的時機。initstage是LzNode的屬性,換言之,它幾乎可以被所有的元素繼承并使用,它有五種可選的屬性值[2]:

  • immediate
    除非該實例的所有子節(jié)點被創(chuàng)建,否則其他代碼都不得運行。也就是說,初始化是實例化的最后一個階段。
  • early
    在視圖(view)和它的子節(jié)點被創(chuàng)建后,立即調(diào)用init方法。
  • normal
    系統(tǒng)缺省值。Init方法在初始化父節(jié)點的工作完成后被調(diào)用。
  • late
    在系統(tǒng)空閑時(idle)初始化節(jié)點。用戶可以通過檢查isinited屬性來確認節(jié)點是否被初始化完畢。如果想在某一時刻強制節(jié)點初始化,可以調(diào)用completeInstantiation方法。
  • defer
    在該設(shè)置下,除非用戶顯式地調(diào)用completeInstantiation,否則節(jié)點將不會被初始化。

不難看出,使用late和defer的節(jié)點,在執(zhí)行init方法以及發(fā)送oninit事件時,并不一定被初始化完畢。因此,它們非常適用于延緩OpenLaszlo節(jié)點的初始化時間。對一些在頁面初次加載時不可見的節(jié)點,我們可以使用initstage = defer來抑制初始化,在觸發(fā)其可見的事件上按需調(diào)用completeInstantiation。這樣既可以減少頁面初始化的時間,又可以減少很多不必要的初始化。因為對用戶而言,很多不可見的元素是不需要被加載進系統(tǒng)的。

具體到我們的通訊錄應(yīng)用中,顯示聯(lián)系人細節(jié)的視圖(contactview)完全符合上述的條件。于是,我們將其initstage的屬性設(shè)為defer,并且重寫了其父節(jié)點的onclick事件,使得只有在用戶點擊了條目后,細節(jié)視圖才會占用系統(tǒng)的資源,按需地被初始化。列表3.1描述了具體的代碼。


列表3.1延緩初始化時間的代碼

            <view id="newEntryView">
    <text text="New Entry..." > 
        <method event="onclick">
                parent.newContactView.setVisible(!parent.newContactView.visible);
                //在點擊時完成初始化
                parent.newContactView.completeInstantiation(); 
        </method>
</text>
<contactview name="newContactView" 
     datapath="newcontact:/contact"
     initstage="defer"> <!--在頁面初次加載時不初始化contactview-->
     <button width="80" x="300" text="Add" />
</contactview>
          

?

3.2 惰性復(fù)制數(shù)據(jù)

用戶界面中,經(jīng)常存在實際條目比展示給用戶的條目多的列表。OpenLaszlo為這種情況在baselist、basecombobox等節(jié)點中定義了dataoption屬性。當(dāng)dataoption取lazy值時,列表的條目(listitem)將會使用惰性復(fù)制,即只復(fù)制需要顯示的條目。通訊錄中表示國家的下拉框有近200個選項,就屬于這種情況。在列表3.2中,我們自定義了一個下拉框類,并附上了它的使用示例。這樣,即使有200個數(shù)據(jù)項,系統(tǒng)也只復(fù)制了5個textlistitem的視圖。


列表3.2 使用惰性復(fù)制的下拉框

            <class name="mycombobox" extends="combobox" editable="false"
      shownitems="5" 
      dataoption="lazy" />
<mycombobox id="country" x="275"
      width="105" 
      datapath="country/text()">
<textlistitem datapath="countrydata:/countries/country/text()" 
          value="${this.text}" />
</mycombobox>
          

?

值得一提的是,我們在<textlistitem>中直接定義了datapath屬性,因此它繼承了父節(jié)點dataopiton = lazy的特征。如果在<textlistitem>下單獨定義datapath元素,那么我們還必須將其replication屬性設(shè)為lazy,如表3.3所示。


列表3.3 單獨聲明datapath的textlistitem

            <mycombobox >
<textlistitem value="${this.text}" >
    <datapath xpath="countrydata:/countries/country/text()" 
         replication = "lazy" />
</textlistitem>
</mycombobox>
          

?

事實上,OpenLaszlo使用惰性復(fù)制的列表使用LzLazyReplicationManager而不是缺省的LzReplicationManager來控制視圖。后者在視圖的datapath和多個datanode匹配時,為每一個匹配都創(chuàng)建一個視圖;而前者出于顯示數(shù)據(jù)的考慮,只創(chuàng)建足夠數(shù)量的視圖。本文的例子中,通訊錄的條目過多時(如超過100條),也可以考慮使用lazy的屬性使初始化時間變快。

3.3 緩存數(shù)據(jù)

假使OpenLaszlo應(yīng)用使用了數(shù)據(jù)復(fù)制,而且這些數(shù)據(jù)在運行時改變的話,默認的LzReplicationManager會將數(shù)據(jù)改變所對應(yīng)的視圖銷毀,然后重新創(chuàng)建它們。顯而易見,如果數(shù)據(jù)集非常大,這樣的調(diào)整策略會導(dǎo)致用戶界面嚴重的反應(yīng)遲緩。如第二章所述,我們的通訊錄應(yīng)用在刪除位于列表頂端的記錄時,就會出現(xiàn)明顯的延遲。

為了解決上述問題,我們可以將匹配多個數(shù)據(jù)節(jié)點的datapath中的pooling屬性設(shè)為true。設(shè)置之后,LzLazyReplicationManager只是將改變了的數(shù)據(jù)重新指向已經(jīng)被創(chuàng)建的視圖。這樣用戶界面所反映出的數(shù)據(jù)更新速度會明顯加快,具體的應(yīng)用見列表3.4。


列表3.4 使用pooling屬性

            <view>
    <datapath xpath="dset:/phonebook/contact" pooling="true" />
    <simplelayout axis="y" />
    <view name="list" >
      <!-- more... -->
    </view>
</view>
          

?



回頁首

?

4. 性能比較和分析

4.1 測試方法和模型

最后,我們將對本文提及的實驗進行性能的監(jiān)測和調(diào)試。根據(jù)上文的原則,我們采用OpenLaszlo 3.3.3,對性能優(yōu)化前后的結(jié)果進行比較。表4.1展示了實驗的具體配置。


表4.1 實驗環(huán)境的配置

CPU 內(nèi)存大小 Total paging space 瀏覽器類型
1698MHz 512MB 1.22GB Mozilla Firefox 1.5.0.4

測量OpenLaszlo代碼的性能分為兩種:加載時間和響應(yīng)時間。前者說明了OpenLaszlo的應(yīng)用在多久之內(nèi)被初始化,而后者則是衡量程序能夠響應(yīng)用戶動作的敏捷程度,比如在通訊錄應(yīng)用中完成"刪除"功能的時間長度。對于這兩種時間,我們都在程序開始和結(jié)尾記錄時間,然后將兩者相減,得到最后的結(jié)果。列表4.2展示了這種方法的實現(xiàn)代碼。


列表4.2 測量響應(yīng)時間

            <button width="80" text="Delete">
    <method event="onclick">
        var pre = (new Date).getTime(); //記錄開始執(zhí)行時間
        parent.parent.parent.datapath.deleteNode();
        var cur = (new Date).getTime(); //記錄結(jié)束時間
        debug.write(cur - pre); //輸出
    </method>
</button>
          

?

4.2 測試結(jié)果

我們分別對通訊錄中有3條、9條和30條記錄的情況做了比較。我們逐項應(yīng)用上述的原則:所有表示時間的實驗數(shù)據(jù)單位為毫秒(ms)。最后的結(jié)果由10次操作的平均時間得到。首先,我們將 "initstage = defer"前后的初始化時間的比較列在表4.3。可以看到,在聯(lián)系人的細節(jié)視圖不被加載的時候,初始化的時間有了明顯的加快。


表4.3使用defer的性能比較

記錄數(shù)目 initstage = defer(ms) initstage = normal(ms) 降低幅度(%)
3 268.4 3277.8 91.82
9 433.6 10816.8 95.99
30 955.2 54734.7 98.25

其次,表4.4展示了在使用"pooling"前后的響應(yīng)時間。


表4.4 使用pooling的響應(yīng)時間比較

記錄數(shù)目 pooling = true(ms) pooling = false(ms) 降低幅度(%)
3 28.00 136.14 79.43
9 77.00 728.00 89.42
30 467.67 3079.25 84.81

最后,本文描述"lazy"選項的效果,如表4.5所示。不難看出,"lazy"選項與上述的選項不同,沒有隨著記錄的增多而對性能有顯著的改善。顯然,這是因為"lazy"針對的是單個更新視圖的初始化時間,和總體記錄的條數(shù)沒有明顯的關(guān)系。


表4.5 使用lazy的性能比較

記錄數(shù)目 dataoption = true(ms) dataoption = none(ms) 降低幅度(%)
3 838 7213.6 88.38
9 852 7344.5 88.40
30 961.4 8587.1 88.80

?



回頁首

?

5. 總結(jié)及今后的工作

本文為OpenLaszlo的開發(fā)者提供了一些提高程序性能的技巧,具體包括:延緩初始化的時間、惰性復(fù)制和緩存數(shù)據(jù)。我們通過擴展OpenLaszlo開發(fā)指南中的示例,向讀者展示了一個略微復(fù)雜的通訊錄應(yīng)用。以其為場景分析了系統(tǒng)的性能瓶頸,將作者所總結(jié)出的技巧應(yīng)用于其上。最后,我們還對每個具體的原則做了實驗,比較了性能的差異。從我們的實驗中可以看到,本文所提及的原則對性能的提高有著顯著的作用。相應(yīng)的用戶體驗也有了明顯的提升,達到了用RIA開發(fā)的目的。

在今后的工作中,我們將進一步優(yōu)化這個示例,使其成為一個能和后臺Java Server進行交互的應(yīng)用,并開發(fā)出相應(yīng)的OpenLaszlo組件。更進一步的,我們會在此基礎(chǔ)上為應(yīng)用添加更多(諸如全球化)的特性。

OpenLaszlo學(xué)習(xí)筆記(一)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論