大規模WebGL應用引發瀏覽器崩潰的幾種情況及解決辦法

一般的Web應用基本上不會導致瀏覽器崩潰,寫Javascript代碼也不需要管理內存資源,基本也不需要考慮內存“泄露”的問題。隨着H5的崛起,越來越多的原本在桌面端的軟件也改頭換面遷移到Web上來,比如三維圖形類的應用。在Web端顯示大規模三維模型不僅僅是三維顯示引擎的問題,也涉及到數據組織、任務調度、資源管理、瀏覽器兼容等方方面面。這裏針對在項目中遇到到幾種把瀏覽器高掛的情況簡要列舉了一下。

異步請求過多
瀏覽器對併發異步請求是有限制的。如果程序不做處理,“同時”發送幾百個請求就可能導致瀏覽器崩潰。

解決這樣的問題涉及到數據管理的問題。有的需要多次請求得到的數據可以重新組織在一次或幾次請求完成。如果就是需要若干次請求,就需要把請求排隊,用多個異步請求隊列加載數據。

併發異步請求資源死鎖
若一個資源被多個異步請求同時請求的時候就可能導致瀏覽器死鎖,死鎖的結果就是瀏覽器崩潰。默認瀏覽器都是啓用cache的,而瀏覽器在從cache中讀取數據的時候會加鎖。

就需要在組織異步請求隊列的時候,相同的資源不能在不同的隊列中出現

GPU進程崩潰
Chrome是多進程架構,每個Tab都會啓用單獨的進程來處理頁面。但,所有的進程都會公用一個GPU進程。

那麼問題來了,如果開啓多個WebGL應用頁面,每個頁面佔用一定的GPU資源,GPU進程的內存加起來總的就會輕輕鬆鬆超過1.5G,結果就是GPU進程崩潰,即使是64位Chrome。

在實際中用WebGL顯示大模型會輕輕鬆鬆的撐爆GPU進程。這就需要顯示引擎要處理好頂點數據的內存佔用。方法有很多種,這裏就不多贅述了。

JS使用內存過多導致崩潰
在上圖中可以看到多個內存:內存、GPU內存、Javascript內存。其中Javascript內存是JS對象佔用的內存,垃圾回收會影響這部分內存。Javascript代碼和垃圾回收運行在同一個線程的環境,當垃圾回收的時候,js代碼不會執行。如果js對象過多,(佔用內存過多),垃圾回收的過程也會變得漫長。所以Chrome簡單粗暴的限制了Javascript內存的佔用,在x64下最大~1.4G。解決這樣的問題需要優化數據結構或者增加數據動態管理的機制。

JS代碼運行Timeout
如果JS運行時間過長,超出一定的時間,瀏覽器就彈個對話框,讓用戶選擇是否結束。相同的代碼在chrome中沒有問題,而在firefox中就可能無響應。

解決方法就是把耗時的算法設計成分部執行,結合setTimeout或者requestAnimationFrame使用。

總結
相對桌面應用,瀏覽器仍然是一個資源受限的環境:JS執行效率,內存管理,線程……。對於大規模的Web應用,需要不斷的在效率性能和資源佔用上做平衡。

一年半下來,大部分精力花在了debugging中。深深感到,前端能做的事情越來越多,程序的規模也越來越大,對JS程序員的要求也越來越高。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章