分步驟詳細解說:H5性能優(yōu)化方案
H5性能優(yōu)化意義
對于一個H5的產(chǎn)品,功能無疑很重要,但是性能同樣是用戶體驗中不可或缺的一環(huán)。原本H5的渲染性能就不及native的app,如果不把性能優(yōu)化做起來,將極大地影響用戶使用產(chǎn)品的積極性。
用戶感受
當 用戶能夠在1-2秒內(nèi)打開H5頁面,看到信息的展示,或者能夠開始進行下一步的操作,用戶會感覺速度還好,可以接受;而頁面如果在2-5秒后才進入可用的 狀態(tài),用戶的耐心會逐漸喪失;而如果一個界面超過5秒甚至更久才能顯示出來,這對用戶來說基本是無法忍受的,也許有一部分用戶會退出重新進入,但更多的用 戶會直接放棄使用。
一秒鐘法則
移動互聯(lián)網(wǎng)的架構(gòu)、通訊機制,與有線網(wǎng)絡(luò)有著巨大的差異,這也給H5的開發(fā)帶來了很大的挑戰(zhàn)。
這是一張手機端接入服務(wù)器的流程。
首 先,手機要通過無線網(wǎng)絡(luò)協(xié)議,從基站獲得無線鏈路分配,才能跟網(wǎng)絡(luò)進行通訊。無線網(wǎng)絡(luò)基站、基站控制器這方面,會給手機進行信號的分配,已完成手機連接和 交互。獲得無線鏈路后,會進行網(wǎng)絡(luò)附著、加密、鑒權(quán),核心網(wǎng)絡(luò)會檢查你是不是可以連接在這個網(wǎng)絡(luò)上,是否開通套餐,是不是漫游等。核心網(wǎng)絡(luò)有SGSN和 GGSN,在這一步完成無線網(wǎng)絡(luò)協(xié)議和有線以太網(wǎng)的協(xié)議轉(zhuǎn)換。再下一步,核心網(wǎng)絡(luò)會給你進行APN選擇、IP分配、啟動計費。再往下面,才是傳統(tǒng)網(wǎng)絡(luò)的步 驟:DNS查詢、響應(yīng),建立TCP鏈接,HTTP GET,RTTP RESPONSE 200 OK,HTTP RESPONSE DATA,LAST HTTP RESPONSE DATA,開始UI展現(xiàn)。
可見,通過運營商的網(wǎng)絡(luò)上網(wǎng),情況比較復(fù)雜,經(jīng)過的節(jié)點太多;運營商的網(wǎng)絡(luò)信號強度變化頻繁,連接狀態(tài)切換快;網(wǎng)絡(luò)延遲高、丟包率高;網(wǎng)絡(luò)建立連接的代價高,傳輸速度快慢不等(從2G到4G,相差很大)。
而我們優(yōu)化的目標,就是所謂的一秒鐘法則,即達成以下的標準:
-
2g網(wǎng)絡(luò):1秒內(nèi)完成dns查詢、和后臺服務(wù)器建立連接
-
3g網(wǎng)絡(luò):1秒內(nèi)完成首字顯示(首字時間)
-
wifi網(wǎng)絡(luò):1秒內(nèi)完成首屏顯示(首屏?xí)r間)
#p#
優(yōu)化方案
資源加載首屏加載
用戶從點擊按鈕開始載入網(wǎng)頁,在他的感知中,什么時候是“加載完成”?是首屏加載,即在可見的屏幕范圍內(nèi),內(nèi)容展現(xiàn)完全,loading進度條消失。因此在H5性能優(yōu)化中,一個很重要的目的就是盡可能提升這個“首屏加載”的時間,讓它滿足“一秒鐘法則”。
按需加載
首先要明確,按需加載雖然能提升首屏加載的速度,但是可能帶來更多的界面重繪,影響渲染性能,因此要評估具體的業(yè)務(wù)場景再做決定。
Lazyload
Lazyload,即延遲加載,這并不是一個新的技術(shù),在PC時代也是非常常用的一種性能優(yōu)化手段。這個方案的原則是讓屏幕外,或者不影響整體效果顯示的圖片、背景等資源,在界面就緒之后再進行網(wǎng)絡(luò)加載。
滾屏加載
滾 屏加載是一種常見的無刷新動態(tài)加載數(shù)據(jù)的方案,通常用在列表形式數(shù)據(jù)展示中。一方面,數(shù)據(jù)不是通過翻頁進行加載,這樣就避免了再一次請求和渲染整個頁面; 另一方面,數(shù)據(jù)顯示的數(shù)量是受限的,例如第一次只請求了10條數(shù)據(jù),也就只需要渲染這10條數(shù)據(jù),下拉滾屏的時候,再去獲得下面10條數(shù)據(jù)。
Media Query(響應(yīng)式加載)
響應(yīng)式設(shè)計是現(xiàn)在網(wǎng)站設(shè)計的一個流行趨勢,隨著移動互聯(lián)網(wǎng)的發(fā)展,這項技術(shù)也越來越受到重視。通過這項技術(shù),我們能夠方便地控制資源的加載與顯示,例如說在分辨率不同的手機上,分別使用不同的css,加載不同大小的圖片資源。方案參考: http://www.poluoluo.com/jzxy/201206/167034.html
第三方資源異步加載
第三方資源有的時候不可控,比如說頁面統(tǒng)計、地圖顯示、分享組件等,這些第三方資源使用的時候要慎重選擇,充分考察它們對于性能的影響,使用異步加載的方式進行,防止第三方資源的使用影響到頁面本身的功能。
Loading進度條
在加載時間較長的時候,務(wù)必要讓用戶明確感知到加載完成的提示,通常是在加載過程中顯示Loading的進度條,加載完成的時候隱藏它。從心理上,這會讓用戶有一種“期盼感”,而不至于太過枯燥。
對于一些重量級的H5應(yīng)用,例如游戲,開始前需要加載很多資源才能讓后面的游戲過程更為流暢,一個帶百分比進度顯示的進度條就更加重要。
避免30*/40*/50*的http status
-
200是一個正常的response,我們在瀏覽器中打開一個網(wǎng)頁(后面會講如何針對移動端進行調(diào)試),還會看到304,即命中瀏覽器緩存。這兩種狀態(tài)是正常的http status。
-
302、301跳轉(zhuǎn)是常見的跳轉(zhuǎn),尤其前一種,在我們進行鑒權(quán)的時候有時會用到,但這個做法要盡可能地優(yōu)化,一個頁面訪問,最多只進行一次302跳轉(zhuǎn)即可,切忌頻繁地跳轉(zhuǎn)。
-
404、 500,我們對自己開發(fā)的代碼比較注意,一般不會發(fā)生,但是有的時候,加載第三方庫,尤其是第三方庫中有自己load組件的操作,這時,404和500錯 誤可能會在你不知不覺的時候發(fā)生。例如釘釘?shù)牡谌轿?yīng)用中,就遇到過dojo的組件加載問題,加載的一些子組件失敗了,但是又沒有影響頁面顯示,這就很 容易被忽略。后面也會再講,如何去測試和發(fā)現(xiàn)這樣的隱患。
Favicon.ico
如果我們沒有設(shè)置圖標ico,則會加載默認的圖標:域名目錄下的favicon.ico。很多開發(fā)者沒有注意到這一點,就會導(dǎo)致這個請求404或者500。
通常,我們在應(yīng)用內(nèi)部打開網(wǎng)頁,不會顯示這個圖標出來(除非放到瀏覽器中顯示網(wǎng)頁),我們需要保證這個圖標存在,盡可能地小(一般4KB以下),并且設(shè)置一個較長的緩存過期時間。
圖片的使用格式選擇
顯示效果較好的圖片格式中,有webp、jpg和png24/32這幾種常見的圖片格式。一般來說,webp的圖片最小,但在iOS或者android4.0以下的系統(tǒng)中可能會有兼容性問題需要解決。
-
Jpg是我們最常使用的方案,大小適中,解碼速度快,兼容性問題也基本不存在,是我們在H5的應(yīng)用中使用起來性價比最高的方案。
-
Png24或png32,一般來說,顯示效果肯定會比jpg更好,但是實際上人眼很難感知出來,所以在H5應(yīng)用中要避免這種格式的大圖片。
對于少量的圖片,推薦用智圖或者tinypng等工具來幫助自己選擇合適的大小、格式。
像素控制
在H5應(yīng)用中,圖片的像素要嚴格控制,一般來說不建議寬度超過640px。
小圖片合并
在html網(wǎng)頁中,如果有多個小圖片需要加載,不妨試試CSS Sprites方案,尤其是一些基本不變,大小差不多的操作類型圖標。
避免html代碼中的大小重設(shè)
在 html或者css中,如果有類似width: **px這樣的代碼,就要注意看一看了,如果說圖片顯示的效果是寬度100px,而下載的圖片卻是200px寬度,那這大小基本上就是所需要的4倍面積 了,所以在H5應(yīng)用中,使用圖片的一個原則就是需要顯示成多大,就下載多大的資源。
避免DataURL
DataURL是用 Base64的方式,將圖片變成一串文本編碼放入代碼的方式。這種方式有好處,因為它可以減少一次http交互的請求,對于一些體積特別小的圖片,或者是 動態(tài)生成的圖片可以考慮使用。但在H5應(yīng)用中,一般情況下,我們都是需要避免DataURL的,因為它的數(shù)據(jù)體積通常比二進制圖片的格式大1/3,而且它 不會被瀏覽器緩存,每次頁面刷新都需要重新加載這部分數(shù)據(jù)。
使用圖片的替代(css3, svg, iconfont)
CSS3和svg可以更好地使用GPU進行渲染加速,而且會避免增加圖片資源導(dǎo)致的http請求增加。例如一些div的圓角效果,就完全可以用用css來實現(xiàn)。
Iconfont,可以認為是一種矢量類型的操作字體。如果頁面中有較多的操作圖標,可以考慮使用iconfont來替代圖片資源。
域名/服務(wù)端部署Gzip
服務(wù)端要開啟Gzip壓縮。
資源緩存,長cache
合理設(shè)置資源的過期時間,尤其對一些靜態(tài)的不需要改變的資源,將其緩存過期時間設(shè)置得長一些。
分域名部署(靜態(tài)資源域名)
將動態(tài)資源和靜態(tài)資源放置在不同的域名下,例如圖片,放在自己特定的域名下。這樣的好處是,靜態(tài)資源請求時,不會帶上動態(tài)域名中所設(shè)置的cookie頭信息,從而減少http請求的大小。
減少Cookie
盡量減少Cookie頭信息的大小,因為這部分數(shù)據(jù)使用的是上行流量,上行帶寬更小,所以傳輸速度更慢,因此要盡量精簡其大小。
CDN加速
部署CDN服務(wù)器,或者使用第三方的CDN加速服務(wù),優(yōu)化不同地域接入網(wǎng)站的帶寬速度。
代碼資源Javascript, CSS合并
盡量將所有的js和css合并,減少資源請求的次數(shù)。
外聯(lián)使用js, css
外聯(lián)使用js和css,這樣可以有效地利用緩存,避免html頁面刷新后重新加載這部分代碼。
壓縮html, js, css
壓縮代碼,尤其是js和css資源,壓縮后的大小可以降低至原來的1/3以下,有效節(jié)約流量。
#p#
資源的版本更新
庫js、css通常不會更新,但是我們的業(yè)務(wù)js和css可能會有更新,如果命中瀏覽器緩存,可能會讓一些新的特性不能及時展現(xiàn),甚至可能導(dǎo)致邏輯上的沖突。
因此對于這些js、css的資源引入,最好用版本號或者更新時間來作為后綴,這樣的話,后綴不變,命中緩存;后綴改變,瀏覽器自動更新最新的代碼。
Css位置
CSS要放到html代碼的開頭的head標簽結(jié)束前。如果網(wǎng)頁是動態(tài)生成的,那么在head代碼完成后可以強制輸出(例如php的flush()操作),這樣的話,瀏覽器就會更快地解析出來head中的內(nèi)容,開始下載css文件資源。
Js位置
Js放到</body>前,這樣的話,js的加載不會影響初始頁面的渲染。
代碼規(guī)范避免空src
圖片設(shè)置為空的src地址,在某些瀏覽器中可能會導(dǎo)致增加一個無效的http請求,因此要避免。
避免css表達式
可能會讓頁面多次執(zhí)行計算,造成卡頓等性能問題。
避免空css規(guī)則
降低css渲染計算的成本
避免直接設(shè)置元素style
直接設(shè)置style屬性,一方面在html代碼中不利于緩存,另一方面也不利于樣式的復(fù)用,因此要避免,通過指定id或者class的方式,在css代碼塊中進行樣式調(diào)整。
服務(wù)端接口接口合并
如果頁面需要請求兩部分以上的數(shù)據(jù)接口,建議將其合并,否則會增加一次http請求。
減少接口數(shù)據(jù)量
有的時候,服務(wù)端會把一些無關(guān)緊要的數(shù)據(jù)返回回來,尤其是類似于更新時間、狀態(tài)等信息,如果在客戶端不影響內(nèi)容的邏輯展示,不妨在接口返回的數(shù)據(jù)中直接去掉這些內(nèi)容。
緩存
緩存接口數(shù)據(jù),在一些數(shù)據(jù)新舊敏感性不高的場景下很有作用,在非首次加載數(shù)據(jù)時候優(yōu)先使用上次請求來的緩存數(shù)據(jù),可以讓頁面更加快速地渲染出來,而不用等待一個新的http請求結(jié)束之后再渲染。這一點我們在后面還會再次提及。
其他一些建議
-
合理使用css
-
正確使用Display屬性Display屬性會影響頁面的渲染,因此請合理使用
-
display:inline后不應(yīng)該再使用width、height、margin、padding以及float
-
display:inline-block后不應(yīng)該再使用float
-
display:block后不應(yīng)該再使用vertical-align
-
display:table-*后不應(yīng)該再使用margin或者float
-
-
不濫用float
-
不聲明過多的font-size
-
值為0時不需要單位
-
標準化各種瀏覽器前綴
-
無前綴應(yīng)放在最后
-
CSS動畫只用 (-webkit- 無前綴)兩種即可
-
其它前綴為 -webkit- -moz- -ms- 無前綴 四種,(-o-Opera瀏覽器改用blink內(nèi)核,所以淘汰)
-
-
選擇器
-
避免讓選擇符看起來像是正則表達式。高級選擇器不容易讀懂,執(zhí)行耗時也長
-
盡量使用ID選擇器
-
盡量使用css3動畫
-
資源加載
-
使用srcset
-
首次加載不超過1024KB(或者可以說是越小越好)
-
html和js
-
減少重繪和回流
-
緩存dom選擇和計算
-
緩存列表.length
-
盡量使用事件代理,避免批量綁定事件
-
使用touchstart,touchend代替click
-
Html使用viewport
-
減少dom節(jié)點
-
合理使用requestAnimationFrame動畫代替setTimeOut
-
適當使用Canvas動畫
-
TouchMove, Scroll事件會導(dǎo)致多次渲染
更快一步
前面的很多建議與普通的PC端web網(wǎng)頁的開發(fā)是一致的,但是在移動互聯(lián)網(wǎng)應(yīng)用下,僅僅做到這些,可能只有60分,那么怎樣才能得到80分甚至更高?
單頁應(yīng)用
釘釘?shù)膶徟?yīng)用,使用的就是單頁架構(gòu)。在這種架構(gòu)下,基本不存在頁面跳轉(zhuǎn)的等待時間,只需要執(zhí)行js邏輯觸發(fā)界面變化,最多進行一次網(wǎng)絡(luò)請求,獲得服務(wù)端數(shù)據(jù),其他資源均不需要再次請求。
#p#
資源離線
再快的網(wǎng)絡(luò)交互,畢竟也是跨越了數(shù)個網(wǎng)絡(luò)節(jié)點,因此一張圖片、一個js,優(yōu)化到了極致,也照樣可能需要幾百毫秒的時間來獲得。因此想要打破這個極限,就要使用資源離線的策略。
在釘釘?shù)奈?yīng)用中,就使用了這樣的一個“離線包”策略。一些固定的圖片、js庫等,被打包放入app中(或根據(jù)需要,在app啟動的時候進行下載更新)。
微應(yīng)用中,網(wǎng)頁代碼里面加載網(wǎng)絡(luò)資源的需求,就變成了直接加載本地文件,速度自然得到再一次巨大的提升。
本地數(shù)據(jù)持久化和更新機制(版本管理)
對于一些時效性沒有那么高的數(shù)據(jù),可以考慮將接口數(shù)據(jù)緩存。那么頁面的渲染將變成這樣的流程:
而非首次進入界面,流程如下:
可以看出,在非首次進入界面的時候,頁面不需要等待網(wǎng)絡(luò)數(shù)據(jù)返回,就可以進行界面渲染,渲染的初始數(shù)據(jù)來自于本地的緩存,頁面可以“秒開”。而當服務(wù)端的數(shù)據(jù)返回之后,本地的渲染會再次更新,緩存也被更新。
采用這樣的方案有利有弊,好處顯而易見,首屏加載的速度簡直太快了——靜態(tài)資源來自本地,數(shù)據(jù)接口來自本地,這在2G、3G或者其他網(wǎng)絡(luò)速度較慢的時候,也可以讓用戶在極短的時間內(nèi)就看到內(nèi)容。但是這種方案也并非萬能。
-
首次加載不可避免,還是會請求網(wǎng)絡(luò)。
-
服務(wù)端有更新的時候,客戶端不能夠快速感知,頁面可能還停留在一個“舊的版本”上,尤其是網(wǎng)絡(luò)速度較慢時,可能還是需要經(jīng)過好幾秒,頁面才會更新至最新版本。因此如果應(yīng)用對數(shù)據(jù)的新舊很敏感的話,這種方案就不適合
-
數(shù)據(jù)更新后,需要重新渲染界面,界面刷新的性能消耗比正常情況更多,而且增加了程序的復(fù)雜度,容易出錯。
預(yù)加載
有 時,我們能夠通過用戶的行為統(tǒng)計,預(yù)判出用戶下一步可能進行的操作。假設(shè),我們統(tǒng)計出來針對某個微應(yīng)用,用戶首頁渲染完成之后,大部分會點擊列表中的第一 個項目查看詳情。那么在首頁渲染完成之后,我們就可以先預(yù)先加載第一個項目的部分內(nèi)容,那么針對這部分用戶,他們實際點擊之后,立即就能看到新的頁面中的 內(nèi)容。
當然,這個方式也并不是在所有場景下都使用。一方面,需要做好充分的用戶調(diào)研,掌握用戶的使用習(xí)慣;另一方面,對于小部分用戶而言,預(yù)加載所帶來的就是不必要的流量消耗。
#p#
測試方案
工具準備Chrome
在功能測試中,我們通??梢杂胏hrome來測試不同的分辨率下,或是不同的設(shè)備上,網(wǎng)頁的展現(xiàn)情況。在我們做性能優(yōu)化的時候,也可以用這種方式來進行調(diào)試,方便地觀察在特定設(shè)備上,靜態(tài)資源是否按照我們想象的那樣去加載了。
例如,我們想看下百度首頁在某個設(shè)備下的表現(xiàn)。通過F12進入控制臺,點擊圖中的短箭頭標示出來的那個設(shè)備圖標,然后就可以在Device和Network中選擇不同的設(shè)備和網(wǎng)絡(luò)狀況。
例如iphone5下,這個地圖的圖標,明顯就可以看到是用iconfont來實現(xiàn)的效果。
當然,這個功能也僅僅是一種模擬,通過控制屏幕分辨率、UserAgent等來模擬設(shè)備請求,在實際的設(shè)備上,又該怎么查看呢?
還是Chrome,我們在地址欄中輸入chrome://inspect(注意:Android版本需要是4.4+,并且應(yīng)用中的WebView必須進行相應(yīng)的調(diào)試聲明配置)
在這里點擊inspect,則可進入我們熟悉的F12控制臺界面,只不過debug的對象變成了我們在手機應(yīng)用中的網(wǎng)頁。
輸 入performance.timing.domComplete - performance.timing.navigationStart,就可以打印出網(wǎng)頁加載的時間,domComplete表示所有的處理都已完成并 且所有的附屬資源都已經(jīng)下載完畢。navigationStart表示開始加載新頁面。兩者相減,就代表這個網(wǎng)頁完成渲染所需要的時間了。
同樣地,我們可以在Elements tab中,debug網(wǎng)頁,查看各個資源的使用,在Network中,看看加載了哪些資源,是否都做過了壓縮。
然 而,這種方式,還是有一定缺陷。1. 如果打開網(wǎng)頁經(jīng)過了跳轉(zhuǎn),那么我們只能在這里看到最后一個url頁面的加載情況。2. 第一次打開頁面的時候,在Network中,默認是不顯示請求的詳情的,當我們選擇了preserve log upon navigation之后才會捕獲,因此首次進入頁面的加載情況,我們就很難獲得了。
那么有沒有一種方法,讓我們能夠更方便地去查看首次訪問時,各種資源的加載使用情況呢?
Charles
Charles Proxy,可以說是H5測試的一個神器。它的作用是在PC端開啟一個代理服務(wù)器,手機連到這個代理服務(wù)器上之后,所有的http請求就都可以在這里看得清清楚楚。經(jīng)過配置證書選項,https的請求也可以正常查看。
從圖中,我們明顯可以看到,有一些404的異常請求,這些都將對我們H5應(yīng)用的性能造成影響。如果我們發(fā)現(xiàn)有一些資源的Duration比較大,那這些可能是服務(wù)端響應(yīng)太慢,自然也可以作為我們優(yōu)化的依據(jù)。
#p#
測試標準
在釘釘?shù)臏y試中,形成了一套標準。
指標項 遵循的原則 優(yōu)先級 檢查項 說明 內(nèi)存 內(nèi)存無泄漏 P0 主功能頁面反復(fù)打開,功能的重復(fù)調(diào)用,內(nèi)存無泄漏 可以使用sysdump,也可以用我們開發(fā)的perfeasy工具進行觀察 P1 主功能頁面,持續(xù)操作,退出后,內(nèi)存占用不超過總內(nèi)存的5% perfeasy CPU 減少無端的CPU使用 P1 滅屏,靜置2分鐘,在5分鐘內(nèi)CPU使用平均1% adb連接后, 使用top命令 主干功能正常操作CPU占用不超過60%, 持續(xù)5秒 perfeasy 電量 避免無端電量消耗 P0 滅屏狀態(tài)下,無線程持續(xù)運行 一般來說, 靜置cpu正常, 這一項就沒有問題 滅屏,window.setTimeout()方法停止 一般來說, 靜置cpu正常, 這一項就沒有問題同上 滅屏,window.setInterval()方法停止 同上 ajax超時時間設(shè)置為5000ms以內(nèi) 結(jié)合代碼 ajax無retry邏輯 結(jié)合代碼 資源 資源的正確使用 P0 是否存在資源的重復(fù)拉取 charles P1 H5頁面首屏總大小不超過200K charles, chrome P1 抓包檢查(js/css/html)代碼去除了空格/注釋,JS文件變量名變成a/b等代替 charles, chrome P1 H5引用的單張圖片小于60K charles, chrome
如 果影響了顯示質(zhì)量, 可酌情調(diào)整 流暢度 確保給到用戶流暢的展示體驗 P1 流暢的實時動畫展示,avgFPS>=45 perfeasy 時延 確保給到用戶流暢的切換體驗 P0 wifi網(wǎng)絡(luò)下,首次進入頁面onload時間<1000ms Chrome 時延 確保給到用戶流暢的切換體驗 P0 wifi網(wǎng)絡(luò)下,首次進入頁面onload時間<1000ms Chrome wifi網(wǎng)絡(luò)下,非首次進入頁面onload時間<500ms Chrome 3G正常網(wǎng)絡(luò), 首次進入頁面onload時間<2000ms chrome, 樹莓派模擬3G 3G正常網(wǎng)絡(luò), 非首次進入頁面onload時間<1000ms chrome, 樹莓派模擬3G
經(jīng)典案例
圖片未優(yōu)化
通過charles可以方便地進行測試。從請求監(jiān)控的情況看,有一張圖片超過了60KB,寬度640px,但是在應(yīng)用中,實際顯示的是一張小縮略圖,是通過代碼控制讓它顯示成小圖的,因此修改方案很簡單,將所有頭像的圖片均改為獲取120px寬度的即可。
按需加載
-
釘釘?shù)慕虒W(xué)頁面
-
多個slide頁面, 每個頁面有2-3個圖片, 其中有一個是大圖顯示
-
圖片是客戶提供的, 最大的圖片大約是300KB以上
-
第一次進入頁面后, 所有slide的圖片均進行加載
-
3G網(wǎng)絡(luò)下, loading的圖標大約持續(xù)6000ms后才會消失
-
優(yōu)化方案
-
盡可能優(yōu)化圖片, 但是壓縮后發(fā)現(xiàn)噪點明顯增加, 影響了顯示效果
-
修改加載方案, 第一次進入后, 只加載本頁的圖片
-
loading時間降低至1秒左右