簡體   English   中英

某些移動瀏覽器中HTML5 Canvas的性能問題。

[英]Performance problems with HTML5 Canvas in some mobile browsers.

嗨,我有一個Web應該能夠在智能手機和桌面瀏覽器上運行。 雖然我期望在像Iphone這樣的小型設備上獲得一些奇怪的行為,但我非常有信心它會在Android Galaxy Tab上運行良好,這是我現在可以運行測試的Android設備。

現在我在Galaxy Tab上安裝了一堆瀏覽器來測試:

  • Android Native Browser
  • 適用於Android的Chrome
  • 適用於Android的Firefox

在我使用過的桌面上

  • 火狐
  • 谷歌瀏覽器

最后我有一個Iphone來測試。

該網站使用HTML5畫布進行像素和基於精靈的繪制,沒有花哨的變換,濾鏡或效果,主要是簡單的路徑和多邊形。 我會聽觸摸事件並使用requestAnimationFrame進行正確的重繪。

總體而言,該應用程序在桌面瀏覽器上運行良好,它在iOS Safari(iPhone)和Firefox-on-Android上運行良好。 Androids Native Browser給我帶來了麻煩。 我已將其設置為當javascript沒有響應時屏幕刷新紅色,並且在觸摸屏幕時它幾乎總是閃爍。

所以我想知道Android Native App和HTML5是否存在任何已知問題。 由於本機瀏覽器的名稱不存在,因此很難獲得有關此內容的Google信息。 有什么想法,我可以獲得更多信息? 什么可能導致本機Android瀏覽器滯后的想法?

關於這個問題有一些想法:

  • iOS不支持requestAnimationFrame,因此我將其替換為基於超時的替換。 如果我在Android的本機瀏覽器上使用該替換,問題仍然存在。

  • 我經常使用AJAX(google clojure xhrio)從服務器檢索數據。 可能是數據檢索回調是cloggin我的事件管道?

  • 是否已知日志控制台消息(console.log)會降低應用程序的速度? 他們可以觸發瀏覽器重新運行DOM樹或任何相關的東西嗎?

我在很多瀏覽器中都用canvas進行了很多實驗。 我注意到的一些性能問題:

首先,關於你的猜測:

  • 當瀏覽器支持requestAnimationFrame ,繪圖內容和應用程序本身響應更快。 使用setTimeoutsetInterval作為回退始終是可行的,但您需要注意時間。 這種強大的polyfill可能會有所幫助,但與原生requestAnimationFrame相比沒有任何幫助。

  • 如果每幀(或幾乎)調用console.log,則表示性能下降。 由於原生Android瀏覽器沒有控制台對象,因此每次調用它都會產生錯誤,這也會導致應用程序運行速度變慢。 你可以這樣做:

    if(typeof console === "undefined"){ console = {}; }

  • 對於密集的實時應用程序, Web套接字比http請求更快。 遺憾的是,舊的原生Android瀏覽器不支持此功能。 如果無法使用Web套接字,則應最小化http請求。

注意: Chrome for android支持此處引用的大部分HTML5功能,包括requestAnimationFramewebsockets

更多信息:

  • 使用上下文2d fillText繪制文本它太貴了,但在某些瀏覽器中這更糟糕。 在另一個畫布中預渲染文本或使用位圖字體。 (在原生Android瀏覽器中,在替換用於預渲染內容的filltext繪圖之后,在我制作的一些游戲中,性能從10-15 FPS增長到30-45 FPS)。

  • 避免縮放和旋轉上下文,因為它們還會導致性能下降。 如果只需要縮放或旋轉一次精靈,請使用預渲染。

  • 您需要最小化實時繪圖。 盡可能預先渲染你的東西。 僅重繪已更改且需要更新的內容。

  • 嘗試編寫內存高效和垃圾收集器友好的代碼。

還有很多事情要做。 我剛引用了一些。

提示:對您不確定它們是否是性能殺手並捕獲基准測試結果的功能進行一些壓力測試。

在移動應用程序,特別是實時應用程序中,如果只是過度優化或一點內存增益,所有優化都是受歡迎的。

有關更多信息,請訪問以下鏈接:

還可以在帖子和教程中搜索性能。

編輯
這個jsfiddle代碼片段顯示了這個答案中涵蓋的一些內容,並為基准測試提供了一個粗略的fps計數器。 自己編輯這個小提琴並檢查出來。

根據您的繪圖,使用Html5畫布最常見的性能改進策略是利用圖層(即多個畫布)並僅更新需要重繪的圖層,而不是重繪每個動畫幀上的整個圖形。 你可以自己滾動這樣的東西,或者你可以使用http://www.concretejs.com/之類的東西,它是一個輕量級的Html5畫布框架,支持點擊檢測,分層,緩存,像素比例支持,下載等外圍設備。你會做這樣的事情:

var wrapper = new Concrete.Wrapper({
  width: 500,
  height: 300,
  container: el
});

var layer1 = new Concrete.Layer();
var layer2 = new Concrete.Layer();

wrapper.add(layer1).add(layer2);

// something happens which requires you to redraw layer2, but not layer1...
layer2.sceneCanvas.context.fillStyle = 'red';
layer2.sceneCanvas.context.fillRect(0, 0, 200, 100);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM