Skip to content

Commit

Permalink
Merge pull request #179 from MicrosoftEdge/user/pieths-ms/fix_wv2_uwp…
Browse files Browse the repository at this point in the history
…_sample_app_warnings_and_child_process_destruction

Dispose of unnecessary WebView2 resources when navigating between pages in the WebView2 UWP sample app.

In the WebView2 UWP sample app, when navigating between pages, the garbage collector takes a long time to activate and does not remove WebView2 resources in a reasonable amount of time. This leaves behind all the render processes and other resources which can bog down low memory systems. This PR "closes" all WebView controls which are on a page that is being unloaded and thus releases all significant resources which are used by those controls.
  • Loading branch information
pieths-ms committed Mar 30, 2023
2 parents 0b7d035 + df19cef commit 93f1c12
Show file tree
Hide file tree
Showing 16 changed files with 94 additions and 32 deletions.
1 change: 0 additions & 1 deletion SampleApps/webview2_sample_uwp/Package.appxmanifest
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
<Capability Name="privateNetworkClientServer" />
<uap:Capability Name="enterpriseAuthentication"/>
<uap:Capability Name="sharedUserCertificates"/>
<rescap:Capability Name="enterpriseCloudSSO" />
<DeviceCapability Name="location"/>
<DeviceCapability Name="microphone"/>
<DeviceCapability Name="webcam"/>
Expand Down
6 changes: 3 additions & 3 deletions SampleApps/webview2_sample_uwp/Pages/AddHostObject.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.-->

<Page
<local:BasePage
x:Class="WebView2_UWP.Pages.AddHostObject"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WebView2_UWP.Pages"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.UI.Xaml.Controls"
xmlns:local="using:WebView2_UWP.Pages"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

Expand Down Expand Up @@ -77,5 +77,5 @@ found in the LICENSE file.-->

<controls:WebView2 Grid.Column="1" x:Name="WebView2" />
</Grid>
</Page>
</local:BasePage>

2 changes: 1 addition & 1 deletion SampleApps/webview2_sample_uwp/Pages/AddHostObject.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace WebView2_UWP.Pages
{
public sealed partial class AddHostObject : Page
public sealed partial class AddHostObject : BasePage
{
private Bridge _bridge;

Expand Down
43 changes: 43 additions & 0 deletions SampleApps/webview2_sample_uwp/Pages/BasePage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (C) Microsoft Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

using Microsoft.UI.Xaml.Controls;
using System.Diagnostics;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;

namespace WebView2_UWP.Pages
{
public class BasePage : Page
{
public BasePage()
{
Unloaded += BasePage_Unloaded;
}

private void BasePage_Unloaded(object sender, RoutedEventArgs e)
{
// The garbage collector can be slow to dispose of the
// webviews. Manually free the resources being used by
// the webviews since they are no longer needed after
// the page has been unloaded.
CloseAllWebViews(this);
}

private void CloseAllWebViews(DependencyObject root)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(root); i++)
{
var childVisual = VisualTreeHelper.GetChild(root, i);
CloseAllWebViews(childVisual);

if (childVisual is WebView2 webView)
{
webView.Close();
}
}
}
}
}
5 changes: 3 additions & 2 deletions SampleApps/webview2_sample_uwp/Pages/Browser.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.-->

<Page
<local:BasePage
x:Class="WebView2_UWP.Pages.Browser"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.UI.Xaml.Controls"
xmlns:local="using:WebView2_UWP.Pages"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

Expand Down Expand Up @@ -45,4 +46,4 @@ found in the LICENSE file.-->
<Rectangle Grid.Row="2" Fill="LightGray"/>
<TextBlock x:Name="StatusBar" Text="WebView2" VerticalAlignment="Center" Grid.Row="2" Margin="10,0,10,0"/>
</Grid>
</Page>
</local:BasePage>
16 changes: 12 additions & 4 deletions SampleApps/webview2_sample_uwp/Pages/Browser.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@

namespace WebView2_UWP.Pages
{
public sealed partial class Browser : Page
public sealed partial class Browser : BasePage
{
private string _homeUrl = "https://developer.microsoft.com/en-us/microsoft-edge/webview2/";

public Browser()
{
this.InitializeComponent();
InitializeComponent();
AddressBar.Text = _homeUrl;

WebView2.CoreWebView2Initialized += WebView2_CoreWebView2Initialized;
Expand All @@ -36,7 +36,11 @@ public Browser()
WebView2.Source = new Uri(AddressBar.Text);
}

#if USE_WEBVIEW2_SMOKETEST
private async void WebView2_CoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args)
#else
private void WebView2_CoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args)
#endif
{
if (args.Exception != null)
{
Expand All @@ -59,7 +63,7 @@ private async void WebView2_CoreWebView2Initialized(WebView2 sender, CoreWebView
}

// <DownloadStarting>
private async void CoreWebView2_DownloadStarting(CoreWebView2 sender, CoreWebView2DownloadStartingEventArgs args)
private void CoreWebView2_DownloadStarting(CoreWebView2 sender, CoreWebView2DownloadStartingEventArgs args)
{
// Developer can obtain a deferral for the event so that the CoreWebView2
// doesn't examine the properties we set on the event args until
Expand Down Expand Up @@ -142,13 +146,17 @@ private void StatusUpdate(string message)
Debug.WriteLine(message);
}

private async void WebView2_NavigationStarting(WebView2 sender, CoreWebView2NavigationStartingEventArgs args)
private void WebView2_NavigationStarting(WebView2 sender, CoreWebView2NavigationStartingEventArgs args)
{
RefreshButton.IsEnabled = false;
CancelButton.IsEnabled = true;
}

#if USE_WEBVIEW2_SMOKETEST
private async void WebView2_NavigationCompleted(WebView2 sender, CoreWebView2NavigationCompletedEventArgs args)
#else
private void WebView2_NavigationCompleted(WebView2 sender, CoreWebView2NavigationCompletedEventArgs args)
#endif
{
StatusUpdate("Navigation complete");

Expand Down
6 changes: 3 additions & 3 deletions SampleApps/webview2_sample_uwp/Pages/ExecuteJavascript.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.-->

<Page
<local:BasePage
x:Class="WebView2_UWP.Pages.ExecuteJavascript"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WebView2_UWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.UI.Xaml.Controls"
xmlns:local="using:WebView2_UWP.Pages"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

Expand Down Expand Up @@ -83,5 +83,5 @@ found in the LICENSE file.-->

<controls:WebView2 Grid.Column="1" x:Name="WebView2" />
</Grid>
</Page>
</local:BasePage>

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace WebView2_UWP.Pages
{
public sealed partial class ExecuteJavascript : Page
public sealed partial class ExecuteJavascript : BasePage
{
Dictionary<string, string> codeSnippets = new Dictionary<string, string>()
{
Expand All @@ -29,7 +29,7 @@ public ExecuteJavascript()
WebView2.Source = new Uri("http://appassets.html.example/execute_javascript.html");
}

private async void WebView2_CoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args)
private void WebView2_CoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args)
{
sender.CoreWebView2.SetVirtualHostNameToFolderMapping("appassets.html.example", "html", CoreWebView2HostResourceAccessKind.Allow);
}
Expand Down
6 changes: 3 additions & 3 deletions SampleApps/webview2_sample_uwp/Pages/NewWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.-->

<Page
<local:BasePage
x:Class="WebView2_UWP.Pages.NewWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WebView2_UWP.Pages"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.UI.Xaml.Controls"
xmlns:local="using:WebView2_UWP.Pages"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

Expand Down Expand Up @@ -78,4 +78,4 @@ found in the LICENSE file.-->
</Grid>

</Grid>
</Page>
</local:BasePage>
4 changes: 2 additions & 2 deletions SampleApps/webview2_sample_uwp/Pages/NewWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace WebView2_UWP.Pages
{
public sealed partial class NewWindow : Page
public sealed partial class NewWindow : BasePage
{
public enum OptionEnum
{
Expand Down Expand Up @@ -65,7 +65,7 @@ public NewWindow()
WebView2.Source = new Uri("http://appassets.html.example/new_window.html");
}

private async void WebView2_CoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args)
private void WebView2_CoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args)
{
sender.CoreWebView2.SetVirtualHostNameToFolderMapping("appassets.html.example", "html", CoreWebView2HostResourceAccessKind.Allow);
sender.CoreWebView2.NewWindowRequested += CoreWebView2_NewWindowRequested;
Expand Down
6 changes: 3 additions & 3 deletions SampleApps/webview2_sample_uwp/Pages/PopupsAndDialogs.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.-->

<Page
<local:BasePage
x:Class="WebView2_UWP.Pages.PopupsAndDialogs"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WebView2_UWP.Pages"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.UI.Xaml.Controls"
xmlns:local="using:WebView2_UWP.Pages"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

Expand Down Expand Up @@ -100,4 +100,4 @@ found in the LICENSE file.-->

<controls:WebView2 Grid.Column="1" x:Name="WebView2" />
</Grid>
</Page>
</local:BasePage>
4 changes: 2 additions & 2 deletions SampleApps/webview2_sample_uwp/Pages/PopupsAndDialogs.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace WebView2_UWP.Pages
{
public sealed partial class PopupsAndDialogs : Page
public sealed partial class PopupsAndDialogs : BasePage
{
public PopupsAndDialogs()
{
Expand All @@ -23,7 +23,7 @@ public PopupsAndDialogs()
WebView2.Source = new Uri("http://appassets.html.example/popups_and_dialogs.html");
}

private async void WebView2_CoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args)
private void WebView2_CoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args)
{
WebView2.CoreWebView2.SetVirtualHostNameToFolderMapping("appassets.html.example", "html", CoreWebView2HostResourceAccessKind.Allow);
}
Expand Down
5 changes: 3 additions & 2 deletions SampleApps/webview2_sample_uwp/Pages/ScriptDebugging.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.-->

<Page
<local:BasePage
x:Class="WebView2_UWP.Pages.ScriptDebugging"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.UI.Xaml.Controls"
xmlns:local="using:WebView2_UWP.Pages"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

Expand Down Expand Up @@ -46,7 +47,7 @@ found in the LICENSE file.-->

<controls:WebView2 Grid.Column="1" x:Name="WebView2" />
</Grid>
</Page>
</local:BasePage>



8 changes: 4 additions & 4 deletions SampleApps/webview2_sample_uwp/Pages/ScriptDebugging.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,24 @@

namespace WebView2_UWP.Pages
{
public sealed partial class ScriptDebugging : Page
public sealed partial class ScriptDebugging : BasePage
{
public ScriptDebugging()
{
this.InitializeComponent();
WebView2.CoreWebView2Initialized += WebView2_CoreWebView2Initialized;
}

private async void WebView2_CoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args)
private void WebView2_CoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args)
{
sender.CoreWebView2.SetVirtualHostNameToFolderMapping("appassets.html.example", "html", CoreWebView2HostResourceAccessKind.Allow);
}

private async void OnJavaScriptLocalFileButtonClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
private void OnJavaScriptLocalFileButtonClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
WebView2.Source = new Uri("http://appassets.html.example/ScenarioJavaScriptDebugIndex.html");
}
private async void OnTypeScriptLocalFileButtonClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
private void OnTypeScriptLocalFileButtonClicked(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
WebView2.Source = new Uri("http://appassets.html.example/ScenarioTypeScriptDebugIndex.html");
}
Expand Down
9 changes: 9 additions & 0 deletions SampleApps/webview2_sample_uwp/Pages/SettingsPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using webview2_sample_uwp;
using Windows.ApplicationModel.Core;
using Windows.Storage;
using Windows.UI.Core;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
Expand Down Expand Up @@ -160,6 +161,14 @@ private async void InitializeAppDetailsItems()
Value = sender.CoreWebView2.Environment.UserDataFolder
});
}
// The garbage collector can be slow to dispose of the
// webview. Manually free the resources being used by
// the webview since it is no longer needed.
var ignored = Dispatcher.RunAsync(CoreDispatcherPriority.Low, () =>
{
webview2.Close();
});
};
await webview2.EnsureCoreWebView2Async();
}
Expand Down
1 change: 1 addition & 0 deletions SampleApps/webview2_sample_uwp/webview2_sample_uwp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
<Compile Include="Pages\AddHostObject.xaml.cs">
<DependentUpon>AddHostObject.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\BasePage.cs" />
<Compile Include="Pages\Browser.xaml.cs">
<DependentUpon>Browser.xaml</DependentUpon>
</Compile>
Expand Down

0 comments on commit 93f1c12

Please sign in to comment.