一開始以hybrid形式做了一個android的小說閱讀客戶端,叫4G閱讀。而後由於業務需求,要迅速實現純手機html5 版的,所以就直接在原先客戶端內內嵌的網頁進行改版,快速實現以後在優化的過程中發現越改越多越改越多…
注意此web應用只支援android及iphone內的瀏覽器,及PC或mac上的chrome,safari,firefox等支援html5的瀏覽器。IE10以上瀏覽器
這算是試驗版了吧,以前沒這麼弄過..
手機訪問http://crapi.4gshu.com:8096/4g-read-qd/#index
先上圖,有圖有真像
檔案結構及路由
HTML
Index.html
整個應用框架的基礎,包含了頭部,尾部HTML,及主要各個頁面部分的容器(content-panel)
根據hash路由通過ajax方式載入對應的內容頁再新增到對應的comtent-panel內
以下是主要內容模組(內容為html片段)
Index-c.html逛
Category-c.html分類
Rank-c.htm排行
Discovery-c.html發現
Channel-c.html男頻,女頻...
Search-c.html搜尋
Bookshelf-c.html書架
Catalog-c.html 目錄
CSS
編寫css時使用了less,特別是在修改時,尤其的好用
Public.css 包含了大部分的應用樣式
Idangerous.swiper.css 切換外掛的樣式檔案
內容頁的樣式可以在自身頁面內自行新增
Javascript
Avalon.js
在此處用這個MV*框架,主要是方便處理將json資料渲染到DOM上
Jquery.js
很想使用zepto之類的輕DOM框架,但最終還是選擇了jquery2.0,原因是方便擴充套件外掛,很多外掛不相容zepto,其實JS檔案的大小遠沒有你想象的那麼影響web應用的表現,其實css的渲染影響更大,血的教訓啊。關於JS檔案過大的問題,其實應用基本上是在3G或wifi情況下使用,你非要在2G環境下使用,那幹麻不用WAP版...
Idangerous.swiper.js
非常強大的輪播外掛,其實可以實現很多東西。所以選用它來實現輪播
Mango-decoupling.js
很好用的訊息外掛,用於程式中解耦設計,其訊息機制也非常強大
Config.js
由於將這個應用分發到不同的渠道,而不同渠道又有一些不同的配置需求,所以用了config.js來配置一些屬性
Core.js
整個框架通用JS的核心,包含了本地儲存,通訊,通用的事件與方法
為了方便實現,及減少JS檔案數,各個內容模組的JS業務邏輯都直接寫在各自的html片段中。內容模組在渲染完畢後應該向框架傳送一個渲染完畢的訊息,或執行框架提開放的渲染完畢API,比如“page_ready”,方便框架處理loading等全域性的控制
本地儲存
1、離線儲存cloudary.appcache,儘可能的將css,js,image,及HTML程式碼片段檔案都離線儲存至本地。初次訪問時會將所有相關檔案都離線到本地,以後再次訪問,會優先讀取離線到本地的檔案
2、Localstorage儲存介面資料。開發過程中明顯感覺到,後臺提供的資料介面的速度明顯影響了整個應用的表現,所以在初次訪問動態資料介面時將使用localstorage將整個介面返回的資料儲存到本地,以後再次訪問時先優先讀取本地的資料,然後後臺會靜默更新資料到localstorage內,由於應用沒有那麼高的實時性要求,所以此方案可行。
Hash路由
整個應用的內容模組content-panel其實是由hash路由來連起來的,構成了所謂的單面應用,即不重新整理整個頁面。一開始使用的是popstate來實現,結果發現在chrome瀏覽器下一進頁面就會觸發一次popstate事件,比較奇葩,這個問題是在應用完成後發現的,還好popstate事件是在core.js中進行過封裝的,我就在封裝處將popstate事件替換成了hashchange事件,所以說對外部的API還是要抱有不信任的態度,儘量進行封裝分隔,萬一發生改變,改起來也快。在載入不同的內容模組時,通過wndow.history的pushState和replaceState來實現hash值的改變,在一進頁面時首先得把自身頁面進行一次replaceState,將自身加入history佇列,否則history佇列會亂(一大坑啊,反正我以前沒replaceState時是遇到過,怎麼也管理不好佇列)。
根據UI上的設計及功能的不同,我將路由分成了兩類,
主頁路由:
Index 逛
Category分類
Rank 排行
Discovery 發現
子頁路由:
Channel頻道
category-detail 分類詳情
Topic 專題
Detail 詳情
Search 搜尋
Bookshelf 書架
Catalog 目錄
關於路由的速度優化
1、很多內容模組開啟過一次後再次開啟時完全是不用再請求的,所以得判斷是否開啟過,開啟過的應用再次開啟時就不再請求對應的html片段了,直接顯示之前請求下來的html片段,比如index,category,rank,discovery,topic,bookshelf,search這幾個內容模組
2、對於需要更新內容的模組,比如detail,channel模組,第一次請求到html片段後也可以快取下來,以後每次請求新的內容時只需要通過JSON資料更新dom即可,即無需把dom清掉再重新建立新dom。這一點的優化對於效能比較差的mobile裝置上尤其重要,這樣實現後,請求資料這個動作需要在路由發生變化時傳送自定義訊息(如:refresh_with_new_data),接受到自定義訊息時再傳送資料請求,得到訊息後再更新dom的內容。
3、即使對於需要更新的內容,同一個連結,連續被開啟時,由於資料完全沒有變化,所以也可以完全不去請求資料,即可做到所謂的“秒開”
理論上應該用但並未使用的技術
1、backbone,算是比較廣泛的mvc框架了,自身提供了路由功能,但個人覺得需要寫的程式碼量太大,如果是團隊使用用來規範程式碼還行,如果個人使用的話,我覺得還是太重了。寫一個簡單的功能就一大堆程式碼及對應的JS檔案。
2、Requirejs或seajs
本身應用中就首頁這幾個JS檔案,寫完就沒了,沒必要再多一個額外的JS檔案請求
3、一些新的CSS3屬性
某些比較好用的CSS3屬性在移動端支援有限,所以沒有使用,比如佈局的兩端對齊
4、較高的內容模組分段顯示,即滾動到了後再渲染到DOM中,首先後臺並未提供分斷載入的API,其次,自適應的佈局加大了實現的難度,最後,木有足夠的時間
不足
1、開發時間過短,很多公司的通病吧
2、產品在設計時未考慮單頁應用的場景,層級太深的頁現在還是重新整理整個頁面
3、有些功能還未按以上的構架實現,比如動態介面本地儲存只做了index首頁等
4、比較醜,樣子醜,程式碼實現也比膠水
No zuo no die
為何在內容模組切換過程中未新增一些像native應用切換一樣的動畫效果?
由於android的機型無花八門,效能參差不齊,css3動畫支援力度不一,很多hybrid應用的出現正是為了彌補這樣的缺點。佈局用html,切換動畫使用native。如果你的web應用只要求跑在iphone這等高大上的裝置上的話,完全可以使用css3來實現介面切換動畫,如果你要求跑在所有平臺上,那麼......該吃藥了親..
如果你非要嘗試,那麼你應該會體會到什麼叫no zuo no die
結束語
優化工作是個系統性工程,得從方方面面考慮,從產品設計--》UI設計--》前端程式碼實現--》後臺資料介面提供
現在的優化只能算是皮毛吧,不僅前端部分需要優化,而且後臺資料介面速度過慢也嚴重導致了響應速度。
純粹的手機web單頁應用本來就做的比較少,經驗太少,需要繼續努力學習..
碼農啊...
有看到這篇文章的同學歡迎提意見,優化方面特別是
========================================================
轉載處請註明:部落格園(王二狗)willian12345@126.com