您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)如何優(yōu)化Ajax中無刷新分頁的性能的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。
Ajax無刷新分頁,已經(jīng)是一個(gè)大家比較熟悉的事物了,大概就是web前端頁面上有一個(gè)js的方法,通過Ajax去請(qǐng)求服務(wù)器端的分頁數(shù)據(jù)接口,拿到數(shù)據(jù)后再在頁面上創(chuàng)建html結(jié)構(gòu),展現(xiàn)給用戶,類似于下面這樣:
<script type=”text/javascript”> function getPage(pageIndex){ ajax({ url:” RemoteInterface.cgi”, method:”get”, data:{pageIndex:pageIndex}, callback:callback }); } function callback(datalist){ //todo:根據(jù)返回的datalist數(shù)據(jù)創(chuàng)建html結(jié)構(gòu)展現(xiàn)給用戶。 } </script>
其中,RemoteInterface.cgi是一個(gè)服務(wù)器端的接口。我們這里限于篇幅,涉及的實(shí)例代碼可能都不是完整的,只為了把意思表達(dá)明白。
UI上,可能會(huì)有各種款式的分頁控件,大家也都比較熟悉,比如:
但無非都是用戶點(diǎn)擊控件觸發(fā)這里的getPage(pageIndex)方法,這個(gè)getPage方法可能不是那么簡(jiǎn)單。
如果按照代碼片段1的寫法,我們可以想象,用戶每次點(diǎn)擊翻頁的時(shí)候,都會(huì)請(qǐng)求一次RemoteInterface.cgi,在忽略數(shù)據(jù)可能有更新的情況下,除了第一次,后面每次getPage(1) 、getPage(2)、getPage(3)等等所觸發(fā)的遠(yuǎn)程接口請(qǐng)求以及在網(wǎng)絡(luò)上往返的數(shù)據(jù)流量,其實(shí)都是重復(fù)的、不必要的。每頁第一次請(qǐng)求的時(shí)候都可以把這些數(shù)據(jù)以某種形式緩存在頁面上,用戶如果有興趣回頭來看之前翻過的頁,getPage方法應(yīng)該先檢查本地緩存當(dāng)中是否包含該頁數(shù)據(jù),如果有,則直接重新展現(xiàn)給用戶,而不是去調(diào)用遠(yuǎn)程接口。按照這個(gè)想法,我們可以把代碼片段1修改一下,如下:
<script type=”text/javascript”> var pageDatalist={}; function getPage(pageIndex){ if(pageDatalist[pageIndex]){ //如果本地的數(shù)據(jù)列表中包含當(dāng)前請(qǐng)求頁碼的數(shù)據(jù) showPage(pageDatalist[pageIndex])//直接展現(xiàn)當(dāng)前數(shù)據(jù) } else { ajax({ url:” RemoteInterface.cgi”, method:”get”, data:{pageIndex:pageIndex}, callback:callback }); } } function callback(pageIndex,datalist){ pageDatalist[pageIndex]= datalist; //緩存數(shù)據(jù) showPage(datalist);//展現(xiàn)數(shù)據(jù) } function showPage(datalist){ //todo:根據(jù)返回的datalist數(shù)據(jù)創(chuàng)建html結(jié)構(gòu)展現(xiàn)給用戶。 } </script>
這樣做一來節(jié)約網(wǎng)絡(luò)請(qǐng)求往返的時(shí)間,更重要的是節(jié)約寶貴的網(wǎng)絡(luò)流量和減輕接口服務(wù)器的負(fù)擔(dān)。在低網(wǎng)速環(huán)境下或者接口服務(wù)器運(yùn)行壓力已經(jīng)比較大的情況下,這種必要的改進(jìn)更能顯現(xiàn)明顯的優(yōu)化效果。大名鼎鼎的yahoo 34條,第一條就是盡量減少HTTP請(qǐng)求次數(shù)。Ajax的異步請(qǐng)求,毫無疑問也是在http請(qǐng)求的范疇內(nèi)。訪問量小的web應(yīng)用或許感覺沒有必要,但是想象一下,如果有一個(gè)這樣的頁面:每天訪問量1000萬次,用戶平均翻5頁,其中有一頁為重復(fù)查看。那么這樣一個(gè)頁面,按照代碼片段1的寫法,平均每天將觸發(fā)5000萬次的數(shù)據(jù)請(qǐng)求,而按照代碼片段2的寫法,則平均每天至少可減少1000萬次請(qǐng)求。如果每次請(qǐng)求的數(shù)據(jù)量是20kb,則可以節(jié)約1000萬*20kb=200,000,000kb 約合190G的網(wǎng)絡(luò)流量。這樣看節(jié)約的資源是相當(dāng)可觀的。
如果要繼續(xù)深究的話,代碼片段2當(dāng)中數(shù)據(jù)緩存方法還值得討論一下。我們前面假定可以忽略分頁數(shù)據(jù)的時(shí)效性,但實(shí)際應(yīng)用里面時(shí)效性卻是個(gè)不能回避的問題。緩存毫無疑問會(huì)導(dǎo)致時(shí)效性的降低,真正的緩存方案應(yīng)該還要依賴對(duì)應(yīng)用時(shí)效性要求的分析和取舍。
對(duì)于一般不是特別強(qiáng)調(diào)時(shí)效性的內(nèi)容,頁面上的緩存應(yīng)該還是可以接受的,一來用戶不會(huì)一直停留在一個(gè)頁面上,頁面之間有跳轉(zhuǎn)造成重新加載時(shí),可以獲得更新后的數(shù)據(jù)。另外如果用戶有刷新頁面的習(xí)慣的話,當(dāng)他特別想看列表是否有數(shù)據(jù)更新的時(shí)候,可以選擇刷新頁面。如果追求完美的話,還可以考慮設(shè)定一個(gè)時(shí)間范圍,比如5分鐘。如果用戶一直停留在當(dāng)前頁面超過5分鐘,那么5分鐘內(nèi)他的翻頁都是先讀取頁面上的緩存,5分鐘以后的翻頁才再次請(qǐng)求服務(wù)器的數(shù)據(jù)。
有些情況,如果我們可以預(yù)知數(shù)據(jù)的更新頻率,比如多少天才可能會(huì)有一次數(shù)據(jù)更新,甚至可以考慮使用本地存儲(chǔ),隔一定時(shí)間才觸發(fā)一次對(duì)服務(wù)器數(shù)據(jù)的請(qǐng)求,這樣對(duì)請(qǐng)求數(shù)和流量的節(jié)約就更加徹底了。當(dāng)然最終什么樣的緩存方法適用,歸根結(jié)底還取決于產(chǎn)品對(duì)時(shí)效性的要求,但原則還是能節(jié)約的請(qǐng)求和流量,盡量節(jié)約,對(duì)于訪問量超大的頁面尤其如此。
對(duì)于時(shí)效性要求高的一類數(shù)據(jù),緩存就完全不適用么?當(dāng)然不是的,只不過整體的思路還得再變一變。一般所謂變化,可能主要是列表當(dāng)中的數(shù)據(jù)有增、減或者改動(dòng),但是絕大多數(shù)的數(shù)據(jù)還是保持不變的。大多數(shù)情況下,前面講的設(shè)定在一段時(shí)間范圍內(nèi)做緩存還是適用的。
如果有接近于要求實(shí)時(shí)更新數(shù)據(jù)的需求,大家可能很容易想到使用定時(shí)器的方法,比如每20秒執(zhí)行一次getPage(pageIndex)方法并重繪列表。但大家只要聯(lián)想到前面1000萬次頁面訪問的假設(shè),就會(huì)發(fā)現(xiàn)這無疑是一件超級(jí)恐怖的事情,按照這種訪問量和重試的頻率,服務(wù)器壓力山大呀。關(guān)于這種情況怎么處理,我想請(qǐng)大家去看一看Gmail、163郵箱和新浪郵箱等對(duì)郵件列表頁的處理方式。它們幾乎同時(shí)滿足了我們之前的假設(shè):超級(jí)大的日訪問量,對(duì)數(shù)據(jù)要求實(shí)時(shí)更新等。用網(wǎng)絡(luò)抓包工具分析一下不難發(fā)現(xiàn),它們?cè)谟脩糁貜?fù)請(qǐng)求同一個(gè)頁碼的數(shù)據(jù)時(shí),都不會(huì)向服務(wù)器發(fā)出請(qǐng)求。為了保證有消息更新時(shí)能夠及時(shí)通知用戶并且更新郵件列表,可以使用一個(gè)定時(shí)、重復(fù)進(jìn)行的異步請(qǐng)求,但是這個(gè)請(qǐng)求只是做一個(gè)狀態(tài)查詢,而不是刷新列表。只有獲取到有消息更新的狀態(tài)時(shí)才會(huì)發(fā)起請(qǐng)求去獲取更新的數(shù)據(jù),或者狀態(tài)查詢的接口在發(fā)現(xiàn)有更新時(shí)會(huì)直接把更新的數(shù)據(jù)返回。事實(shí)上,163郵箱這個(gè)定時(shí)的狀態(tài)查詢,間隔時(shí)間都是設(shè)的比較長(zhǎng)的,大概兩分鐘一次,新浪郵箱這個(gè)時(shí)間間隔更長(zhǎng)一些,大概5分鐘一次,可以了解它們都在盡力減少請(qǐng)求數(shù)量。但是這種處理方式,可能就不是僅前端單方面就能做的,實(shí)現(xiàn)方案需要和后臺(tái)接口整體考慮才行。
現(xiàn)在我們?cè)倩剡^頭來看一下代碼片段2當(dāng)中的數(shù)據(jù)緩存方法?,F(xiàn)在不再討論請(qǐng)求數(shù)量和流量的節(jié)約,我們來看一下前端的實(shí)現(xiàn)上還有沒有什么值得深究一下的。按照代碼片段2示意的處理方式,原始數(shù)據(jù)被儲(chǔ)存起來,當(dāng)再次被調(diào)用時(shí),showPage(datalist)需要再次根據(jù)數(shù)據(jù)去重建html結(jié)構(gòu)展現(xiàn)給用戶,但是之前這個(gè)創(chuàng)建結(jié)構(gòu)的過程我們是有做過的,是不是可以考慮在第一次創(chuàng)建結(jié)構(gòu)的時(shí)候,直接把這個(gè)結(jié)構(gòu)存起來呢?這樣可以減少js重復(fù)的計(jì)算,特別當(dāng)結(jié)構(gòu)比較復(fù)雜時(shí)更值得考慮。再想一下,這個(gè)結(jié)構(gòu)之前在頁面上創(chuàng)建過了,翻頁的時(shí)候銷毀并再次創(chuàng)建新的結(jié)構(gòu),也是耗費(fèi)資源的,能不能第一次創(chuàng)建好了之后,翻頁的時(shí)候不銷毀,只是通過控制CSS樣式給它隱藏起來,重復(fù)翻頁的時(shí)候也只是在這些創(chuàng)建好的結(jié)構(gòu)之間控制彼此顯示或者隱藏?
感謝各位的閱讀!關(guān)于“如何優(yōu)化Ajax中無刷新分頁的性能”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。