diff --git a/accessible/base/CacheConstants.h b/accessible/base/CacheConstants.h
index fecf73d6134afce903510e0a3b1d1d40c749bd9a..58de8d68fa1863ed4a1c7600f27e7b26af4903e7 100644
--- a/accessible/base/CacheConstants.h
+++ b/accessible/base/CacheConstants.h
@@ -24,9 +24,7 @@ class CacheDomain {
   static constexpr uint64_t Style = ((uint64_t)0x1) << 9;
   static constexpr uint64_t TransformMatrix = ((uint64_t)0x1) << 10;
   static constexpr uint64_t ScrollPosition = ((uint64_t)0x1) << 11;
-  static constexpr uint64_t Table = ((uint64_t)0x1) << 11;
-  static constexpr uint64_t TextBounds = ((uint64_t)0x1) << 12;
-  // TODO: Combine TextBounds updates with Bounds updates
+  static constexpr uint64_t Table = ((uint64_t)0x1) << 12;
   static constexpr uint64_t All = ~((uint64_t)0x0);
 };
 
diff --git a/accessible/generic/LocalAccessible.cpp b/accessible/generic/LocalAccessible.cpp
index b4b5b7e8500d419650c31a318a3c5154fd5b55c7..f637eebaf2ae481c9bcbd4b97531b34bac48a7fb 100644
--- a/accessible/generic/LocalAccessible.cpp
+++ b/accessible/generic/LocalAccessible.cpp
@@ -3207,31 +3207,6 @@ already_AddRefed<AccAttributes> LocalAccessible::BundleFieldsForCache(
     }
   }
 
-  nsIFrame* frame = GetFrame();
-  if ((aCacheDomain & CacheDomain::TextBounds) && IsTextLeaf()) {
-    if (frame && frame->IsTextFrame()) {
-      nsTArray<int32_t> charData;
-      nsIFrame* currTextFrame = frame;
-      while (currTextFrame) {
-        nsTArray<nsRect> charBounds;
-        currTextFrame->GetCharacterRectsInRange(
-            0, static_cast<nsTextFrame*>(currTextFrame)->GetContentLength(),
-            charBounds);
-        for (const nsRect& rect : charBounds) {
-          charData.AppendElement(rect.x);
-          charData.AppendElement(rect.y);
-          charData.AppendElement(rect.width);
-          charData.AppendElement(rect.height);
-        }
-        currTextFrame = currTextFrame->GetNextContinuation();
-      }
-
-      if (charData.Length()) {
-        fields->SetAttribute(nsGkAtoms::characterData, std::move(charData));
-      }
-    }
-  }
-
   bool boundsChanged = false;
   if (aCacheDomain & CacheDomain::Bounds) {
     nsRect newBoundsRect = ParentRelativeBounds();
@@ -3281,6 +3256,7 @@ already_AddRefed<AccAttributes> LocalAccessible::BundleFieldsForCache(
     }
   }
 
+  nsIFrame* frame = GetFrame();
   if (aCacheDomain & (CacheDomain::Text | CacheDomain::Bounds) &&
       !HasChildren()) {
     // We cache line start offsets for both text and non-text leaf Accessibles
@@ -3289,9 +3265,9 @@ already_AddRefed<AccAttributes> LocalAccessible::BundleFieldsForCache(
         TextLeafPoint(this, 0).FindNextLineStartSameLocalAcc(
             /* aIncludeOrigin */ true);
     int32_t lineStartOffset = lineStart ? lineStart.mOffset : -1;
-    // We push line starts in two cases:
+    // We push line starts and text bounds in two cases:
     // 1. Text or bounds changed, which means it's very likely that line starts
-    // changed too.
+    // and text bounds changed too.
     // 2. CacheDomain::Bounds was requested (indicating that the frame was
     // reflowed) but the bounds  didn't actually change. This can happen when
     // the spanned text is non-rectangular. For example, an Accessible might
@@ -3316,6 +3292,28 @@ already_AddRefed<AccAttributes> LocalAccessible::BundleFieldsForCache(
       } else if (aUpdateType == CacheUpdateType::Update) {
         fields->SetAttribute(nsGkAtoms::line, DeleteEntry());
       }
+
+      if (frame && frame->IsTextFrame()) {
+        nsTArray<int32_t> charData;
+        nsIFrame* currTextFrame = frame;
+        while (currTextFrame) {
+          nsTArray<nsRect> charBounds;
+          currTextFrame->GetCharacterRectsInRange(
+              0, static_cast<nsTextFrame*>(currTextFrame)->GetContentLength(),
+              charBounds);
+          for (const nsRect& rect : charBounds) {
+            charData.AppendElement(rect.x);
+            charData.AppendElement(rect.y);
+            charData.AppendElement(rect.width);
+            charData.AppendElement(rect.height);
+          }
+          currTextFrame = currTextFrame->GetNextContinuation();
+        }
+
+        if (charData.Length()) {
+          fields->SetAttribute(nsGkAtoms::characterData, std::move(charData));
+        }
+      }
     }
   }
 
@@ -3483,7 +3481,7 @@ already_AddRefed<AccAttributes> LocalAccessible::BundleFieldsForCache(
       }
     }
 
-    if (nsIFrame* frame = GetFrame()) {
+    if (frame) {
       // Note our frame's current computed style so we can track style changes
       // later on.
       mOldComputedStyle = frame->Style();
diff --git a/accessible/tests/browser/e10s/browser_caching_text_bounds.js b/accessible/tests/browser/e10s/browser_caching_text_bounds.js
index cdb62f7225d20463d8c63095a8e0d9e9b879c65a..7262d281828aa1c0b60d247bf74264f68e684409 100644
--- a/accessible/tests/browser/e10s/browser_caching_text_bounds.js
+++ b/accessible/tests/browser/e10s/browser_caching_text_bounds.js
@@ -315,3 +315,26 @@ addAccessibleTask(
     iframe: !isWinNoCache,
   }
 );
+
+/**
+ * Test bounds after text mutations.
+ */
+addAccessibleTask(
+  `<p id="p">a</p>`,
+  async function(browser, docAcc) {
+    await testTextNode(docAcc, browser, "p");
+    const p = findAccessibleChildByID(docAcc, "p");
+    info("Appending a character to text leaf");
+    let textInserted = waitForEvent(EVENT_TEXT_INSERTED, p);
+    await invokeContentTask(browser, [], () => {
+      content.document.getElementById("p").firstChild.data = "ab";
+    });
+    await textInserted;
+    await testTextNode(docAcc, browser, "p");
+  },
+  {
+    chrome: true,
+    topLevel: !isWinNoCache,
+    iframe: !isWinNoCache,
+  }
+);