diff --git a/Core/Handling/ResourceHandlerFactory.cs b/Core/Handling/ResourceHandlerFactory.cs
new file mode 100644
index 00000000..cba2649e
--- /dev/null
+++ b/Core/Handling/ResourceHandlerFactory.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Concurrent;
+using CefSharp;
+using TweetDuck.Data;
+
+namespace TweetDuck.Core.Handling{
+    sealed class ResourceHandlerFactory : IResourceHandlerFactory{
+        public bool HasHandlers => !handlers.IsEmpty;
+
+        private readonly ConcurrentDictionary<string, IResourceHandler> handlers = new ConcurrentDictionary<string, IResourceHandler>(StringComparer.OrdinalIgnoreCase);
+
+        public IResourceHandler GetResourceHandler(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request){
+            try{
+                return handlers.TryGetValue(request.Url, out IResourceHandler handler) ? handler : null;
+            }finally{
+                request.Dispose();
+            }
+        }
+
+        // registration
+
+        public bool RegisterHandler(string url, IResourceHandler handler){
+            if (Uri.TryCreate(url, UriKind.Absolute, out Uri uri)){
+                handlers.AddOrUpdate(uri.AbsoluteUri, handler, (key, prev) => handler);
+                return true;
+            }
+
+            return false;
+        }
+
+        public bool RegisterHandler(ResourceLink link){
+            return RegisterHandler(link.Url, link.Handler);
+        }
+
+        public bool UnregisterHandler(string url){
+            return handlers.TryRemove(url, out IResourceHandler _);
+        }
+
+        public bool UnregisterHandler(ResourceLink link){
+            return UnregisterHandler(link.Url);
+        }
+    }
+}
diff --git a/Core/Notification/FormNotificationBase.cs b/Core/Notification/FormNotificationBase.cs
index 228b0bbe..cc3275fa 100644
--- a/Core/Notification/FormNotificationBase.cs
+++ b/Core/Notification/FormNotificationBase.cs
@@ -121,18 +121,20 @@ protected FormNotificationBase(FormBrowser owner, bool enableContextMenu){
             this.owner = owner;
             this.owner.FormClosed += owner_FormClosed;
 
+            ResourceHandlerFactory resourceHandlerFactory = new ResourceHandlerFactory();
+            resourceHandlerFactory.RegisterHandler(TwitterUtils.TweetDeckURL, this.resourceHandler);
+            resourceHandlerFactory.RegisterHandler(TweetNotification.AppLogo);
+
             this.browser = new ChromiumWebBrowser("about:blank"){
                 MenuHandler = new ContextMenuNotification(this, enableContextMenu),
                 JsDialogHandler = new JavaScriptDialogHandler(),
                 LifeSpanHandler = new LifeSpanHandler(),
-                RequestHandler = new RequestHandlerBase(false)
+                RequestHandler = new RequestHandlerBase(false),
+                ResourceHandlerFactory = resourceHandlerFactory
             };
 
             this.browser.Dock = DockStyle.None;
             this.browser.ClientSize = ClientSize;
-            
-            this.browser.SetupResourceHandler(TwitterUtils.TweetDeckURL, this.resourceHandler);
-            this.browser.SetupResourceHandler(TweetNotification.AppLogo);
             this.browser.SetupZoomEvents();
 
             Controls.Add(browser);
diff --git a/Core/Other/FormGuide.cs b/Core/Other/FormGuide.cs
index 4dec265b..67aa2051 100644
--- a/Core/Other/FormGuide.cs
+++ b/Core/Other/FormGuide.cs
@@ -63,12 +63,16 @@ private FormGuide(string url, FormBrowser owner){
             Text = Program.BrandName+" Guide";
             Size = new Size(owner.Size.Width*3/4, owner.Size.Height*3/4);
             VisibleChanged += (sender, args) => this.MoveToCenter(owner);
+
+            ResourceHandlerFactory resourceHandlerFactory = new ResourceHandlerFactory();
+            resourceHandlerFactory.RegisterHandler(DummyPage);
             
             this.browser = new ChromiumWebBrowser(url){
                 MenuHandler = new ContextMenuGuide(owner),
                 JsDialogHandler = new JavaScriptDialogHandler(),
                 LifeSpanHandler = new LifeSpanHandler(),
-                RequestHandler = new RequestHandlerBase(true)
+                RequestHandler = new RequestHandlerBase(true),
+                ResourceHandlerFactory = resourceHandlerFactory
             };
 
             browser.LoadingStateChanged += browser_LoadingStateChanged;
@@ -77,8 +81,6 @@ private FormGuide(string url, FormBrowser owner){
             browser.BrowserSettings.BackgroundColor = (uint)BackColor.ToArgb();
             browser.Dock = DockStyle.None;
             browser.Location = ControlExtensions.InvisibleLocation;
-
-            browser.SetupResourceHandler(DummyPage);
             browser.SetupZoomEvents();
 
             Controls.Add(browser);
diff --git a/Core/TweetDeckBrowser.cs b/Core/TweetDeckBrowser.cs
index c024d96a..9d11d7c2 100644
--- a/Core/TweetDeckBrowser.cs
+++ b/Core/TweetDeckBrowser.cs
@@ -39,10 +39,14 @@ public bool IsTweetDeckWebsite{
         }
         
         private readonly ChromiumWebBrowser browser;
+        private readonly ResourceHandlerFactory resourceHandlerFactory = new ResourceHandlerFactory();
 
         private string prevSoundNotificationPath = null;
 
         public TweetDeckBrowser(FormBrowser owner, PluginManager plugins, TweetDeckBridge tdBridge, UpdateBridge updateBridge){
+            resourceHandlerFactory.RegisterHandler(TweetNotification.AppLogo);
+            resourceHandlerFactory.RegisterHandler(TwitterUtils.LoadingSpinner);
+
             RequestHandlerBrowser requestHandler = new RequestHandlerBrowser();
             
             this.browser = new ChromiumWebBrowser(TwitterUtils.TweetDeckURL){
@@ -52,7 +56,8 @@ public TweetDeckBrowser(FormBrowser owner, PluginManager plugins, TweetDeckBridg
                 JsDialogHandler = new JavaScriptDialogHandler(),
                 KeyboardHandler = new KeyboardHandlerBrowser(owner),
                 LifeSpanHandler = new LifeSpanHandler(),
-                RequestHandler = requestHandler
+                RequestHandler = requestHandler,
+                ResourceHandlerFactory = resourceHandlerFactory
             };
 
             this.browser.LoadingStateChanged += browser_LoadingStateChanged;
@@ -66,11 +71,8 @@ public TweetDeckBrowser(FormBrowser owner, PluginManager plugins, TweetDeckBridg
             this.browser.BrowserSettings.BackgroundColor = (uint)TwitterUtils.BackgroundColor.ToArgb();
             this.browser.Dock = DockStyle.None;
             this.browser.Location = ControlExtensions.InvisibleLocation;
-
-            this.browser.SetupResourceHandler(TweetNotification.AppLogo);
-            this.browser.SetupResourceHandler(TwitterUtils.LoadingSpinner);
             this.browser.SetupZoomEvents();
-
+            
             owner.Controls.Add(browser);
             plugins.Register(browser, PluginEnvironment.Browser, owner, true);
             
@@ -174,10 +176,16 @@ private void Config_SoundNotificationInfoChanged(object sender, EventArgs e){
 
             bool hasCustomSound = Config.IsCustomSoundNotificationSet;
             string newNotificationPath = Config.NotificationSoundPath;
-
+            
             if (prevSoundNotificationPath != newNotificationPath){
-                browser.SetupResourceHandler(soundUrl, hasCustomSound ? SoundNotification.CreateFileHandler(newNotificationPath) : null);
                 prevSoundNotificationPath = newNotificationPath;
+
+                if (hasCustomSound){
+                    resourceHandlerFactory.RegisterHandler(soundUrl, SoundNotification.CreateFileHandler(newNotificationPath));
+                }
+                else{
+                    resourceHandlerFactory.UnregisterHandler(soundUrl);
+                }
             }
 
             browser.ExecuteScriptAsync("TDGF_setSoundNotificationData", hasCustomSound, Config.NotificationSoundVolume);
diff --git a/Core/Utils/BrowserUtils.cs b/Core/Utils/BrowserUtils.cs
index c6019af6..ad143c0c 100644
--- a/Core/Utils/BrowserUtils.cs
+++ b/Core/Utils/BrowserUtils.cs
@@ -60,21 +60,6 @@ public static ChromiumWebBrowser AsControl(this IWebBrowser browserControl){
             return (ChromiumWebBrowser)browserControl;
         }
 
-        public static void SetupResourceHandler(this ChromiumWebBrowser browser, string url, IResourceHandler handler){
-            DefaultResourceHandlerFactory factory = (DefaultResourceHandlerFactory)browser.ResourceHandlerFactory;
-
-            if (handler == null){
-                factory.UnregisterHandler(url);
-            }
-            else{
-                factory.RegisterHandler(url, handler);
-            }
-        }
-
-        public static void SetupResourceHandler(this ChromiumWebBrowser browser, ResourceLink resource){
-            browser.SetupResourceHandler(resource.Url, resource.Handler);
-        }
-
         public static void SetupZoomEvents(this ChromiumWebBrowser browser){
             void UpdateZoomLevel(object sender, EventArgs args){
                 SetZoomLevel(browser.GetBrowser(), Config.ZoomLevel);
diff --git a/TweetDuck.csproj b/TweetDuck.csproj
index 35223003..06ae04dc 100644
--- a/TweetDuck.csproj
+++ b/TweetDuck.csproj
@@ -95,6 +95,7 @@
     <Compile Include="Core\Handling\KeyboardHandlerNotification.cs" />
     <Compile Include="Core\Handling\RequestHandlerBase.cs" />
     <Compile Include="Core\Handling\RequestHandlerBrowser.cs" />
+    <Compile Include="Core\Handling\ResourceHandlerFactory.cs" />
     <Compile Include="Core\Handling\ResourceHandlerNotification.cs" />
     <Compile Include="Core\Management\ContextInfo.cs" />
     <Compile Include="Core\Notification\Example\FormNotificationExample.cs">