WebView2 зависает при работе через удалённый рабочий стол (RDP)
Устранение многосекундных зависаний интерфейса WebView2, когда приложение Wails работает через сеанс RDP, в ходе которого изменяется DPI монитора.
Проблема
Когда приложение Wails используется через сеанс удалённого рабочего стола (RDP), интерфейс может зависать на несколько секунд при обычных действиях:
- После щелчка всплывающее окно с содержимым появляется примерно через 4–8 секунд.
- При закрытии окна родительское окно блокируется примерно на 2 секунд.
- Замедление сохраняется после повторных подключений и исчезает только после перезагрузки хост-компьютера.
Чаще всего это наблюдается при использовании клиента Microsoft Remote Desktop для iOS, который в ходе сеанса создаёт виртуальный монитор, оптимизированный для Retina. Такое же поведение может вызвать любой RDP-клиент, который в ходе сеанса добавляет монитор с другим контекстом DPI.
Почему это происходит
По умолчанию WebView2 использует оконный режим размещения, при котором поверхность его компоновщика находится в дочернем окне. Когда RDP-клиент добавляет монитор, контекст DPI которого отличается от контекста сеанса, каждый вызов контроллера WebView2 (PutIsVisible, MoveFocus, первая отрисовка и освобождение поверхности) вынуждает DirectComposition выполнять синхронный повторный маршалинг. Каждый такой маршалинг блокирует поток пользовательского интерфейса примерно на 2 секунд, поэтому в приложениях с большим количеством всплывающих окон задержки накапливаются.
Нативное приложение Win32 с WebView2 на том же компьютере не затронуто, поскольку использует визуальный режим размещения. Это указывает на то, что причиной является режим размещения, а не общая проблема WebView2 или компоновщика Windows.
Решение
Включите визуальный режим размещения, задав UseVisualHosting в параметрах Windows. В этом режиме поверхность компоновщика WebView2 принадлежит визуальному элементу DirectComposition, которым управляет хост, поэтому изменения контекста DPI больше не запускают синхронный повторный маршалинг.
package main
import "github.com/wailsapp/wails/v3/pkg/application"
func main() {
app := application.New(application.Options{
Windows: application.WindowsOptions{
UseVisualHosting: true,
},
})
// ... create your windows, then:
app.Run()
}После включения этого режима всплывающие окна открываются за обычное для навигации время (примерно за 150–500 мс), а закрытие окна больше не блокирует родительское окно.
По умолчанию параметр имеет значение false, поэтому оконный режим размещения остаётся режимом по умолчанию. Поведение существующих приложений не изменится, если они явно не включат этот параметр.
Когда следует включать этот параметр
Задайте UseVisualHosting: true, если ваше приложение регулярно используется через RDP, особенно через клиент Microsoft Remote Desktop для iOS, и при открытии или закрытии окон возникают многосекундные зависания. Если приложение не работает через RDP, этот параметр не нужен и можно оставить значение по умолчанию.
Ссылки
- WebView2: оконный и визуальный режимы размещения
- Обращение №5248 в WebView2Feedback
- Обращение №4485 в WebView2Feedback