diff --git a/Runtime/ChromeDevtools/Browser.cs b/Runtime/ChromeDevtools/Browser.cs
index 5bdf86aefc69fbd0868f32d8667c2af581762dda..6303eda5bb9b826c4f04bdf3e07e3230195d6b8b 100644
--- a/Runtime/ChromeDevtools/Browser.cs
+++ b/Runtime/ChromeDevtools/Browser.cs
@@ -17,7 +17,8 @@ namespace bessw.Unity.WebView.ChromeDevTools
         private Process browserProcess;
 
         /* browser settings */
-        public static string browserExecutablePath = Application.streamingAssetsPath + "/chrome-headless-shell-win64/chrome-headless-shell.exe";
+        public static string BrowserExecutablePath = "chrome";
+        public static string headlessBrowserExecutablePath = Application.streamingAssetsPath + "/chrome-headless-shell-win64/chrome-headless-shell.exe";
         public static bool headless = true;
         private const int debugPort = 9222;
 
@@ -67,7 +68,14 @@ namespace bessw.Unity.WebView.ChromeDevTools
             if (browserProcess == null || browserProcess.HasExited)
             {
                 browserProcess = new Process();
-                browserProcess.StartInfo.FileName = browserExecutablePath;
+                if (headless)
+                {
+                    browserProcess.StartInfo.FileName = headlessBrowserExecutablePath;
+                }
+                else
+                {
+                    browserProcess.StartInfo.FileName = BrowserExecutablePath;
+                }
                 browserProcess.StartInfo.Arguments = String.Join(" ", new []{
                     $"--user-data-dir={Path.Join(Application.temporaryCachePath, "BrowserView")}",
                     $"--remote-debugging-port={debugPort}",
diff --git a/Runtime/ChromeDevtools/BrowserTab.cs b/Runtime/ChromeDevtools/BrowserTab.cs
index daff011aa05acc6042d7395d67864b0254e75480..18f1ed2821ef83e80f00b2a598fc8e692e030ec7 100644
--- a/Runtime/ChromeDevtools/BrowserTab.cs
+++ b/Runtime/ChromeDevtools/BrowserTab.cs
@@ -77,9 +77,10 @@ namespace bessw.Unity.WebView.ChromeDevTools
             _document = null;
         }
 
-        public IEnumerator Update()
+        public void Update()
         {
-            yield return devtools.readLoop();
+            //yield return devtools.readLoop();
+            devtools.handleMessages();
         }
 
         public async Task SetSize(Vector2Int size)
diff --git a/Runtime/ChromeDevtools/DevtoolsProtocolHandler.cs b/Runtime/ChromeDevtools/DevtoolsProtocolHandler.cs
index 4f6fb746d06b5b58ace3ad92dc8090ddc28597ca..57af61add86775c66f0f842f87b8b04d7179543a 100644
--- a/Runtime/ChromeDevtools/DevtoolsProtocolHandler.cs
+++ b/Runtime/ChromeDevtools/DevtoolsProtocolHandler.cs
@@ -21,6 +21,7 @@ namespace bessw.Unity.WebView.ChromeDevTools
 
         private IDevtoolsConnection devtools;
 
+        private ConcurrentQueue<string> messageQueue = new();
         private ConcurrentDictionary<long, ResponseTypeAndCallback<IDevtoolsResponse>> commandResponseDict = new();
 
         // devtools events
@@ -44,12 +45,27 @@ namespace bessw.Unity.WebView.ChromeDevTools
         public DevtoolsProtocolHandler(IDevtoolsConnection devtools)
         {
             this.devtools = devtools;
-            devtools.receivedMessage += ParseMessage;
-            //TODO: let devtools open async
+            devtools.receivedMessage += enqueueMessage;
+            //TODO: let devtools open async (some other code currently expects it to be open once this method returns)
             devtools.OpenAsync().Wait();
-            //devtools.AsyncReadLoop();
+            // run AsyncReadLoop in a c# background thread to be able to receive more then one message per Unity update() call
+            Task.Run(devtools.AsyncReadLoop);
         }
 
+        private void enqueueMessage(string msg)
+        {
+            messageQueue.Enqueue(msg);
+        }
+
+        public void handleMessages()
+        {
+            while (messageQueue.TryDequeue(out string msgStr))
+            {
+                ParseMessage(msgStr);
+            }
+        }
+
+        [Obsolete]
         public IEnumerator readLoop()
         {
             while (true)
@@ -79,7 +95,15 @@ namespace bessw.Unity.WebView.ChromeDevTools
         private void ParseMessage(string msgStr)
         {
             // deserialize the devtools response wrapper
-            var message = JObject.Parse(msgStr);
+            JObject message;
+            try
+            {
+                message = JObject.Parse(msgStr);
+            } catch (Exception e)
+            {
+                Debug.LogError($"Could not parse message '{msgStr}' error '{e.Message}'");
+                return;
+            }
 
             if (message.ContainsKey("id"))
             {
diff --git a/Runtime/ChromeDevtools/DevtoolsWebsocket.cs b/Runtime/ChromeDevtools/DevtoolsWebsocket.cs
index b0acb780dc044ad2672439bc3d3a4804b2bb1dae..a97c477c90646fbd8d7e7b2da754678d806ef8a7 100644
--- a/Runtime/ChromeDevtools/DevtoolsWebsocket.cs
+++ b/Runtime/ChromeDevtools/DevtoolsWebsocket.cs
@@ -38,7 +38,6 @@ namespace bessw.Unity.WebView.ChromeDevTools
         /// Experimental! Synchronisation with Unity coroutines is not jet implemented. Call ReadAsync from a coroutine instead.
         /// </summary>
         /// <returns></returns>
-        [Obsolete]
         public async Task AsyncReadLoop()
         {
             var cancellationToken = cancellationTokenSource.Token;
diff --git a/Runtime/ChromeDevtools/IDevtoolsConnection.cs b/Runtime/ChromeDevtools/IDevtoolsConnection.cs
index 122c5699fe5c9f4f717fe3c48a712fac399762d0..7613461e67be9bd7619ca66bdd2c3d945379d654 100644
--- a/Runtime/ChromeDevtools/IDevtoolsConnection.cs
+++ b/Runtime/ChromeDevtools/IDevtoolsConnection.cs
@@ -23,7 +23,6 @@ namespace bessw.Unity.WebView.ChromeDevTools
         /// experimental
         /// </summary>
         /// <returns></returns>
-        [Obsolete]
         public Task AsyncReadLoop();
 
         public Task SendCommandAsync(string command);
diff --git a/Runtime/ChromeDevtools/Protocol/DOM/DOM.cs b/Runtime/ChromeDevtools/Protocol/DOM/DOM.cs
index 08c6e7023d698ee37381f8b56bd80c37df7149d6..ef019703425e2c478735fcd3d6ba0834f4fd4c0c 100644
--- a/Runtime/ChromeDevtools/Protocol/DOM/DOM.cs
+++ b/Runtime/ChromeDevtools/Protocol/DOM/DOM.cs
@@ -922,12 +922,12 @@ namespace bessw.Unity.WebView.ChromeDevTools.Protocol.DOM
         /// <summary>
         /// Child nodes of this node when requested with children.
         /// </summary>
-        public List<Node> children { get; set; }
+        public List<Node> children { get; set; } = new List<Node>();
         /// <summary>
         /// Attributes of the `Element` node in the form of flat array `[name1, value1, name2, value2]`.
         /// </summary>
         [JsonConverter(typeof(JsonInterleavedArrayConverter<string, string>))]
-        public Dictionary<string,string> attributes { get; set; }
+        public Dictionary<string,string> attributes { get; set; } = new Dictionary<string, string>();
         /// <summary>
         /// Document URL that `Document` or `FrameOwner` node points to.
         /// </summary>
diff --git a/Runtime/WebViewComponent.cs b/Runtime/WebViewComponent.cs
index 1862a6e392f8aae4ff98f747dc336d386c20e3cb..aee692c7148a8037112dfa8479ed01d15edfbc28 100644
--- a/Runtime/WebViewComponent.cs
+++ b/Runtime/WebViewComponent.cs
@@ -85,7 +85,7 @@ namespace bessw.Unity.WebView
                 //_ = tab.SetSize(Vector2Int.RoundToInt(this.gameObject.GetComponentInParent<Canvas>().renderingDisplaySize));
                 OnRectTransformDimensionsChange();
 
-                StartCoroutine(tab.Update());
+                //StartCoroutine(tab.Update());
                 //StartCoroutine(createScreenshots());
                 StartCoroutine(tab.StartStream(tab.Size.x, tab.Size.y, (frame) =>
                 {
@@ -126,7 +126,7 @@ namespace bessw.Unity.WebView
         // Update is called once per frame
         private void Update()
         {
-
+            tab?.Update();
         }
 
         #region pointer event handlers