1. 程式人生 > >使用CefSharp在.Net程式中嵌入Chrome瀏覽器(九)——效能問題

使用CefSharp在.Net程式中嵌入Chrome瀏覽器(九)——效能問題

在使用CEF的過程中,我發現了一個現象:WPF版的CEF比Chrome效能要差:一些有動畫的地方會掉幀(例如,CSS動畫,全屏圖片拖動等),視訊播放的效果也沒有Chrome流暢。

查了一下相關資料,發現CEFSharp.WPF不是直接渲染在控制元件上的,它的大概流程如下:

  1. CEFSharp.WPF的ChromiumWebBrowser控制元件本質上是一個圖片
  2. 而是通過離屏渲染的方式渲染在緩衝區裡,
  3. 繪製完成後,然後將緩衝區的資料傳遞到InteropBitmap中去
  4. 將InteropBitmap作為ChromiumWebBrowser的圖源更新

這個基本上是類似於WPF的視訊播放器的做法:先離屏渲染出圖片,在將圖片更新到介面。這個做法由於是使用的WPF的原生渲染方案,可以說是WPF的原生控制元件的,本身是有不少好處的:

  1. 可以支援透明背景
  2. 可以在上面疊加其它WPF控制元件
  3. 可以支援WPF的變形,動畫,裁剪等特效

簡單一句話,是可以和WPF程式無縫整合的,如果將WEB介面作為控制元件嵌入式再方便不過的。

但是,它這個實現是有代價的:

  1. 離屏渲染本身需要多一層工序,
  2. 有切換上下文和記憶體拷貝的開銷。
  3. 更要命的是,貌似目前GPU離線渲染視訊效果還不是很好,因此預設還把gpu加速給關了,效能更下降了一截。

另外,InteropBitmap傳遞圖片記憶體的效率本身就不高,不光吃cpu,還吃記憶體,網上也有人討論過。

針對這些問題,有人建議使用WritableBitmap替換InteropBitmap,但貌似作者認為InteropBitmap的效率更好些。我使用過WritableBitmap離屏渲染地圖,應該是能做到比當前更好的效能的。

也有人建議使用效率更高的D3DImage(WPF原生支援這個,不過麻煩些),可能作者覺得目前它的這個效能問題不是首要解決的目標吧,也一直沒有采納。

最後說一下解決方法吧,雖然在大部分的情況下,當前的解決方案是能滿足我們的需求的,不過如果遇到非要解決的情況下,可以使用下WinFrom版的CEFSharp,通過WinFormHost來整合到WPF程式中去。

WinFrom版的CEFSharp應該是直接渲染的,我試了一下,效率基本上接近Chrome,並且由於他們的基礎庫是公用的,在WPF程式中WinFrom版和WPF版的CEF是可以並存的,用起來還算方便。