兩年前,我們開發了一套基於Flash的檔(主要是圖片)上傳RIA應用,提供給阿裡巴巴的使用者使用。 如果你使用過Wordpress或flickr上傳圖片,你應該已經用過類似的產品。 這個程式基於YUI Uploader開發,增加了一個實用的功能——在用戶端先將圖片縮小,再上傳到伺服器。 使用者用數碼相機拍攝的照片往往有600萬以上的圖元,但產品圖片放到阿裡巴巴網站上顯示,並不需要這麼大的圖元,通常等比例縮小到1024×1024之內就可以了。 借助于Flash對圖片先縮小再上傳的技術,我們在沒有增加伺服器投入的情況下,將原先上傳圖片的尺寸限制由250KB/張提升到了5MB/張。 同時,Flash上傳還比傳統HTML表單方式上傳有更好的體驗,例如可以多選一批次檔同時上傳、可以即時展示上傳進度、選擇檔時可以過濾非圖片檔。
這個元件獲得了很大的成功。 上線後不久,阿裡巴巴網站上使用者的圖片上傳數量由日均1萬張左右上升至日均15萬張左右。 但在這個上傳應用投入應用的兩年中,我們遇到了各種問題。
1. BUG
在基於IE多標籤瀏覽器中的偽沙箱問題就不說了,最嚴重的是cookie的問題。 使用FileReference.upload的方式上傳檔,HTTP請求中附帶的cookie資訊不一定是當前瀏覽器進程的cookie,在Firefox、chrome等非IE瀏覽器中非常嚴重, 可能傳輸的是IE中的cookie。 即便是IE,也可能傳輸的cookie內容和當前頁面的cookie記錄不符合。 這直接導致伺服器端在收到檔之後的安全驗證中失敗。 而對於阿裡巴巴這樣的大型網站,有比較成熟的java web框架,要去掉對cookie的依賴非常麻煩。 於是結果就是,首先我們只有在使用者使用IE系瀏覽器的時候才使用Flash上傳,其次我們隔三岔五的還會收到使用IE的某些客戶的投訴,在花費了大量的時間排查之後,我發現是由於cookie的問題導致上傳失敗。 這個bug已經存在很多年,但是隨著Flash從9升級到10,許多版本過去了,問題依然沒有被解決。 對於閉源的Flash,我們也幫不上忙。
2.性能
相對於現今數碼相機的圖元量,5MB的大小限制非常保守。 但大於5M的時候,在一些低配置的電腦上,讀取檔內容的時候就會發生瀏覽器假死現象。 假死很容易導致瀏覽器崩潰,所以我們採取了保守的限制——5MB。
另外一個性能消耗是將BitmapData編碼成JPEG檔的時候。 Adobe提供了JPEGEncoder,但由於是Array實現的,所以性能是個問題。 編碼一個2880×2880的圖片在一台中等配置的電腦上大約需要15秒時間。
我用Vector改寫了這個類,時間縮短為3.5秒左右。 使用Alchemy,時間進一步縮短到1.5秒左右。 但還是不夠安全,所以最後採用了非同步Vector的方式,延長編碼的時間,以保證程式的穩定性。 (評測在這裡)
3.圖片品質
Flash內置的最好的圖片縮小演算法(用BitmapData.draw,並將smoothing參數設為true),在縮小圖片的時候容易產生鋸齒。 因此我改寫了Jacwright提供的縮小演算法,圖片品質的問題解決,但代價是性能又降低了一些。
4.安全限制
Flash10.0之後,增加了一個安全限制——當URLLoader以標準檔上傳的方式發送POST請求的時候,需要由使用者的UI操作(滑鼠點擊或按鍵事件)觸發。 因為我們對使用者的圖片做了處理,已經無法再通過FileReference上傳,只能通過URLLoader。 這個安全性限制規定每次發起一個上傳檔的URLLoader請求,都必須讓使用者點擊一下滑鼠才可以。 如果使用者選擇了20張圖片,就要點擊20次滑鼠。 這顯然是無法接受的。 因此我們放棄了用標準檔上傳,採用普通post形式。 代價是失去了對上傳進度的跟蹤,不知道檔上傳的百分比;同時伺服器端也需要改造。
改變
最近,我們做了一個決定:開發一個類似功能的ActiveX控制項,替代Flash作為圖片上傳的主要解決方案。 ActiveX的優勢是性能,不足之處在于只能在Windows+IE瀏覽器中使用,但實際上我們的Flash上傳目前也只能在IE中使用。 Flash真的適合像阿裡巴巴這樣的網站使用嗎? 閉源和性能是Flash最大的問題。 但在HTML5被廣泛支援前,Flash和傳統Ajax還是我們最主要的富用戶端應用開發技術,相對於ActiveX、Silverlight、JAVAFX、Gear等技術來說,Flash還是有安裝率優勢的。 我們看到Adobe最近在新功能開發方面非常給力,值得稱讚,但基礎的功能的持續完善對開發者也同樣重要。 目前Flash依然是我們很重要的RIA技術,但是HTML5完全到來的那一天,現在很難說。
來源:HTTP://www.ued163.com/?p=1813