Merge autoland to mozilla-central. a=merge
authorBogdan Szekely <bszekely@mozilla.com>
Wed, 06 Jul 2022 12:39:26 +0300
changeset 623092 fc7fbf3a78e0776b0a0ff21cf27151e6b6aa5970
parent 623066 1e006be789cd9b2b4bead9fb398c6bfb32ff387d (current diff)
parent 623091 1bc59aea73e0788325eba5d8a35d2195d4724ff9 (diff)
child 623109 e2b5f3d21ea7796a88b5bef89cbc1639635b4e36
push id39942
push userbszekely@mozilla.com
push dateWed, 06 Jul 2022 09:40:22 +0000
treeherdermozilla-central@fc7fbf3a78e0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone104.0a1
first release with
nightly linux32
fc7fbf3a78e0 / 104.0a1 / 20220706094022 / files
nightly linux64
fc7fbf3a78e0 / 104.0a1 / 20220706094022 / files
nightly mac
fc7fbf3a78e0 / 104.0a1 / 20220706094022 / files
nightly win32
fc7fbf3a78e0 / 104.0a1 / 20220706094022 / files
nightly win64
fc7fbf3a78e0 / 104.0a1 / 20220706094022 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge autoland to mozilla-central. a=merge
--- a/accessible/base/TextLeafRange.cpp
+++ b/accessible/base/TextLeafRange.cpp
@@ -1398,17 +1398,17 @@ TextLeafPoint TextLeafPoint::FindTextAtt
       lastPoint.mAcc,
       aDirection == eDirPrevious
           ? 0
           : static_cast<int32_t>(nsAccUtils::TextLength(lastPoint.mAcc)));
 }
 
 LayoutDeviceIntRect TextLeafPoint::CharBounds() {
   if (mAcc && !mAcc->IsText()) {
-    // If we're dealing with an empty embedded object, return the
+    // If we're dealing with an empty container, return the
     // accessible's non-text bounds.
     return mAcc->Bounds();
   }
 
   if (!mAcc || !mAcc->IsRemote() || !mAcc->AsRemote() ||
       !mAcc->AsRemote()->mCachedFields) {
     return LayoutDeviceIntRect();
   }
@@ -1421,9 +1421,19 @@ LayoutDeviceIntRect TextLeafPoint::CharB
     // It is valid for a client to call this with an offset 1 after the last
     // character because of the insertion point at the end of text boxes.
     MOZ_ASSERT(mOffset == static_cast<int32_t>(charBounds->Length()));
   }
 
   return LayoutDeviceIntRect();
 }
 
+bool TextLeafPoint::ContainsPoint(int32_t aX, int32_t aY) {
+  if (mAcc && !mAcc->IsText()) {
+    // If we're dealing with an empty embedded object, use the
+    // accessible's non-text bounds.
+    return mAcc->Bounds().Contains(aX, aY);
+  }
+
+  return CharBounds().Contains(aX, aY);
+}
+
 }  // namespace mozilla::a11y
--- a/accessible/base/TextLeafRange.h
+++ b/accessible/base/TextLeafRange.h
@@ -163,16 +163,25 @@ class TextLeafPoint final {
   /**
    * Returns a rect (in dev pixels) describing position and size of
    * the character at mOffset in mAcc. This rect is screen-relative.
    * This function only works on remote accessibles, and assumes caching
    * is enabled.
    */
   LayoutDeviceIntRect CharBounds();
 
+  /**
+   * Returns true if the given point (in screen coords) is contained
+   * in the char bounds of the current TextLeafPoint. Returns false otherwise.
+   * If the current point is an empty container, we use the acc's bounds instead
+   * of char bounds. Because this depends on CharBounds, this function only
+   * works on remote accessibles, and assumes caching is enabled.
+   */
+  bool ContainsPoint(int32_t aX, int32_t aY);
+
   bool IsLineFeedChar() const { return GetChar() == '\n'; }
 
   bool IsSpace() const;
 
  private:
   bool IsEmptyLastLine() const;
 
   char16_t GetChar() const;
--- a/accessible/basetypes/HyperTextAccessibleBase.cpp
+++ b/accessible/basetypes/HyperTextAccessibleBase.cpp
@@ -242,16 +242,43 @@ LayoutDeviceIntRect HyperTextAccessibleB
   }
 
   // Calls to TextLeafPoint::CharBounds() will construct screen coordinates.
   // Perform any additional conversions here.
   nsAccUtils::ConvertScreenCoordsTo(&result.x, &result.y, aCoordType, Acc());
   return result;
 }
 
+int32_t HyperTextAccessibleBase::OffsetAtPoint(int32_t aX, int32_t aY,
+                                               uint32_t aCoordType) {
+  Accessible* thisAcc = Acc();
+  LayoutDeviceIntPoint coords =
+      nsAccUtils::ConvertToScreenCoords(aX, aY, aCoordType, thisAcc);
+  if (!thisAcc->Bounds().Contains(coords.x, coords.y)) {
+    // The requested point does not exist in this accessible.
+    return -1;
+  }
+
+  TextLeafPoint point = ToTextLeafPoint(0, false);
+  // As with TextBounds, we walk to the very end of the text contained in this
+  // hypertext and then step backwards to make our endPoint inclusive.
+  TextLeafPoint endPoint =
+      ToTextLeafPoint(static_cast<int32_t>(CharacterCount()), true);
+  endPoint =
+      endPoint.FindBoundary(nsIAccessibleText::BOUNDARY_CHAR, eDirPrevious,
+                            /* aIncludeOrigin */ false);
+  // XXX: We should create a TextLeafRange object for this hypertext and move
+  // this search inside the TextLeafRange class.
+  for (; !point.ContainsPoint(coords.x, coords.y) && point != endPoint;
+       point = point.FindBoundary(nsIAccessibleText::BOUNDARY_CHAR, eDirNext,
+                                  /* aIncludeOrigin */ false)) {
+  };
+  return point.ContainsPoint(coords.x, coords.y) ? point.mOffset : -1;
+}
+
 TextLeafPoint HyperTextAccessibleBase::ToTextLeafPoint(int32_t aOffset,
                                                        bool aDescendToEnd) {
   Accessible* thisAcc = Acc();
   if (!thisAcc->HasChildren()) {
     return TextLeafPoint(thisAcc, 0);
   }
   Accessible* child = GetChildAtOffset(aOffset);
   if (!child) {
--- a/accessible/basetypes/HyperTextAccessibleBase.h
+++ b/accessible/basetypes/HyperTextAccessibleBase.h
@@ -111,16 +111,21 @@ class HyperTextAccessibleBase {
    * Return a rect (in dev pixels) of the given text range relative given
    * coordinate system.
    */
   virtual LayoutDeviceIntRect TextBounds(int32_t aStartOffset,
                                          int32_t aEndOffset,
                                          uint32_t aCoordType);
 
   /**
+   * Return the offset of the char that contains the given coordinates.
+   */
+  virtual int32_t OffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType);
+
+  /**
    * Get a TextLeafPoint for a given offset in this HyperTextAccessible.
    * If the offset points to an embedded object and aDescendToEnd is true,
    * the point right at the end of this subtree will be returned instead of the
    * start.
    */
   TextLeafPoint ToTextLeafPoint(int32_t aOffset, bool aDescendToEnd = false);
 
   /**
--- a/accessible/generic/HyperTextAccessible.h
+++ b/accessible/generic/HyperTextAccessible.h
@@ -166,17 +166,17 @@ class HyperTextAccessible : public Acces
 
   virtual LocalAccessible* GetChildAtOffset(uint32_t aOffset) const override {
     return LocalChildAt(GetChildIndexAtOffset(aOffset));
   }
 
   /**
    * Return an offset at the given point.
    */
-  int32_t OffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType);
+  int32_t OffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType) override;
 
   LayoutDeviceIntRect TextBounds(
       int32_t aStartOffset, int32_t aEndOffset,
       uint32_t aCoordType =
           nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE) override;
 
   LayoutDeviceIntRect CharBounds(int32_t aOffset,
                                  uint32_t aCoordType) override {
--- a/accessible/ipc/RemoteAccessibleBase.cpp
+++ b/accessible/ipc/RemoteAccessibleBase.cpp
@@ -479,25 +479,28 @@ void RemoteAccessibleBase<Derived>::Appl
   // moves up/closer to the origin).
   nsPoint scrollOffset(-scrollPosition[0], -scrollPosition[1]);
 
   aBounds.MoveBy(scrollOffset.x, scrollOffset.y);
 }
 
 template <class Derived>
 nsRect RemoteAccessibleBase<Derived>::BoundsInAppUnits() const {
-  dom::CanonicalBrowsingContext* cbc =
-      static_cast<dom::BrowserParent*>(mDoc->Manager())
-          ->GetBrowsingContext()
-          ->Top();
-  dom::BrowserParent* bp = cbc->GetBrowserParent();
-  nsPresContext* presContext =
-      bp->GetOwnerElement()->OwnerDoc()->GetPresContext();
-  return LayoutDeviceIntRect::ToAppUnits(Bounds(),
-                                         presContext->AppUnitsPerDevPixel());
+  if (dom::CanonicalBrowsingContext* cbc = mDoc->GetBrowsingContext()->Top()) {
+    if (dom::BrowserParent* bp = cbc->GetBrowserParent()) {
+      DocAccessibleParent* topDoc = bp->GetTopLevelDocAccessible();
+      if (topDoc && topDoc->mCachedFields) {
+        auto appUnitsPerDevPixel = topDoc->mCachedFields->GetAttribute<int32_t>(
+            nsGkAtoms::_moz_device_pixel_ratio);
+        MOZ_ASSERT(appUnitsPerDevPixel);
+        return LayoutDeviceIntRect::ToAppUnits(Bounds(), *appUnitsPerDevPixel);
+      }
+    }
+  }
+  return LayoutDeviceIntRect::ToAppUnits(Bounds(), AppUnitsPerCSSPixel());
 }
 
 template <class Derived>
 LayoutDeviceIntRect RemoteAccessibleBase<Derived>::BoundsWithOffset(
     Maybe<nsRect> aOffset) const {
   Maybe<nsRect> maybeBounds = RetrieveCachedBounds();
   if (maybeBounds) {
     nsRect bounds = *maybeBounds;
--- a/accessible/ipc/RemoteAccessibleShared.h
+++ b/accessible/ipc/RemoteAccessibleShared.h
@@ -85,17 +85,18 @@ virtual void TextAtOffset(int32_t aOffse
 
 virtual void TextBeforeOffset(int32_t aOffset,
                               AccessibleTextBoundary aBoundaryType,
                               int32_t* aStartOffset, int32_t* aEndOffset,
                               nsAString& aText) override;
 
 char16_t CharAt(int32_t aOffset);
 
-int32_t OffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType);
+virtual int32_t OffsetAtPoint(int32_t aX, int32_t aY,
+                              uint32_t aCoordType) override;
 
 bool SetSelectionBoundsAt(int32_t aSelectionNum, int32_t aStartOffset,
                           int32_t aEndOffset);
 
 bool AddToSelection(int32_t aStartOffset, int32_t aEndOffset);
 
 bool RemoveFromSelection(int32_t aSelectionNum);
 
--- a/accessible/ipc/other/RemoteAccessible.cpp
+++ b/accessible/ipc/other/RemoteAccessible.cpp
@@ -304,16 +304,22 @@ LayoutDeviceIntRect RemoteAccessible::Ch
 
   LayoutDeviceIntRect rect;
   Unused << mDoc->SendCharBounds(mID, aOffset, aCoordType, &rect);
   return rect;
 }
 
 int32_t RemoteAccessible::OffsetAtPoint(int32_t aX, int32_t aY,
                                         uint32_t aCoordType) {
+  if (StaticPrefs::accessibility_cache_enabled_AtStartup()) {
+    MOZ_ASSERT(IsHyperText(), "is not hypertext?");
+    return RemoteAccessibleBase<RemoteAccessible>::OffsetAtPoint(aX, aY,
+                                                                 aCoordType);
+  }
+
   int32_t retVal = -1;
   Unused << mDoc->SendOffsetAtPoint(mID, aX, aY, aCoordType, &retVal);
   return retVal;
 }
 
 bool RemoteAccessible::SelectionBoundsAt(int32_t aSelectionNum, nsString& aData,
                                          int32_t* aStartOffset,
                                          int32_t* aEndOffset) {
--- a/accessible/ipc/win/RemoteAccessible.cpp
+++ b/accessible/ipc/win/RemoteAccessible.cpp
@@ -512,16 +512,21 @@ static IA2TextBoundaryType GetIA2TextBou
       return IA2_TEXT_BOUNDARY_PARAGRAPH;
     default:
       MOZ_CRASH();
   }
 }
 
 int32_t RemoteAccessible::OffsetAtPoint(int32_t aX, int32_t aY,
                                         uint32_t aCoordinateType) {
+  if (StaticPrefs::accessibility_cache_enabled_AtStartup()) {
+    return RemoteAccessibleBase<RemoteAccessible>::OffsetAtPoint(
+        aX, aY, aCoordinateType);
+  }
+
   RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
   if (!acc) {
     return -1;
   }
 
   IA2CoordinateType coordType;
   if (aCoordinateType ==
       nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE) {
--- a/accessible/tests/browser/Layout.jsm
+++ b/accessible/tests/browser/Layout.jsm
@@ -12,17 +12,20 @@ const { CommonUtils } = ChromeUtils.impo
 );
 
 const Layout = {
   /**
    * Zoom the given document.
    */
   zoomDocument(doc, zoom) {
     const bc = BrowsingContext.getFromWindow(doc.defaultView);
-    bc.fullZoom = zoom;
+    // To mirror the behaviour of the UI, we set the zoom
+    // value on the top level browsing context. This value automatically
+    // propagates down to iframes.
+    bc.top.fullZoom = zoom;
   },
 
   /**
    * Set the relative resolution of this document. This is what apz does.
    * On non-mobile platforms you won't see a visible change.
    */
   setResolution(doc, zoom) {
     const windowUtils = doc.defaultView.windowUtils;
--- a/accessible/tests/browser/e10s/browser.ini
+++ b/accessible/tests/browser/e10s/browser.ini
@@ -67,9 +67,8 @@ skip-if =
 [browser_treeupdate_table.js]
 [browser_treeupdate_textleaf.js]
 [browser_treeupdate_visibility.js]
 [browser_treeupdate_whitespace.js]
 skip-if = true # Failing due to incorrect index of test container children on document load.
 [browser_obj_group.js]
 skip-if = os == 'win' # Only supported with cache enabled
 [browser_caching_position.js]
-[browser_caching_hittest.js]
deleted file mode 100644
--- a/accessible/tests/browser/e10s/browser_caching_hittest.js
+++ /dev/null
@@ -1,187 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const { Layout } = ChromeUtils.import(
-  "chrome://mochitests/content/browser/accessible/tests/browser/Layout.jsm"
-);
-
-const { CommonUtils } = ChromeUtils.import(
-  "chrome://mochitests/content/browser/accessible/tests/browser/Common.jsm"
-);
-
-function getChildAtPoint(container, x, y, findDeepestChild) {
-  try {
-    const child = findDeepestChild
-      ? container.getDeepestChildAtPoint(x, y)
-      : container.getChildAtPoint(x, y);
-    info(`Got child with role: ${roleToString(child.role)}`);
-    return child;
-  } catch (e) {
-    // Failed to get child at point.
-  }
-
-  return null;
-}
-
-async function testChildAtPoint(dpr, x, y, container, child, grandChild) {
-  const [containerX, containerY] = Layout.getBounds(container, dpr);
-  x += containerX;
-  y += containerY;
-  await untilCacheIs(
-    () => getChildAtPoint(container, x, y, false),
-    child,
-    `Wrong direct child accessible at the point (${x}, ${y}) of ${CommonUtils.prettyName(
-      container
-    )}, sought ${child ? roleToString(child.role) : "unknown"}`
-  );
-  await untilCacheIs(
-    () => getChildAtPoint(container, x, y, true),
-    grandChild,
-    `Wrong deepest child accessible at the point (${x}, ${y}) of ${CommonUtils.prettyName(
-      container
-    )}, sought ${grandChild ? roleToString(grandChild.role) : "unknown"}`
-  );
-}
-
-async function hitTest(browser, container, child, grandChild) {
-  const [childX, childY] = await getContentBoundsForDOMElm(
-    browser,
-    getAccessibleDOMNodeID(child)
-  );
-  const x = childX + 1;
-  const y = childY + 1;
-
-  await untilCacheIs(
-    () => getChildAtPoint(container, x, y, false),
-    child,
-    `Wrong direct child accessible at the point (${x}, ${y}) of ${CommonUtils.prettyName(
-      container
-    )}, sought ${child ? roleToString(child.role) : "unknown"}`
-  );
-  await untilCacheIs(
-    () => getChildAtPoint(container, x, y, true),
-    grandChild,
-    `Wrong deepest child accessible at the point (${x}, ${y}) of ${CommonUtils.prettyName(
-      container
-    )}, sought ${grandChild ? roleToString(grandChild.role) : "unknown"}`
-  );
-}
-
-async function runTests(browser, accDoc) {
-  await waitForImageMap(browser, accDoc);
-  const dpr = await getContentDPR(browser);
-
-  await testChildAtPoint(
-    dpr,
-    3,
-    3,
-    findAccessibleChildByID(accDoc, "list"),
-    findAccessibleChildByID(accDoc, "listitem"),
-    findAccessibleChildByID(accDoc, "inner").firstChild
-  );
-  todo(
-    false,
-    "Bug 746974 - children must match on all platforms. On Windows, " +
-      "ChildAtPoint with eDeepestChild is incorrectly ignoring MustPrune " +
-      "for the graphic."
-  );
-
-  const txt = findAccessibleChildByID(accDoc, "txt");
-  await testChildAtPoint(dpr, 1, 1, txt, txt, txt);
-
-  info(
-    "::MustPrune case, point is outside of textbox accessible but is in document."
-  );
-  await testChildAtPoint(dpr, -1, -1, txt, null, null);
-
-  info("::MustPrune case, point is outside of root accessible.");
-  await testChildAtPoint(dpr, -10000, -10000, txt, null, null);
-
-  info("Not specific case, point is inside of btn accessible.");
-  const btn = findAccessibleChildByID(accDoc, "btn");
-  await testChildAtPoint(dpr, 1, 1, btn, btn, btn);
-
-  info("Not specific case, point is outside of btn accessible.");
-  await testChildAtPoint(dpr, -1, -1, btn, null, null);
-
-  info(
-    "Out of flow accessible testing, do not return out of flow accessible " +
-      "because it's not a child of the accessible even though visually it is."
-  );
-  await invokeContentTask(browser, [], () => {
-    // We have to reimprot CommonUtils in this scope -- eslint thinks this is
-    // wrong, but if you remove it, things will break.
-    /* eslint-disable no-shadow */
-    const { CommonUtils } = ChromeUtils.import(
-      "chrome://mochitests/content/browser/accessible/tests/browser/Common.jsm"
-    );
-    /* eslint-enable no-shadow */
-    const doc = content.document;
-    const rectArea = CommonUtils.getNode("area", doc).getBoundingClientRect();
-    const outOfFlow = CommonUtils.getNode("outofflow", doc);
-    outOfFlow.style.left = rectArea.left + "px";
-    outOfFlow.style.top = rectArea.top + "px";
-  });
-
-  const area = findAccessibleChildByID(accDoc, "area");
-  await testChildAtPoint(dpr, 1, 1, area, area, area);
-
-  info("Test image maps. Their children are not in the layout tree.");
-  const imgmap = findAccessibleChildByID(accDoc, "imgmap");
-  const theLetterA = imgmap.firstChild;
-  await hitTest(browser, imgmap, theLetterA, theLetterA);
-  await hitTest(
-    browser,
-    findAccessibleChildByID(accDoc, "container"),
-    imgmap,
-    theLetterA
-  );
-
-  info("hit testing for element contained by zero-width element");
-  const container2Input = findAccessibleChildByID(accDoc, "container2_input");
-  await hitTest(
-    browser,
-    findAccessibleChildByID(accDoc, "container2"),
-    container2Input,
-    container2Input
-  );
-}
-
-addAccessibleTask(
-  `
-  <div role="list" id="list">
-    <div role="listitem" id="listitem"><span title="foo" id="inner">inner</span>item</div>
-  </div>
-
-  <span role="button">button1</span><span role="button" id="btn">button2</span>
-
-  <span role="textbox">textbox1</span><span role="textbox" id="txt">textbox2</span>
-
-  <div id="outofflow" style="width: 10px; height: 10px; position: absolute; left: 0px; top: 0px; background-color: yellow;">
-  </div>
-  <div id="area" style="width: 100px; height: 100px; background-color: blue;"></div>
-
-  <map name="atoz_map">
-    <area id="thelettera" href="http://www.bbc.co.uk/radio4/atoz/index.shtml#a"
-          coords="0,0,15,15" alt="thelettera" shape="rect"/>
-  </map>
-
-  <div id="container">
-    <img id="imgmap" width="447" height="15" usemap="#atoz_map" src="http://example.com/a11y/accessible/tests/mochitest/letters.gif"/>
-  </div>
-
-  <div id="container2" style="width: 0px">
-    <input id="container2_input">
-  </div>
-  `,
-  runTests,
-  {
-    iframe: true,
-    remoteIframe: true,
-    // Ensure that all hittest elements are in view.
-    iframeAttrs: { style: "width: 600px; height: 600px; padding: 10px;" },
-  }
-);
--- a/accessible/tests/browser/hittest/browser_test_general.js
+++ b/accessible/tests/browser/hittest/browser_test_general.js
@@ -3,72 +3,66 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 async function runTests(browser, accDoc) {
   await waitForImageMap(browser, accDoc);
   const dpr = await getContentDPR(browser);
 
-  info("Not specific case, child and deepchild testing.");
-  testChildAtPoint(
+  await testChildAtPoint(
     dpr,
     3,
     3,
     findAccessibleChildByID(accDoc, "list"),
     findAccessibleChildByID(accDoc, "listitem"),
     findAccessibleChildByID(accDoc, "inner").firstChild
   );
   todo(
     false,
     "Bug 746974 - children must match on all platforms. On Windows, " +
       "ChildAtPoint with eDeepestChild is incorrectly ignoring MustPrune " +
       "for the graphic."
   );
 
-  info(
-    "::MustPrune case (in this case childAtPoint doesn't look inside a " +
-      "textbox), point is inside of textbox."
-  );
   const txt = findAccessibleChildByID(accDoc, "txt");
-  testChildAtPoint(dpr, 1, 1, txt, txt, txt);
+  await testChildAtPoint(dpr, 1, 1, txt, txt, txt);
 
   info(
     "::MustPrune case, point is outside of textbox accessible but is in document."
   );
-  testChildAtPoint(dpr, -1, -1, txt, null, null);
+  await testChildAtPoint(dpr, -1, -1, txt, null, null);
 
   info("::MustPrune case, point is outside of root accessible.");
-  testChildAtPoint(dpr, -10000, -10000, txt, null, null);
+  await testChildAtPoint(dpr, -10000, -10000, txt, null, null);
 
   info("Not specific case, point is inside of btn accessible.");
   const btn = findAccessibleChildByID(accDoc, "btn");
-  testChildAtPoint(dpr, 1, 1, btn, btn, btn);
+  await testChildAtPoint(dpr, 1, 1, btn, btn, btn);
 
   info("Not specific case, point is outside of btn accessible.");
-  testChildAtPoint(dpr, -1, -1, btn, null, null);
+  await testChildAtPoint(dpr, -1, -1, btn, null, null);
 
   info(
     "Out of flow accessible testing, do not return out of flow accessible " +
       "because it's not a child of the accessible even though visually it is."
   );
   await invokeContentTask(browser, [], () => {
     const { CommonUtils } = ChromeUtils.import(
       "chrome://mochitests/content/browser/accessible/tests/browser/Common.jsm"
     );
-
     const doc = content.document;
     const rectArea = CommonUtils.getNode("area", doc).getBoundingClientRect();
     const outOfFlow = CommonUtils.getNode("outofflow", doc);
     outOfFlow.style.left = rectArea.left + "px";
     outOfFlow.style.top = rectArea.top + "px";
   });
 
   const area = findAccessibleChildByID(accDoc, "area");
-  testChildAtPoint(dpr, 1, 1, area, area, area);
+  await testChildAtPoint(dpr, 1, 1, area, area, area);
 
   info("Test image maps. Their children are not in the layout tree.");
   const imgmap = findAccessibleChildByID(accDoc, "imgmap");
   const theLetterA = imgmap.firstChild;
   await hitTest(browser, imgmap, theLetterA, theLetterA);
   await hitTest(
     browser,
     findAccessibleChildByID(accDoc, "container"),
@@ -113,11 +107,11 @@ addAccessibleTask(
     <input id="container2_input">
   </div>
   `,
   runTests,
   {
     iframe: true,
     remoteIframe: true,
     // Ensure that all hittest elements are in view.
-    iframeAttrs: { style: "width: 600px; height: 600px;" },
+    iframeAttrs: { style: "width: 600px; height: 600px; padding: 10px;" },
   }
 );
--- a/accessible/tests/browser/hittest/browser_test_shadowroot.js
+++ b/accessible/tests/browser/hittest/browser_test_shadowroot.js
@@ -2,27 +2,27 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 async function runTests(browser, accDoc) {
   const dpr = await getContentDPR(browser);
   let componentAcc = findAccessibleChildByID(accDoc, "component1");
-  testChildAtPoint(
+  await testChildAtPoint(
     dpr,
     1,
     1,
     componentAcc,
     componentAcc.firstChild,
     componentAcc.firstChild
   );
 
   componentAcc = findAccessibleChildByID(accDoc, "component2");
-  testChildAtPoint(
+  await testChildAtPoint(
     dpr,
     1,
     1,
     componentAcc,
     componentAcc.firstChild,
     componentAcc.firstChild
   );
 }
--- a/accessible/tests/browser/hittest/browser_test_zoom_text.js
+++ b/accessible/tests/browser/hittest/browser_test_zoom_text.js
@@ -2,44 +2,43 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 /**
  * Test if getOffsetAtPoint returns the given text offset at given coordinates.
  */
-function testOffsetAtPoint(hyperText, x, y, coordType, expectedOffset) {
-  is(
-    hyperText.getOffsetAtPoint(x, y, coordType),
+async function testOffsetAtPoint(hyperText, x, y, coordType, expectedOffset) {
+  await untilCacheIs(
+    () => hyperText.getOffsetAtPoint(x, y, coordType),
     expectedOffset,
     `Wrong offset at given point (${x}, ${y}) for ${prettyName(hyperText)}`
   );
 }
 
 async function runTests(browser, accDoc) {
   const expectedLength = await invokeContentTask(browser, [], () => {
     const { CommonUtils } = ChromeUtils.import(
       "chrome://mochitests/content/browser/accessible/tests/browser/Common.jsm"
     );
     const hyperText = CommonUtils.getNode("paragraph", content.document);
-
-    return hyperText.textContent.length / 2;
+    return Math.floor(hyperText.textContent.length / 2);
   });
   const hyperText = findAccessibleChildByID(accDoc, "paragraph", [
     Ci.nsIAccessibleText,
   ]);
   const textNode = hyperText.firstChild;
 
   let [x, y, width, height] = Layout.getBounds(
     textNode,
     await getContentDPR(browser)
   );
 
-  testOffsetAtPoint(
+  await testOffsetAtPoint(
     hyperText,
     x + width / 2,
     y + height / 2,
     COORDTYPE_SCREEN_RELATIVE,
     expectedLength
   );
 
   await invokeContentTask(browser, [], () => {
@@ -51,26 +50,26 @@ async function runTests(browser, accDoc)
     content.document.body.offsetTop; // getBounds doesn't flush layout on its own.
   });
 
   [x, y, width, height] = Layout.getBounds(
     textNode,
     await getContentDPR(browser)
   );
 
-  testOffsetAtPoint(
+  await testOffsetAtPoint(
     hyperText,
     x + width / 2,
     y + height / 2,
     COORDTYPE_SCREEN_RELATIVE,
     expectedLength
   );
 }
 
 addAccessibleTask(
-  `<p id="paragraph" style="font-family: monospace;">Болтали две сороки</p>`,
+  `<p id="paragraph" style="font-family: monospace;">hello world hello world</p>`,
   runTests,
   {
     iframe: true,
     remoteIframe: true,
     iframeAttrs: { style: "width: 600px; height: 600px;" },
   }
 );
--- a/accessible/tests/browser/hittest/head.js
+++ b/accessible/tests/browser/hittest/head.js
@@ -36,54 +36,55 @@ function getChildAtPoint(container, x, y
       : container.getChildAtPoint(x, y);
   } catch (e) {
     // Failed to get child at point.
   }
 
   return null;
 }
 
-function testChildAtPoint(dpr, x, y, container, child, grandChild) {
+async function testChildAtPoint(dpr, x, y, container, child, grandChild) {
   const [containerX, containerY] = Layout.getBounds(container, dpr);
   x += containerX;
   y += containerY;
-
-  CommonUtils.isObject(
-    getChildAtPoint(container, x, y, false),
+  await untilCacheIs(
+    () => getChildAtPoint(container, x, y, false),
     child,
     `Wrong direct child accessible at the point (${x}, ${y}) of ${CommonUtils.prettyName(
       container
-    )}`
+    )}, sought ${child ? roleToString(child.role) : "unknown"}`
   );
-
-  CommonUtils.isObject(
-    getChildAtPoint(container, x, y, true),
+  await untilCacheIs(
+    () => getChildAtPoint(container, x, y, true),
     grandChild,
     `Wrong deepest child accessible at the point (${x}, ${y}) of ${CommonUtils.prettyName(
       container
-    )}`
+    )}, sought ${grandChild ? roleToString(grandChild.role) : "unknown"}`
   );
 }
 
 /**
  * Test if getChildAtPoint returns the given child and grand child accessibles
  * at coordinates of child accessible (direct and deep hit test).
  */
 async function hitTest(browser, container, child, grandChild) {
   const [childX, childY] = await getContentBoundsForDOMElm(
     browser,
     getAccessibleDOMNodeID(child)
   );
   const x = childX + 1;
   const y = childY + 1;
 
-  CommonUtils.isObject(
-    getChildAtPoint(container, x, y, false),
+  await untilCacheIs(
+    () => getChildAtPoint(container, x, y, false),
     child,
-    `Wrong direct child of ${prettyName(container)}`
+    `Wrong direct child accessible at the point (${x}, ${y}) of ${CommonUtils.prettyName(
+      container
+    )}, sought ${child ? roleToString(child.role) : "unknown"}`
   );
-
-  CommonUtils.isObject(
-    getChildAtPoint(container, x, y, true),
+  await untilCacheIs(
+    () => getChildAtPoint(container, x, y, true),
     grandChild,
-    `Wrong deepest child of ${prettyName(container)}`
+    `Wrong deepest child accessible at the point (${x}, ${y}) of ${CommonUtils.prettyName(
+      container
+    )}, sought ${grandChild ? roleToString(grandChild.role) : "unknown"}`
   );
 }
--- a/accessible/windows/msaa/MsaaAccessible.cpp
+++ b/accessible/windows/msaa/MsaaAccessible.cpp
@@ -484,16 +484,26 @@ static already_AddRefed<IDispatch> GetPr
   RefPtr<IDispatch> disp;
   if (FAILED(comProxy->get_accChild(aVarChild, getter_AddRefs(disp)))) {
     return nullptr;
   }
 
   return disp.forget();
 }
 
+static bool IsInclusiveDescendantOf(DocAccessible* aAncestor,
+                                    DocAccessible* aDescendant) {
+  for (DocAccessible* doc = aDescendant; doc; doc = doc->ParentDocument()) {
+    if (doc == aAncestor) {
+      return true;
+    }
+  }
+  return false;
+}
+
 already_AddRefed<IAccessible> MsaaAccessible::GetIAccessibleFor(
     const VARIANT& aVarChild, bool* aIsDefunct) {
   if (aVarChild.vt != VT_I4) return nullptr;
 
   VARIANT varChild = aVarChild;
 
   MOZ_ASSERT(aIsDefunct);
   *aIsDefunct = false;
@@ -597,19 +607,18 @@ already_AddRefed<IAccessible> MsaaAccess
     if (!child && StaticPrefs::accessibility_cache_enabled_AtStartup()) {
       // Search remote documents which are descendants of this local document.
       const auto remoteDocs = DocManager::TopLevelRemoteDocs();
       if (!remoteDocs) {
         return nullptr;
       }
       for (DocAccessibleParent* remoteDoc : *remoteDocs) {
         LocalAccessible* outerDoc = remoteDoc->OuterDocOfRemoteBrowser();
-        if (!outerDoc || outerDoc->Document() != localDoc) {
-          // The OuterDoc isn't inside our document, so this isn't a
-          // descendant.
+        if (!outerDoc ||
+            !IsInclusiveDescendantOf(localDoc, outerDoc->Document())) {
           continue;
         }
         child = GetAccessibleInSubtree(remoteDoc, id);
         if (child) {
           break;
         }
       }
     }
--- a/accessible/windows/msaa/MsaaRootAccessible.cpp
+++ b/accessible/windows/msaa/MsaaRootAccessible.cpp
@@ -1,13 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "mozilla/a11y/DocAccessibleParent.h"
+#include "mozilla/dom/BrowserParent.h"
 #include "mozilla/WindowsVersion.h"
 #include "MsaaRootAccessible.h"
 #include "Relation.h"
 #include "RootAccessible.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
@@ -124,22 +126,21 @@ MsaaRootAccessible::get_accFocus(
   }
 
   // The base implementation reported no focus.
   // Focus might be in a remote document.
   // (The base implementation can't handle this.)
   if (StaticPrefs::accessibility_cache_enabled_AtStartup()) {
     return S_FALSE;
   }
-  // Get the document in the active tab.
-  RootAccessible* rootAcc = RootAcc();
-  if (!rootAcc) {
-    return CO_E_OBJNOTCONNECTED;
+  dom::BrowserParent* browser = dom::BrowserParent::GetFocused();
+  if (!browser) {
+    return hr;
   }
-  RemoteAccessible* docProxy = rootAcc->GetPrimaryRemoteTopLevelContentDoc();
+  DocAccessibleParent* docProxy = browser->GetTopLevelDocAccessible();
   if (!docProxy) {
     return hr;
   }
   RefPtr<IDispatch> docDisp = NativeAccessible(docProxy);
   if (!docDisp) {
     return E_FAIL;
   }
   RefPtr<IAccessible> docIa;
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1521,18 +1521,16 @@ pref("browser.newtabpage.activity-stream
 pref("browser.newtabpage.activity-stream.asrouter.useRemoteL10n", true);
 
 // These prefs control if Discovery Stream is enabled.
 pref("browser.newtabpage.activity-stream.discoverystream.enabled", true);
 pref("browser.newtabpage.activity-stream.discoverystream.hardcoded-basic-layout", false);
 pref("browser.newtabpage.activity-stream.discoverystream.hybridLayout.enabled", false);
 pref("browser.newtabpage.activity-stream.discoverystream.hideCardBackground.enabled", false);
 pref("browser.newtabpage.activity-stream.discoverystream.fourCardLayout.enabled", false);
-pref("browser.newtabpage.activity-stream.discoverystream.loadMore.enabled", false);
-pref("browser.newtabpage.activity-stream.discoverystream.lastCardMessage.enabled", false);
 pref("browser.newtabpage.activity-stream.discoverystream.newFooterSection.enabled", false);
 pref("browser.newtabpage.activity-stream.discoverystream.saveToPocketCard.enabled", false);
 pref("browser.newtabpage.activity-stream.discoverystream.hideDescriptions.enabled", false);
 pref("browser.newtabpage.activity-stream.discoverystream.compactGrid.enabled", false);
 pref("browser.newtabpage.activity-stream.discoverystream.compactImages.enabled", false);
 pref("browser.newtabpage.activity-stream.discoverystream.imageGradient.enabled", false);
 pref("browser.newtabpage.activity-stream.discoverystream.titleLines", 3);
 pref("browser.newtabpage.activity-stream.discoverystream.descLines", 3);
--- a/browser/components/newtab/content-src/components/DiscoveryStreamBase/DiscoveryStreamBase.jsx
+++ b/browser/components/newtab/content-src/components/DiscoveryStreamBase/DiscoveryStreamBase.jsx
@@ -220,18 +220,16 @@ export class _DiscoveryStreamBase extend
             compactImages={component.properties.compactImages}
             imageGradient={component.properties.imageGradient}
             newSponsoredLabel={component.properties.newSponsoredLabel}
             titleLines={component.properties.titleLines}
             descLines={component.properties.descLines}
             essentialReadsHeader={component.properties.essentialReadsHeader}
             editorsPicksHeader={component.properties.editorsPicksHeader}
             readTime={component.properties.readTime}
-            loadMore={component.loadMore}
-            lastCardMessageEnabled={component.lastCardMessageEnabled}
             saveToPocketCard={component.saveToPocketCard}
             cta_variant={component.cta_variant}
             pocket_button_enabled={component.pocketButtonEnabled}
             display_engagement_labels={ENGAGEMENT_LABEL_ENABLED}
           />
         );
       case "HorizontalRule":
         return <HorizontalRule />;
--- a/browser/components/newtab/content-src/components/DiscoveryStreamComponents/CardGrid/CardGrid.jsx
+++ b/browser/components/newtab/content-src/components/DiscoveryStreamComponents/CardGrid/CardGrid.jsx
@@ -1,17 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-import {
-  DSCard,
-  PlaceholderDSCard,
-  LastCardMessage,
-} from "../DSCard/DSCard.jsx";
+import { DSCard, PlaceholderDSCard } from "../DSCard/DSCard.jsx";
 import { DSEmptyState } from "../DSEmptyState/DSEmptyState.jsx";
 import { TopicsWidget } from "../TopicsWidget/TopicsWidget.jsx";
 import { SafeAnchor } from "../SafeAnchor/SafeAnchor";
 import { FluentOrText } from "../../FluentOrText/FluentOrText.jsx";
 import { actionCreators as ac, actionTypes as at } from "common/Actions.jsm";
 import React, { useEffect, useState, useRef, useCallback } from "react";
 import { connect, useSelector } from "react-redux";
 const WIDGET_IDS = {
@@ -176,72 +172,39 @@ export function RecentSavesContainer({
         </SafeAnchor>
       </DSSubHeader>
       <div className={gridClassName}>{recentSavesCards}</div>
     </>
   );
 }
 
 export class _CardGrid extends React.PureComponent {
-  constructor(props) {
-    super(props);
-    this.state = { moreLoaded: false };
-    this.loadMoreClicked = this.loadMoreClicked.bind(this);
-  }
-
-  loadMoreClicked() {
-    this.props.dispatch(
-      ac.UserEvent({
-        event: "CLICK",
-        source: "DS_LOAD_MORE_BUTTON",
-      })
-    );
-    this.setState({ moreLoaded: true });
-  }
-
-  get showLoadMore() {
-    const { loadMore, data, loadMoreThreshold } = this.props;
-    return (
-      loadMore &&
-      data.recommendations.length > loadMoreThreshold &&
-      !this.state.moreLoaded
-    );
-  }
-
   renderCards() {
-    let { items } = this.props;
     const { DiscoveryStream } = this.props;
     const prefs = this.props.Prefs.values;
     const { recentSavesEnabled } = DiscoveryStream;
     const showRecentSaves = prefs.showRecentSaves && recentSavesEnabled;
     const {
+      items,
       hybridLayout,
       hideCardBackground,
       fourCardLayout,
       hideDescriptions,
-      lastCardMessageEnabled,
       saveToPocketCard,
-      loadMoreThreshold,
       compactGrid,
       compactImages,
       imageGradient,
       newSponsoredLabel,
       titleLines,
       descLines,
       readTime,
       essentialReadsHeader,
       editorsPicksHeader,
       widgets,
     } = this.props;
-    let showLastCardMessage = lastCardMessageEnabled;
-    if (this.showLoadMore) {
-      items = loadMoreThreshold;
-      // We don't want to show this until after load more has been clicked.
-      showLastCardMessage = false;
-    }
 
     const recs = this.props.data.recommendations.slice(0, items);
     const cards = [];
     let essentialReadsCards = [];
     let editorsPicksCards = [];
 
     for (let index = 0; index < items; index++) {
       const rec = recs[index];
@@ -286,25 +249,16 @@ export class _CardGrid extends React.Pur
             cta_variant={this.props.cta_variant}
             is_video={this.props.enable_video_playheads && rec.is_video}
             is_collection={this.props.is_collection}
           />
         )
       );
     }
 
-    // Replace last card with "you are all caught up card"
-    if (showLastCardMessage) {
-      cards.splice(
-        cards.length - 1,
-        1,
-        <LastCardMessage key={`dscard-last-${cards.length - 1}`} />
-      );
-    }
-
     if (widgets?.positions?.length && widgets?.data?.length) {
       let positionIndex = 0;
       const source = "CARDGRID_WIDGET";
 
       for (const widget of widgets.data) {
         let widgetComponent = null;
         const position = widgets.positions[positionIndex];
 
@@ -439,33 +393,24 @@ export class _CardGrid extends React.Pur
               status={data.status}
               dispatch={this.props.dispatch}
               feed={this.props.feed}
             />
           </div>
         ) : (
           this.renderCards()
         )}
-        {this.showLoadMore && (
-          <button
-            className="ASRouterButton primary ds-card-grid-load-more-button"
-            onClick={this.loadMoreClicked}
-            data-l10n-id="newtab-pocket-load-more-stories-button"
-          />
-        )}
       </div>
     );
   }
 }
 
 _CardGrid.defaultProps = {
   border: `border`,
   items: 4, // Number of stories to display
   enable_video_playheads: false,
-  lastCardMessageEnabled: false,
   saveToPocketCard: false,
-  loadMoreThreshold: 12,
 };
 
 export const CardGrid = connect(state => ({
   Prefs: state.Prefs,
   DiscoveryStream: state.DiscoveryStream,
 }))(_CardGrid);
--- a/browser/components/newtab/content-src/components/DiscoveryStreamComponents/CardGrid/_CardGrid.scss
+++ b/browser/components/newtab/content-src/components/DiscoveryStreamComponents/CardGrid/_CardGrid.scss
@@ -155,25 +155,23 @@
       }
 
       .meta {
         .story-footer {
           margin-top: 8px;
         }
 
         .source,
-        .ds-last-card-desc,
         .story-sponsored-label,
         .status-message .story-context-label {
           color: var(--newtab-text-secondary-color);
           -webkit-line-clamp: 2;
         }
 
         .source,
-        .ds-last-card-desc,
         .story-sponsored-label {
           font-size: 13px;
         }
 
         .status-message .story-context-label {
           font-size: 11.7px;
         }
 
@@ -266,22 +264,16 @@
       .img-wrapper .img img {
         @include ds-focus;
       }
     }
 
     .img-wrapper .img img {
       border-radius: 8px;
       box-shadow: $shadow-card;
-
-      &.last-card-message-image {
-        background: transparent;
-        box-shadow: none;
-        object-fit: contain;
-      }
     }
 
     .meta {
       padding: 12px 0 0;
     }
   }
 }
 
@@ -306,17 +298,9 @@
         text-decoration: underline;
       }
 
       &:active {
         color: var(--newtab-primary-element-active-color);
       }
     }
   }
-
-  .ds-card-grid-load-more-button {
-    display: block;
-    margin: 32px auto 0;
-    font-size: 13px;
-    line-height: 16px;
-    border-radius: 4px;
-  }
 }
--- a/browser/components/newtab/content-src/components/DiscoveryStreamComponents/DSCard/DSCard.jsx
+++ b/browser/components/newtab/content-src/components/DiscoveryStreamComponents/DSCard/DSCard.jsx
@@ -375,44 +375,16 @@ export class _DSCard extends React.PureC
 
   render() {
     if (this.props.placeholder || !this.state.isSeen) {
       return (
         <div className="ds-card placeholder" ref={this.setPlaceholderRef} />
       );
     }
 
-    if (this.props.lastCard) {
-      return (
-        <div className="ds-card last-card-message">
-          <div className="img-wrapper">
-            <picture className="ds-image img loaded">
-              <img
-                data-l10n-id="newtab-pocket-last-card-image"
-                className="last-card-message-image"
-                src="chrome://activity-stream/content/data/content/assets/caught-up-illustration.svg"
-                alt="You’re all caught up"
-              />
-            </picture>
-          </div>
-          <div className="meta">
-            <div className="info-wrap">
-              <header
-                className="title clamp"
-                data-l10n-id="newtab-pocket-last-card-title"
-              />
-              <p
-                className="ds-last-card-desc"
-                data-l10n-id="newtab-pocket-last-card-desc"
-              />
-            </div>
-          </div>
-        </div>
-      );
-    }
     const isButtonCTA = this.props.cta_variant === "button";
 
     const {
       is_video,
       saveToPocketCard,
       hideDescriptions,
       compactImages,
       imageGradient,
@@ -580,9 +552,8 @@ export class _DSCard extends React.PureC
   windowObj: window, // Added to support unit tests
 };
 
 export const DSCard = connect(state => ({
   App: state.App,
 }))(_DSCard);
 
 export const PlaceholderDSCard = props => <DSCard placeholder={true} />;
-export const LastCardMessage = props => <DSCard lastCard={true} />;
--- a/browser/components/newtab/content-src/components/DiscoveryStreamComponents/DSCard/_DSCard.scss
+++ b/browser/components/newtab/content-src/components/DiscoveryStreamComponents/DSCard/_DSCard.scss
@@ -191,34 +191,16 @@
       }
     }
   }
 
   &.video-card .meta {
     margin-top: 4px;
   }
 
-  &.last-card-message {
-    .ds-last-card-desc {
-      font-size: 13px;
-      color: var(--newtab-text-secondary-color);
-    }
-
-    .ds-last-card-desc,
-    .title {
-      text-align: center;
-    }
-
-    .last-card-message-image {
-      object-fit: contain;
-      background: transparent;
-      box-shadow: none;
-    }
-  }
-
   .meta {
     display: flex;
     flex-direction: column;
     padding: 12px 16px;
     flex-grow: 1;
 
     .info-wrap {
       flex-grow: 1;
--- a/browser/components/newtab/css/activity-stream-linux.css
+++ b/browser/components/newtab/css/activity-stream-linux.css
@@ -2757,24 +2757,22 @@ main.has-snippet {
 }
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card.placeholder {
   min-height: 247px;
 }
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .story-footer {
   margin-top: 8px;
 }
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .source,
-.ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .ds-last-card-desc,
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .story-sponsored-label,
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .status-message .story-context-label {
   color: var(--newtab-text-secondary-color);
   -webkit-line-clamp: 2;
 }
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .source,
-.ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .ds-last-card-desc,
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .story-sponsored-label {
   font-size: 13px;
 }
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .status-message .story-context-label {
   font-size: 11.7px;
 }
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .story-badge-icon {
   margin-inline-end: 2px;
@@ -2811,39 +2809,31 @@ main.has-snippet {
 @media (max-width: 1122px) {
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder {
     min-height: 247px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer {
     margin-top: 8px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label {
     color: var(--newtab-text-secondary-color);
     -webkit-line-clamp: 2;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label {
     font-size: 13px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label {
     font-size: 11.7px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon {
     margin-inline-end: 2px;
@@ -2866,39 +2856,31 @@ main.has-snippet {
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder {
     min-height: 247px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer {
     margin-top: 8px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label {
     color: var(--newtab-text-secondary-color);
     -webkit-line-clamp: 2;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label {
     font-size: 13px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label {
     font-size: 11.7px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon {
     margin-inline-end: 2px;
@@ -2931,22 +2913,16 @@ main.has-snippet {
   outline: 0;
   box-shadow: 0 0 0 3px var(--newtab-primary-action-background-dimmed), 0 0 0 1px var(--newtab-primary-action-background);
 }
 .outer-wrapper .ds-card-grid.ds-card-grid-hide-background.ds-card-grid-border .ds-card:not(.placeholder) .img-wrapper .img img,
 .outer-wrapper.newtab-experience .ds-card-grid.ds-card-grid-hide-background.ds-card-grid-border .ds-card:not(.placeholder) .img-wrapper .img img {
   border-radius: 8px;
   box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
 }
-.outer-wrapper .ds-card-grid.ds-card-grid-hide-background.ds-card-grid-border .ds-card:not(.placeholder) .img-wrapper .img img.last-card-message-image,
-.outer-wrapper.newtab-experience .ds-card-grid.ds-card-grid-hide-background.ds-card-grid-border .ds-card:not(.placeholder) .img-wrapper .img img.last-card-message-image {
-  background: transparent;
-  box-shadow: none;
-  object-fit: contain;
-}
 .outer-wrapper .ds-card-grid.ds-card-grid-hide-background.ds-card-grid-border .ds-card:not(.placeholder) .meta,
 .outer-wrapper.newtab-experience .ds-card-grid.ds-card-grid-hide-background.ds-card-grid-border .ds-card:not(.placeholder) .meta {
   padding: 12px 0 0;
 }
 
 .ds-layout .ds-sub-header {
   margin-top: 24px;
 }
@@ -2963,23 +2939,16 @@ main.has-snippet {
   cursor: pointer;
 }
 .ds-layout .ds-sub-header .section-sub-link:hover {
   text-decoration: underline;
 }
 .ds-layout .ds-sub-header .section-sub-link:active {
   color: var(--newtab-primary-element-active-color);
 }
-.ds-layout .ds-card-grid-load-more-button {
-  display: block;
-  margin: 32px auto 0;
-  font-size: 13px;
-  line-height: 16px;
-  border-radius: 4px;
-}
 
 .ds-dismiss.ds-dismiss-ds-collection .ds-dismiss-button {
   margin: 15px 0 0;
   inset-inline-end: 25px;
 }
 .ds-dismiss.ds-dismiss-ds-collection.hovering {
   background: var(--newtab-element-hover-color);
 }
@@ -3501,29 +3470,16 @@ main.has-snippet {
   color: var(--newtab-primary-action-background);
 }
 .ds-card .ds-card-link:active header {
   color: var(--newtab-primary-element-active-color);
 }
 .ds-card.video-card .meta {
   margin-top: 4px;
 }
-.ds-card.last-card-message .ds-last-card-desc {
-  font-size: 13px;
-  color: var(--newtab-text-secondary-color);
-}
-.ds-card.last-card-message .ds-last-card-desc,
-.ds-card.last-card-message .title {
-  text-align: center;
-}
-.ds-card.last-card-message .last-card-message-image {
-  object-fit: contain;
-  background: transparent;
-  box-shadow: none;
-}
 .ds-card .meta {
   display: flex;
   flex-direction: column;
   padding: 12px 16px;
   flex-grow: 1;
 }
 .ds-card .meta .info-wrap {
   flex-grow: 1;
--- a/browser/components/newtab/css/activity-stream-mac.css
+++ b/browser/components/newtab/css/activity-stream-mac.css
@@ -2761,24 +2761,22 @@ main.has-snippet {
 }
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card.placeholder {
   min-height: 247px;
 }
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .story-footer {
   margin-top: 8px;
 }
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .source,
-.ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .ds-last-card-desc,
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .story-sponsored-label,
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .status-message .story-context-label {
   color: var(--newtab-text-secondary-color);
   -webkit-line-clamp: 2;
 }
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .source,
-.ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .ds-last-card-desc,
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .story-sponsored-label {
   font-size: 13px;
 }
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .status-message .story-context-label {
   font-size: 11.7px;
 }
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .story-badge-icon {
   margin-inline-end: 2px;
@@ -2815,39 +2813,31 @@ main.has-snippet {
 @media (max-width: 1122px) {
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder {
     min-height: 247px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer {
     margin-top: 8px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label {
     color: var(--newtab-text-secondary-color);
     -webkit-line-clamp: 2;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label {
     font-size: 13px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label {
     font-size: 11.7px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon {
     margin-inline-end: 2px;
@@ -2870,39 +2860,31 @@ main.has-snippet {
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder {
     min-height: 247px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer {
     margin-top: 8px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label {
     color: var(--newtab-text-secondary-color);
     -webkit-line-clamp: 2;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label {
     font-size: 13px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label {
     font-size: 11.7px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon {
     margin-inline-end: 2px;
@@ -2935,22 +2917,16 @@ main.has-snippet {
   outline: 0;
   box-shadow: 0 0 0 3px var(--newtab-primary-action-background-dimmed), 0 0 0 1px var(--newtab-primary-action-background);
 }
 .outer-wrapper .ds-card-grid.ds-card-grid-hide-background.ds-card-grid-border .ds-card:not(.placeholder) .img-wrapper .img img,
 .outer-wrapper.newtab-experience .ds-card-grid.ds-card-grid-hide-background.ds-card-grid-border .ds-card:not(.placeholder) .img-wrapper .img img {
   border-radius: 8px;
   box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
 }
-.outer-wrapper .ds-card-grid.ds-card-grid-hide-background.ds-card-grid-border .ds-card:not(.placeholder) .img-wrapper .img img.last-card-message-image,
-.outer-wrapper.newtab-experience .ds-card-grid.ds-card-grid-hide-background.ds-card-grid-border .ds-card:not(.placeholder) .img-wrapper .img img.last-card-message-image {
-  background: transparent;
-  box-shadow: none;
-  object-fit: contain;
-}
 .outer-wrapper .ds-card-grid.ds-card-grid-hide-background.ds-card-grid-border .ds-card:not(.placeholder) .meta,
 .outer-wrapper.newtab-experience .ds-card-grid.ds-card-grid-hide-background.ds-card-grid-border .ds-card:not(.placeholder) .meta {
   padding: 12px 0 0;
 }
 
 .ds-layout .ds-sub-header {
   margin-top: 24px;
 }
@@ -2967,23 +2943,16 @@ main.has-snippet {
   cursor: pointer;
 }
 .ds-layout .ds-sub-header .section-sub-link:hover {
   text-decoration: underline;
 }
 .ds-layout .ds-sub-header .section-sub-link:active {
   color: var(--newtab-primary-element-active-color);
 }
-.ds-layout .ds-card-grid-load-more-button {
-  display: block;
-  margin: 32px auto 0;
-  font-size: 13px;
-  line-height: 16px;
-  border-radius: 4px;
-}
 
 .ds-dismiss.ds-dismiss-ds-collection .ds-dismiss-button {
   margin: 15px 0 0;
   inset-inline-end: 25px;
 }
 .ds-dismiss.ds-dismiss-ds-collection.hovering {
   background: var(--newtab-element-hover-color);
 }
@@ -3505,29 +3474,16 @@ main.has-snippet {
   color: var(--newtab-primary-action-background);
 }
 .ds-card .ds-card-link:active header {
   color: var(--newtab-primary-element-active-color);
 }
 .ds-card.video-card .meta {
   margin-top: 4px;
 }
-.ds-card.last-card-message .ds-last-card-desc {
-  font-size: 13px;
-  color: var(--newtab-text-secondary-color);
-}
-.ds-card.last-card-message .ds-last-card-desc,
-.ds-card.last-card-message .title {
-  text-align: center;
-}
-.ds-card.last-card-message .last-card-message-image {
-  object-fit: contain;
-  background: transparent;
-  box-shadow: none;
-}
 .ds-card .meta {
   display: flex;
   flex-direction: column;
   padding: 12px 16px;
   flex-grow: 1;
 }
 .ds-card .meta .info-wrap {
   flex-grow: 1;
--- a/browser/components/newtab/css/activity-stream-windows.css
+++ b/browser/components/newtab/css/activity-stream-windows.css
@@ -2757,24 +2757,22 @@ main.has-snippet {
 }
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card.placeholder {
   min-height: 247px;
 }
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .story-footer {
   margin-top: 8px;
 }
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .source,
-.ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .ds-last-card-desc,
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .story-sponsored-label,
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .status-message .story-context-label {
   color: var(--newtab-text-secondary-color);
   -webkit-line-clamp: 2;
 }
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .source,
-.ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .ds-last-card-desc,
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .story-sponsored-label {
   font-size: 13px;
 }
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .status-message .story-context-label {
   font-size: 11.7px;
 }
 .ds-card-grid.ds-card-grid-four-card-variant .ds-card .meta .story-badge-icon {
   margin-inline-end: 2px;
@@ -2811,39 +2809,31 @@ main.has-snippet {
 @media (max-width: 1122px) {
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder {
     min-height: 247px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer {
     margin-top: 8px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label {
     color: var(--newtab-text-secondary-color);
     -webkit-line-clamp: 2;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label {
     font-size: 13px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label {
     font-size: 11.7px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon {
     margin-inline-end: 2px;
@@ -2866,39 +2856,31 @@ main.has-snippet {
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card.placeholder {
     min-height: 247px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-footer {
     margin-top: 8px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label,
 .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label {
     color: var(--newtab-text-secondary-color);
     -webkit-line-clamp: 2;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .source,
-.ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .ds-last-card-desc,
 .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-sponsored-label {
     font-size: 13px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .status-message .story-context-label {
     font-size: 11.7px;
   }
   .ds-column-9 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon, .ds-column-10 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon, .ds-column-11 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon, .ds-column-12 .ds-card-grid.ds-card-grid-hybrid-layout .ds-card .meta .story-badge-icon {
     margin-inline-end: 2px;
@@ -2931,22 +2913,16 @@ main.has-snippet {
   outline: 0;
   box-shadow: 0 0 0 3px var(--newtab-primary-action-background-dimmed), 0 0 0 1px var(--newtab-primary-action-background);
 }
 .outer-wrapper .ds-card-grid.ds-card-grid-hide-background.ds-card-grid-border .ds-card:not(.placeholder) .img-wrapper .img img,
 .outer-wrapper.newtab-experience .ds-card-grid.ds-card-grid-hide-background.ds-card-grid-border .ds-card:not(.placeholder) .img-wrapper .img img {
   border-radius: 8px;
   box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
 }
-.outer-wrapper .ds-card-grid.ds-card-grid-hide-background.ds-card-grid-border .ds-card:not(.placeholder) .img-wrapper .img img.last-card-message-image,
-.outer-wrapper.newtab-experience .ds-card-grid.ds-card-grid-hide-background.ds-card-grid-border .ds-card:not(.placeholder) .img-wrapper .img img.last-card-message-image {
-  background: transparent;
-  box-shadow: none;
-  object-fit: contain;
-}
 .outer-wrapper .ds-card-grid.ds-card-grid-hide-background.ds-card-grid-border .ds-card:not(.placeholder) .meta,
 .outer-wrapper.newtab-experience .ds-card-grid.ds-card-grid-hide-background.ds-card-grid-border .ds-card:not(.placeholder) .meta {
   padding: 12px 0 0;
 }
 
 .ds-layout .ds-sub-header {
   margin-top: 24px;
 }
@@ -2963,23 +2939,16 @@ main.has-snippet {
   cursor: pointer;
 }
 .ds-layout .ds-sub-header .section-sub-link:hover {
   text-decoration: underline;
 }
 .ds-layout .ds-sub-header .section-sub-link:active {
   color: var(--newtab-primary-element-active-color);
 }
-.ds-layout .ds-card-grid-load-more-button {
-  display: block;
-  margin: 32px auto 0;
-  font-size: 13px;
-  line-height: 16px;
-  border-radius: 4px;
-}
 
 .ds-dismiss.ds-dismiss-ds-collection .ds-dismiss-button {
   margin: 15px 0 0;
   inset-inline-end: 25px;
 }
 .ds-dismiss.ds-dismiss-ds-collection.hovering {
   background: var(--newtab-element-hover-color);
 }
@@ -3501,29 +3470,16 @@ main.has-snippet {
   color: var(--newtab-primary-action-background);
 }
 .ds-card .ds-card-link:active header {
   color: var(--newtab-primary-element-active-color);
 }
 .ds-card.video-card .meta {
   margin-top: 4px;
 }
-.ds-card.last-card-message .ds-last-card-desc {
-  font-size: 13px;
-  color: var(--newtab-text-secondary-color);
-}
-.ds-card.last-card-message .ds-last-card-desc,
-.ds-card.last-card-message .title {
-  text-align: center;
-}
-.ds-card.last-card-message .last-card-message-image {
-  object-fit: contain;
-  background: transparent;
-  box-shadow: none;
-}
 .ds-card .meta {
   display: flex;
   flex-direction: column;
   padding: 12px 16px;
   flex-grow: 1;
 }
 .ds-card .meta .info-wrap {
   flex-grow: 1;
--- a/browser/components/newtab/data/content/activity-stream.bundle.js
+++ b/browser/components/newtab/data/content/activity-stream.bundle.js
@@ -7745,41 +7745,16 @@ class _DSCard extends (external_React_de
   render() {
     if (this.props.placeholder || !this.state.isSeen) {
       return /*#__PURE__*/external_React_default().createElement("div", {
         className: "ds-card placeholder",
         ref: this.setPlaceholderRef
       });
     }
 
-    if (this.props.lastCard) {
-      return /*#__PURE__*/external_React_default().createElement("div", {
-        className: "ds-card last-card-message"
-      }, /*#__PURE__*/external_React_default().createElement("div", {
-        className: "img-wrapper"
-      }, /*#__PURE__*/external_React_default().createElement("picture", {
-        className: "ds-image img loaded"
-      }, /*#__PURE__*/external_React_default().createElement("img", {
-        "data-l10n-id": "newtab-pocket-last-card-image",
-        className: "last-card-message-image",
-        src: "chrome://activity-stream/content/data/content/assets/caught-up-illustration.svg",
-        alt: "You\u2019re all caught up"
-      }))), /*#__PURE__*/external_React_default().createElement("div", {
-        className: "meta"
-      }, /*#__PURE__*/external_React_default().createElement("div", {
-        className: "info-wrap"
-      }, /*#__PURE__*/external_React_default().createElement("header", {
-        className: "title clamp",
-        "data-l10n-id": "newtab-pocket-last-card-title"
-      }), /*#__PURE__*/external_React_default().createElement("p", {
-        className: "ds-last-card-desc",
-        "data-l10n-id": "newtab-pocket-last-card-desc"
-      }))));
-    }
-
     const isButtonCTA = this.props.cta_variant === "button";
     const {
       is_video,
       saveToPocketCard,
       hideDescriptions,
       compactImages,
       imageGradient,
       titleLines = 3,
@@ -7914,19 +7889,16 @@ class _DSCard extends (external_React_de
 
 };
 const DSCard = (0,external_ReactRedux_namespaceObject.connect)(state => ({
   App: state.App
 }))(_DSCard);
 const PlaceholderDSCard = props => /*#__PURE__*/external_React_default().createElement(DSCard, {
   placeholder: true
 });
-const LastCardMessage = props => /*#__PURE__*/external_React_default().createElement(DSCard, {
-  lastCard: true
-});
 ;// CONCATENATED MODULE: ./content-src/components/DiscoveryStreamComponents/DSEmptyState/DSEmptyState.jsx
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
 class DSEmptyState extends (external_React_default()).PureComponent {
   constructor(props) {
@@ -8308,84 +8280,45 @@ function RecentSavesContainer({
     url: `https://getpocket.com/a${queryParams}`
   }, /*#__PURE__*/external_React_default().createElement(FluentOrText, {
     message: "View My List"
   }))), /*#__PURE__*/external_React_default().createElement("div", {
     className: gridClassName
   }, recentSavesCards));
 }
 class _CardGrid extends (external_React_default()).PureComponent {
-  constructor(props) {
-    super(props);
-    this.state = {
-      moreLoaded: false
-    };
-    this.loadMoreClicked = this.loadMoreClicked.bind(this);
-  }
-
-  loadMoreClicked() {
-    this.props.dispatch(actionCreators.UserEvent({
-      event: "CLICK",
-      source: "DS_LOAD_MORE_BUTTON"
-    }));
-    this.setState({
-      moreLoaded: true
-    });
-  }
-
-  get showLoadMore() {
-    const {
-      loadMore,
-      data,
-      loadMoreThreshold
-    } = this.props;
-    return loadMore && data.recommendations.length > loadMoreThreshold && !this.state.moreLoaded;
-  }
-
   renderCards() {
     var _widgets$positions, _widgets$data, _essentialReadsCards, _editorsPicksCards;
 
-    let {
-      items
-    } = this.props;
     const {
       DiscoveryStream
     } = this.props;
     const prefs = this.props.Prefs.values;
     const {
       recentSavesEnabled
     } = DiscoveryStream;
     const showRecentSaves = prefs.showRecentSaves && recentSavesEnabled;
     const {
+      items,
       hybridLayout,
       hideCardBackground,
       fourCardLayout,
       hideDescriptions,
-      lastCardMessageEnabled,
       saveToPocketCard,
-      loadMoreThreshold,
       compactGrid,
       compactImages,
       imageGradient,
       newSponsoredLabel,
       titleLines,
       descLines,
       readTime,
       essentialReadsHeader,
       editorsPicksHeader,
       widgets
     } = this.props;
-    let showLastCardMessage = lastCardMessageEnabled;
-
-    if (this.showLoadMore) {
-      items = loadMoreThreshold; // We don't want to show this until after load more has been clicked.
-
-      showLastCardMessage = false;
-    }
-
     const recs = this.props.data.recommendations.slice(0, items);
     const cards = [];
     let essentialReadsCards = [];
     let editorsPicksCards = [];
 
     for (let index = 0; index < items; index++) {
       const rec = recs[index];
       cards.push(!rec || rec.placeholder ? /*#__PURE__*/external_React_default().createElement(PlaceholderDSCard, {
@@ -8423,23 +8356,16 @@ class _CardGrid extends (external_React_
         newSponsoredLabel: newSponsoredLabel,
         titleLines: titleLines,
         descLines: descLines,
         cta: rec.cta,
         cta_variant: this.props.cta_variant,
         is_video: this.props.enable_video_playheads && rec.is_video,
         is_collection: this.props.is_collection
       }));
-    } // Replace last card with "you are all caught up card"
-
-
-    if (showLastCardMessage) {
-      cards.splice(cards.length - 1, 1, /*#__PURE__*/external_React_default().createElement(LastCardMessage, {
-        key: `dscard-last-${cards.length - 1}`
-      }));
     }
 
     if (widgets !== null && widgets !== void 0 && (_widgets$positions = widgets.positions) !== null && _widgets$positions !== void 0 && _widgets$positions.length && widgets !== null && widgets !== void 0 && (_widgets$data = widgets.data) !== null && _widgets$data !== void 0 && _widgets$data.length) {
       let positionIndex = 0;
       const source = "CARDGRID_WIDGET";
 
       for (const widget of widgets.data) {
         let widgetComponent = null;
@@ -8536,32 +8462,26 @@ class _CardGrid extends (external_React_
     }, /*#__PURE__*/external_React_default().createElement("div", {
       className: "ds-context"
     }))), isEmpty ? /*#__PURE__*/external_React_default().createElement("div", {
       className: "ds-card-grid empty"
     }, /*#__PURE__*/external_React_default().createElement(DSEmptyState, {
       status: data.status,
       dispatch: this.props.dispatch,
       feed: this.props.feed
-    })) : this.renderCards(), this.showLoadMore && /*#__PURE__*/external_React_default().createElement("button", {
-      className: "ASRouterButton primary ds-card-grid-load-more-button",
-      onClick: this.loadMoreClicked,
-      "data-l10n-id": "newtab-pocket-load-more-stories-button"
-    }));
+    })) : this.renderCards());
   }
 
 }
 _CardGrid.defaultProps = {
   border: `border`,
   items: 4,
   // Number of stories to display
   enable_video_playheads: false,
-  lastCardMessageEnabled: false,
-  saveToPocketCard: false,
-  loadMoreThreshold: 12
+  saveToPocketCard: false
 };
 const CardGrid = (0,external_ReactRedux_namespaceObject.connect)(state => ({
   Prefs: state.Prefs,
   DiscoveryStream: state.DiscoveryStream
 }))(_CardGrid);
 ;// CONCATENATED MODULE: ./content-src/components/DiscoveryStreamComponents/DSDismiss/DSDismiss.jsx
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
@@ -13927,18 +13847,16 @@ class _DiscoveryStreamBase extends (exte
           compactImages: component.properties.compactImages,
           imageGradient: component.properties.imageGradient,
           newSponsoredLabel: component.properties.newSponsoredLabel,
           titleLines: component.properties.titleLines,
           descLines: component.properties.descLines,
           essentialReadsHeader: component.properties.essentialReadsHeader,
           editorsPicksHeader: component.properties.editorsPicksHeader,
           readTime: component.properties.readTime,
-          loadMore: component.loadMore,
-          lastCardMessageEnabled: component.lastCardMessageEnabled,
           saveToPocketCard: component.saveToPocketCard,
           cta_variant: component.cta_variant,
           pocket_button_enabled: component.pocketButtonEnabled,
           display_engagement_labels: ENGAGEMENT_LABEL_ENABLED
         });
 
       case "HorizontalRule":
         return /*#__PURE__*/external_React_default().createElement(HorizontalRule, null);
deleted file mode 100644
--- a/browser/components/newtab/data/content/assets/caught-up-illustration.svg
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
-   - License, v. 2.0. If a copy of the MPL was not distributed with this
-   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 124.3 100.9" xml:space="preserve">
-  <path class="st0" d="M119 90.7C119 94 82.8 99 55.6 99S13.1 89 13.1 85.6s18.8-5.6 46-5.6 60 7.2 60 10.7z" fill="#FCB643"></path>
-  <path class="st1" d="m73 14.5-51 11c-.2 0-.3.2-.2.4l13.8 67c0 .2.2.3.3.3l50.3-9.9c.1 0 .3-.2.2-.4l-13-68.1c0-.2-.2-.3-.4-.3z" fill="#fff"></path>
-  <path d="M74.3 14.6a1.3 1.3 0 0 0-1.5-1l-51 11c-.7 0-1.2.8-1 1.5l13.8 67c.1.7.7 1.1 1.3 1.1h.3l50.2-10c.7 0 1.1-.7 1-1.5l-13-68.1zm11.9 68.7L36 93.2h-.1c-.1 0-.3-.1-.3-.3L21.8 26c0-.2 0-.4.2-.4l51-11c.2 0 .3 0 .4.3l13 68.1c0 .2 0 .4-.2.4z"></path>
-  <path class="st1" d="m93.3 19.2-52-2.6c-.2 0-.4.1-.4.3l-4 68.3c0 .2 0 .4.3.4l51 3.5c.2 0 .3-.2.4-.3l5-69.3v-.2l-.3-.1z" fill="#fff"></path>
-  <path d="m93.4 18.2-52.1-2.6c-.8 0-1.3.5-1.4 1.2l-4 68.4c0 .7.5 1.3 1.2 1.4L88 90h.1c.7 0 1.3-.5 1.4-1.2l5-69.3c0-.7-.5-1.4-1.2-1.4zm-5.2 70.9-51-3.5a.3.3 0 0 1-.3-.4l4-68.3c0-.2.2-.3.3-.3l52.1 2.6.3.1v.3l-5 69.2c0 .2-.2.3-.4.3z"></path>
-  <path class="st1" d="M109 26.6 58 15.1c-.1 0-.3.1-.3.3L42 82c0 .2.1.4.3.4L92 94.6c.2 0 .3 0 .4-.3L109.2 27v-.3h-.3z" fill="#fff"></path>
-  <path d="M91.8 95.6h.3c.6 0 1.1-.4 1.3-1l16.8-67.3c.1-.8-.3-1.5-1-1.7L58.3 14.2H58c-.6 0-1.1.4-1.3 1L41.1 81.8c-.2.7.2 1.4 1 1.6l49.7 12.2zm.3-1H92L42.3 82.4a.3.3 0 0 1-.3-.4l15.7-66.6c0-.2.2-.3.3-.3l51 11.5.1.2s.1.1 0 .2L92.5 94.4l-.3.2z"></path>
-  <path class="st2" d="M101.7 31.5 62 22.7c-1-.2-2 .4-2.2 1.4l-3 12c-.2 1 .4 1.9 1.4 2.1L98 47.8c1 .2 2-.4 2.1-1.4l3-12.7c.2-1-.4-2-1.4-2.2zm-9.5 40.9-11.9-2.6a1 1 0 0 0-1.1.7L76 82c-.1.5.2 1 .7 1.1l12.2 3.3c.5.1 1-.2 1.2-.7l2.9-12a1 1 0 0 0-.8-1.2z" fill="#EF4056"></path>
-  <path d="M97.3 52.3c-1.8-.4-3 .6-4 1.4-.8.7-1.3 1.1-2 1-.9-.3-1.2-.8-1.6-1.9-.5-1.1-1-2.5-2.9-3-1.8-.3-3 .6-3.9 1.4-.8.7-1.4 1.1-2.1 1-.8-.2-1.1-.8-1.5-1.8-.5-1.2-1.1-2.6-3-3s-2.9.6-3.8 1.4c-.9.7-1.4 1-2.2 1-.7-.3-1-.9-1.5-1.9-.5-1.1-1-2.5-2.9-3-1.7-.4-3 .6-3.9 1.4-.8.7-1.3 1.1-2.1 1-.8-.2-1-.8-1.5-1.9-.5-1-1-2.5-2.9-3a1 1 0 0 0-1.2.8c-.1.6.2 1.1.8 1.2.7.2 1 .8 1.5 1.8.4 1.2 1 2.6 2.8 3 1.8.4 3-.6 4-1.4.8-.7 1.3-1 2.1-.9s1 .8 1.5 1.8c.5 1.1 1 2.5 2.9 3 1.8.4 3-.6 3.9-1.4.8-.7 1.4-1.1 2.1-1s1 .8 1.5 1.9c.5 1 1.1 2.5 3 3 1.7.3 2.9-.7 3.8-1.4.9-.8 1.4-1.2 2.2-1 .7.2 1 .8 1.5 1.8.5 1.1 1 2.5 2.9 3h.8c1.3 0 2.3-.7 3-1.4 1-.7 1.4-1.1 2.2-1a1 1 0 1 0 .5-1.9zM95 61.7c-1.7-.4-3 .6-3.9 1.4-.8.7-1.3 1.1-2.1 1s-1-.8-1.5-1.9c-.5-1-1.1-2.5-2.9-3-1.8-.3-3 .7-3.9 1.4-.9.8-1.4 1.2-2.2 1-.7-.2-1-.8-1.5-1.8-.4-1.1-1-2.5-2.8-3-1.8-.4-3 .6-4 1.4-.8.7-1.3 1.1-2 1-.9-.3-1.1-.8-1.6-1.9-.5-1.1-1-2.5-2.9-3-1.8-.4-3 .6-3.9 1.4-.8.7-1.3 1.1-2.1 1s-1-.8-1.5-1.8c-.5-1.2-1.1-2.6-2.9-3a1 1 0 1 0-.4 2c.7.1 1 .7 1.5 1.8.4 1 1 2.5 2.8 3 1.8.3 3-.7 4-1.4.8-.8 1.3-1.2 2-1 .9.2 1.1.8 1.6 1.8.5 1.1 1 2.5 2.9 3 1.8.4 3-.6 3.9-1.4.8-.7 1.3-1.1 2.1-1 .8.3 1 .8 1.5 1.9.5 1.1 1.1 2.5 2.9 3 1.8.4 3-.6 3.9-1.4.8-.7 1.4-1.1 2.1-1s1.1.8 1.6 1.8c.4 1.2 1 2.6 2.8 3h.9c1.3 0 2.3-.7 3-1.4.9-.7 1.4-1.1 2.2-1 .5.2 1-.1 1.2-.7s-.2-1-.8-1.2zM76.3 71c-.7-.2-1-.8-1.5-1.8-.4-1.1-1-2.5-2.8-3-1.8-.4-3 .6-4 1.4-.8.7-1.3 1.1-2 1-.9-.2-1.1-.8-1.6-1.9-.5-1.1-1-2.5-2.9-3-1.8-.3-3 .6-3.9 1.4-.8.8-1.3 1.2-2.1 1-.8-.2-1-.8-1.5-1.8-.5-1.2-1.1-2.6-2.9-3a1 1 0 1 0-.4 2c.7.1 1 .7 1.5 1.8.4 1 1 2.5 2.8 3 1.8.3 3-.6 4-1.4.8-.8 1.3-1.2 2-1s1.1.8 1.6 1.8c.5 1.2 1 2.6 2.9 3 1.8.4 3-.6 3.9-1.4.8-.7 1.3-1.1 2.1-1s1 .9 1.5 1.9c.5 1.1 1.1 2.5 2.9 3h.2a1 1 0 0 0 .3-2zm-2.2 9.4c-.7-.2-1-.8-1.5-1.8-.4-1.1-1-2.5-2.8-3-1.8-.4-3 .6-4 1.4-.8.7-1.3 1.1-2 1-.9-.2-1.1-.8-1.6-1.9-.5-1.1-1-2.5-2.9-3-1.8-.3-3 .6-3.9 1.4-.8.8-1.3 1.2-2.1 1-.8-.2-1-.8-1.5-1.8-.5-1.2-1.1-2.6-2.9-3a1 1 0 0 0-1.2.8c-.1.5.2 1 .7 1.2.8.1 1.1.7 1.5 1.8.5 1 1.1 2.5 3 3 1.7.3 2.9-.6 3.8-1.4.9-.8 1.4-1.2 2.2-1s1 .8 1.5 1.8c.5 1.2 1 2.6 2.9 3 1.8.4 3-.6 3.9-1.4.8-.7 1.3-1.1 2.1-1 .8.3 1 .9 1.5 1.9.5 1.1 1.1 2.5 2.9 3h.2a1 1 0 0 0 .2-2z"></path>
-  <path class="st3" fill="#1CB0A8" d="M176.8 13.9h5.8v5.8h-5.8zM1 28.4 3 23l5.4 2-2 5.4zM34.3 4.2l6.7-3 3 6.5-6.6 3.3z"></path>
-  <path class="st2" d="M19.6 8a3 3 0 1 0 0 6.2 3 3 0 0 0 0-6.2zm47.5-4.6a3.3 3.3 0 1 0 0 6.6 3.3 3.3 0 0 0 0-6.6z" fill="#EF4056"></path>
-  <circle class="st2" cx="120.1" cy="31.3" r="2.2" fill="#EF4056"></circle>
-  <path class="st0" fill="#FCB643" d="m14.3 51.3 1.6 3.8 1.7 3.8 2.5-3.4 2.4-3.3-4.1-.5zm98.1-41.8-3.5 1.5 3.1 2.3 3.1 2.3.4-3.9.4-3.8zm-7.5 64.2 4.3 3.2 4.4 3.2.6-5.4.6-5.4-5 2.2z"></path>
-  <path class="st3" d="M46 22.7a2 2 0 0 0-2 1.7l-1 11.7c-.1.4 0 1 .3 1.3.4.4.8.6 1.4.7l6.5.6L54.9 23l-8.9-.3zm-1.3 21.8a2 2 0 0 0-2 1.7l-1 11.7c-.1.5 0 1 .3 1.3.4.4.8.6 1.4.7l2.8.3 3.6-15.5-5-.2zM44.5 67h-1.1a2 2 0 0 0-2 1.7l-1 11.6a1.8 1.8 0 0 0 .7 1.6v-.1L44.5 67z" fill="#1CB0A8"></path>
-  <path d="M37.8 30.6c-1.8.4-2.4 1.8-3 2.9-.4 1-.7 1.6-1.5 1.8s-1.3-.3-2-1c-1-.9-2.1-1.9-4-1.5a1 1 0 0 0 .5 2c.7-.2 1.2.2 2 1 .9.7 1.8 1.5 3.2 1.5h.7c1.8-.4 2.5-1.8 3-3 .5-1 .8-1.6 1.5-1.7h.8l.1-2h-1.3zm-1 12.3c-.4 1-.7 1.6-1.5 1.8-.8.1-1.3-.3-2.1-1-1-.9-2.1-1.9-4-1.5a1 1 0 0 0 .5 2c.8-.2 1.3.2 2.1 1 .8.6 1.7 1.5 3.1 1.5h.8a4 4 0 0 0 2.6-2.3l.2-3.8c-.9.6-1.3 1.5-1.7 2.3z"></path>
-  <path class="st0" d="M32.8 54c-.8.2-1.3 1-1.1 1.7l4.6 23 1.5-26-5 1.3zm6.6 33 1.6-.2-2.8-.2c.3.3.7.5 1.2.5z" fill="#FCB643"></path>
-</svg>
--- a/browser/components/newtab/docs/v2-system-addon/data_events.md
+++ b/browser/components/newtab/docs/v2-system-addon/data_events.md
@@ -677,35 +677,16 @@ This reports the user's interaction with
   // "shim" is a base64 encoded shim attached to spocs, unique to the impression from the Ad server.
   "tiles": [{"id": 10000, "pos": 0, "shim": "enuYa1j73z3RzxgTexHNxYPC/b,9JT6w5KB0CRKYEU+"}],
 
   // A 0-based index to record which tile in the "tiles" list that the user just interacted with.
   "click|block|pocket": 0
 }
 ```
 
-### Load more button ping
-
-```js
-{
-  "event": "CLICK",
-  "source": "DS_LOAD_MORE_BUTTON",
-
-  // Basic metadata
-  "action": "activity_stream_event",
-  "page": ["about:newtab" | "about:home" | "about:welcome" | "unknown"],
-  "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c",
-  "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",
-  "browser_session_id": "e7e52665-7db3-f348-9918-e93160eb2ef3",
-  "addon_version": "20180710100040",
-  "locale": "en-US",
-  "user_prefs": 7
-}
-```
-
 ## Save to Pocket button pings
 
 Right now the save to Pocket button, while technically outside of newtab, has some similarities with the newtab telemetry.
 
 These pings record user interaction with the save to Pocket button.
 
 ### Click/impression ping
 
--- a/browser/components/newtab/lib/DiscoveryStreamFeed.jsm
+++ b/browser/components/newtab/lib/DiscoveryStreamFeed.jsm
@@ -567,18 +567,16 @@ class DiscoveryStreamFeed {
           pocketConfig.widgetPositions?.split(`,`)
         ),
         widgetData: [
           ...(this.locale.startsWith("en-") ? [{ type: "TopicsWidget" }] : []),
         ],
         hybridLayout: pocketConfig.hybridLayout,
         hideCardBackground: pocketConfig.hideCardBackground,
         fourCardLayout: pocketConfig.fourCardLayout,
-        loadMore: pocketConfig.loadMore,
-        lastCardMessageEnabled: pocketConfig.lastCardMessageEnabled,
         pocketButtonEnabled,
         saveToPocketCard: pocketButtonEnabled && pocketConfig.saveToPocketCard,
         newFooterSection: pocketConfig.newFooterSection,
         hideDescriptions: pocketConfig.hideDescriptions,
         compactGrid: pocketConfig.compactGrid,
         compactImages: pocketConfig.compactImages,
         imageGradient: pocketConfig.imageGradient,
         newSponsoredLabel: pocketConfig.newSponsoredLabel,
@@ -1972,18 +1970,16 @@ class DiscoveryStreamFeed {
 
    NOTE: There is some branching logic in the template.
      `items` How many items to include in the primary card grid.
      `spocPositions` Changes the position of spoc cards.
      `sponsoredCollectionsEnabled` Tuns on and off the sponsored collection section.
      `hybridLayout` Changes cards to smaller more compact cards only for specific breakpoints.
      `hideCardBackground` Removes Pocket card background and borders.
      `fourCardLayout` Enable four Pocket cards per row.
-     `loadMore` Hide half the Pocket stories behind a load more button.
-     `lastCardMessageEnabled` Shows a message card at the end of the feed.
      `newFooterSection` Changes the layout of the topics section.
      `pocketButtonEnabled` Removes Pocket context menu items from cards.
      `saveToPocketCard` Cards have a save to Pocket button over their thumbnail on hover.
      `hideDescriptions` Hide or display descriptions for Pocket stories.
      `compactGrid` Reduce the number of pixels between the Pocket cards.
      `compactImages` Reduce the height on Pocket card images.
      `imageGradient` Add a gradient to the bottom of Pocket card images to blend the image in with the card.
      `newSponsoredLabel` Updates the sponsored label position to below the image.
@@ -1996,18 +1992,16 @@ getHardcodedLayout = ({
   items = 21,
   spocPositions = [1, 5, 7, 11, 18, 20],
   widgetPositions = [],
   widgetData = [],
   sponsoredCollectionsEnabled = false,
   hybridLayout = false,
   hideCardBackground = false,
   fourCardLayout = false,
-  loadMore = false,
-  lastCardMessageEnabled = false,
   newFooterSection = false,
   pocketButtonEnabled = false,
   saveToPocketCard = false,
   hideDescriptions = true,
   compactGrid = false,
   compactImages = false,
   imageGradient = false,
   newSponsoredLabel = false,
@@ -2107,18 +2101,16 @@ getHardcodedLayout = ({
             readTime,
           },
           widgets: {
             positions: widgetPositions.map(position => {
               return { index: position };
             }),
             data: widgetData,
           },
-          loadMore,
-          lastCardMessageEnabled,
           pocketButtonEnabled,
           saveToPocketCard,
           cta_variant: "link",
           header: {
             title: "",
           },
           placement: {
             name: "spocs",
--- a/browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/CardGrid.test.jsx
+++ b/browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/CardGrid.test.jsx
@@ -5,17 +5,16 @@ import {
   DSSubHeader,
 } from "content-src/components/DiscoveryStreamComponents/CardGrid/CardGrid";
 import { combineReducers, createStore } from "redux";
 import { INITIAL_STATE, reducers } from "common/Reducers.jsm";
 import { Provider } from "react-redux";
 import {
   DSCard,
   PlaceholderDSCard,
-  LastCardMessage,
 } from "content-src/components/DiscoveryStreamComponents/DSCard/DSCard";
 import { TopicsWidget } from "content-src/components/DiscoveryStreamComponents/TopicsWidget/TopicsWidget";
 import { actionCreators as ac, actionTypes as at } from "common/Actions.jsm";
 import React from "react";
 import { shallow, mount } from "enzyme";
 
 // Wrap this around any component that uses useSelector,
 // or any mount that uses a child that uses redux.
@@ -123,66 +122,16 @@ describe("<CardGrid>", () => {
     wrapper.setProps({
       hideDescriptions: true,
       data: { recommendations: [{}, {}] },
     });
 
     assert.ok(!wrapper.find(".ds-card-grid-include-descriptions").exists());
   });
 
-  it("should show last card and more loaded state", () => {
-    const dispatch = sinon.stub();
-    wrapper.setProps({
-      dispatch,
-      compact: true,
-      loadMore: true,
-      lastCardMessageEnabled: true,
-      loadMoreThreshold: 2,
-      data: {
-        recommendations: [{}, {}, {}],
-      },
-    });
-
-    const loadMoreButton = wrapper.find(".ds-card-grid-load-more-button");
-    assert.ok(loadMoreButton.exists());
-
-    loadMoreButton.simulate("click", { preventDefault: () => {} });
-    assert.calledOnce(dispatch);
-    assert.calledWith(
-      dispatch,
-      ac.UserEvent({
-        event: "CLICK",
-        source: "DS_LOAD_MORE_BUTTON",
-      })
-    );
-
-    const lastCard = wrapper.find(LastCardMessage);
-    assert.ok(lastCard.exists());
-  });
-
-  it("should only show load more with more than threshold number of stories", () => {
-    wrapper.setProps({
-      loadMore: true,
-      loadMoreThreshold: 2,
-      data: {
-        recommendations: [{}, {}, {}],
-      },
-    });
-
-    let loadMoreButton = wrapper.find(".ds-card-grid-load-more-button");
-    assert.ok(loadMoreButton.exists());
-
-    wrapper.setProps({
-      loadMoreThreshold: 3,
-    });
-
-    loadMoreButton = wrapper.find(".ds-card-grid-load-more-button");
-    assert.ok(!loadMoreButton.exists());
-  });
-
   it("should create a widget card", () => {
     wrapper.setProps({
       widgets: {
         positions: [{ index: 1 }],
         data: [{ type: "TopicsWidget" }],
       },
       data: {
         recommendations: [{}, {}, {}],
--- a/browser/components/urlbar/QuickActionsLoaderDefault.jsm
+++ b/browser/components/urlbar/QuickActionsLoaderDefault.jsm
@@ -6,43 +6,44 @@
 
 var EXPORTED_SYMBOLS = ["QuickActionsLoaderDefault"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
-XPCOMUtils.defineLazyModuleGetters(this, {
+const lazy = {};
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
   DevToolsShim: "chrome://devtools-startup/content/DevToolsShim.jsm",
   UrlbarProviderQuickActions:
     "resource:///modules/UrlbarProviderQuickActions.jsm",
 });
 
 const BASE_URL = Services.urlFormatter.formatURLPref("app.support.baseURL");
 
 let openUrlFun = url => () => openUrl(url);
 let openUrl = url => {
-  let window = BrowserWindowTracker.getTopWindow();
+  let window = lazy.BrowserWindowTracker.getTopWindow();
   window.gBrowser.loadOneTab(url, {
     inBackground: false,
     triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
   });
 };
 
 // There are various actions that will either fail or do not
 // make sense to use unless the user is viewing web content,
 // Screenshots for example cannot be taken on about: pages.
 // We may want to show these as disabled buttons, that may
 // aid discovery but may also confuse users.
 let currentPageIsWebContentFilter = () =>
   currentBrowser().currentURI.spec.startsWith("about:");
 let currentBrowser = () =>
-  BrowserWindowTracker.getTopWindow().gBrowser.selectedBrowser;
+  lazy.BrowserWindowTracker.getTopWindow().gBrowser.selectedBrowser;
 
 const DEFAULT_ACTIONS = {
   clear: {
     commands: ["clear"],
     label: "quickactions-clear",
     onPick: openUrlFun(
       `${BASE_URL}delete-browsing-search-download-history-firefox`
     ),
@@ -60,17 +61,17 @@ const DEFAULT_ACTIONS = {
     isActive: currentPageIsWebContentFilter,
     onPick: openInspector,
   },
   print: {
     commands: ["print"],
     label: "quickactions-print",
     isActive: currentPageIsWebContentFilter,
     onPick: () => {
-      BrowserWindowTracker.getTopWindow()
+      lazy.BrowserWindowTracker.getTopWindow()
         .document.getElementById("cmd_print")
         .doCommand();
     },
   },
   refresh: {
     commands: ["reset"],
     label: "quickactions-refresh",
     onPick: openUrlFun(`${BASE_URL}refresh-firefox-reset-add-ons-and-settings`),
@@ -108,18 +109,18 @@ const DEFAULT_ACTIONS = {
     label: "quickactions-viewsource",
     isActive: currentPageIsWebContentFilter,
     onPick: () => openUrl("view-source:" + currentBrowser().currentURI.spec),
   },
 };
 
 function openInspector() {
   // TODO: This is supposed to be called with an element to start inspecting.
-  DevToolsShim.inspectNode(
-    BrowserWindowTracker.getTopWindow().gBrowser.selectedTab
+  lazy.DevToolsShim.inspectNode(
+    lazy.BrowserWindowTracker.getTopWindow().gBrowser.selectedTab
   );
 }
 
 // TODO: We likely want a prompt to confirm with the user that they want to restart
 // the browser.
 function restartBrowser() {
   // Notify all windows that an application quit has been requested.
   let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(
@@ -145,12 +146,12 @@ function restartBrowser() {
 }
 
 /**
  * Loads the default QuickActions.
  */
 class QuickActionsLoaderDefault {
   static load() {
     for (const key in DEFAULT_ACTIONS) {
-      UrlbarProviderQuickActions.addAction(key, DEFAULT_ACTIONS[key]);
+      lazy.UrlbarProviderQuickActions.addAction(key, DEFAULT_ACTIONS[key]);
     }
   }
 }
--- a/browser/components/urlbar/UrlbarController.jsm
+++ b/browser/components/urlbar/UrlbarController.jsm
@@ -8,17 +8,18 @@ var EXPORTED_SYMBOLS = ["UrlbarControlle
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 const { AppConstants } = ChromeUtils.import(
   "resource://gre/modules/AppConstants.jsm"
 );
-XPCOMUtils.defineLazyModuleGetters(this, {
+const lazy = {};
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   BrowserSearchTelemetry: "resource:///modules/BrowserSearchTelemetry.jsm",
   FormHistory: "resource://gre/modules/FormHistory.jsm",
   PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
   UrlbarProvidersManager: "resource:///modules/UrlbarProvidersManager.jsm",
   UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.jsm",
   UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
@@ -82,17 +83,17 @@ class UrlbarController {
     }
     if (!("isPrivate" in options.input)) {
       throw new Error("input.isPrivate must be set.");
     }
 
     this.input = options.input;
     this.browserWindow = options.input.window;
 
-    this.manager = options.manager || UrlbarProvidersManager;
+    this.manager = options.manager || lazy.UrlbarProvidersManager;
 
     this._listeners = new Set();
     this._userSelectionBehavior = "none";
 
     this.engagementEvent = new TelemetryEvent(
       this,
       options.eventTelemetryCategory
     );
@@ -364,17 +365,17 @@ class UrlbarController {
           break;
         }
         if (this.view.isOpen) {
           if (executeAction) {
             this.userSelectionBehavior = "arrow";
             this.view.selectBy(
               event.keyCode == KeyEvent.DOM_VK_PAGE_DOWN ||
                 event.keyCode == KeyEvent.DOM_VK_PAGE_UP
-                ? UrlbarUtils.PAGE_UP_DOWN_DELTA
+                ? lazy.UrlbarUtils.PAGE_UP_DOWN_DELTA
                 : 1,
               {
                 reverse:
                   event.keyCode == KeyEvent.DOM_VK_UP ||
                   event.keyCode == KeyEvent.DOM_VK_PAGE_UP,
               }
             );
           }
@@ -443,52 +444,55 @@ class UrlbarController {
    *  - autofill results
    *  - http/https results
    */
   speculativeConnect(result, context, reason) {
     // Never speculative connect in private contexts.
     if (!this.input || context.isPrivate || !context.results.length) {
       return;
     }
-    let { url } = UrlbarUtils.getUrlFromResult(result);
+    let { url } = lazy.UrlbarUtils.getUrlFromResult(result);
     if (!url) {
       return;
     }
 
     switch (reason) {
       case "resultsadded": {
         // We should connect to an heuristic result, if it exists.
         if (
           (result == context.results[0] && result.heuristic) ||
           result.autofill
         ) {
-          if (result.type == UrlbarUtils.RESULT_TYPE.SEARCH) {
+          if (result.type == lazy.UrlbarUtils.RESULT_TYPE.SEARCH) {
             // Speculative connect only if search suggestions are enabled.
             if (
-              UrlbarPrefs.get("suggest.searches") &&
-              UrlbarPrefs.get("browser.search.suggest.enabled")
+              lazy.UrlbarPrefs.get("suggest.searches") &&
+              lazy.UrlbarPrefs.get("browser.search.suggest.enabled")
             ) {
               let engine = Services.search.getEngineByName(
                 result.payload.engine
               );
-              UrlbarUtils.setupSpeculativeConnection(
+              lazy.UrlbarUtils.setupSpeculativeConnection(
                 engine,
                 this.browserWindow
               );
             }
           } else if (result.autofill) {
-            UrlbarUtils.setupSpeculativeConnection(url, this.browserWindow);
+            lazy.UrlbarUtils.setupSpeculativeConnection(
+              url,
+              this.browserWindow
+            );
           }
         }
         return;
       }
       case "mousedown": {
         // On mousedown, connect only to http/https urls.
         if (url.startsWith("http")) {
-          UrlbarUtils.setupSpeculativeConnection(url, this.browserWindow);
+          lazy.UrlbarUtils.setupSpeculativeConnection(url, this.browserWindow);
         }
         return;
       }
       default: {
         throw new Error("Invalid speculative connection reason");
       }
     }
   }
@@ -521,17 +525,17 @@ class UrlbarController {
     let resultIndex = result ? result.rowIndex : -1;
     let selectedResult = -1;
     if (resultIndex >= 0) {
       // Except for the history popup, the urlbar always has a selection.  The
       // first result at index 0 is the "heuristic" result that indicates what
       // will happen when you press the Enter key.  Treat it as no selection.
       selectedResult = resultIndex > 0 || !result.heuristic ? resultIndex : -1;
     }
-    BrowserSearchTelemetry.recordSearchSuggestionSelectionMethod(
+    lazy.BrowserSearchTelemetry.recordSearchSuggestionSelectionMethod(
       event,
       "urlbar",
       selectedResult,
       this._userSelectionBehavior
     );
 
     if (!result) {
       return;
@@ -548,17 +552,17 @@ class UrlbarController {
     //
     // The "topsite" type overrides the other ones, because it starts from a
     // unique user interaction, that we want to count apart. We do this here
     // rather than in telemetryTypeFromResult because other consumers, like
     // events telemetry, are reporting this information separately.
     let telemetryType =
       result.providerName == "UrlbarProviderTopSites"
         ? "topsite"
-        : UrlbarUtils.telemetryTypeFromResult(result);
+        : lazy.UrlbarUtils.telemetryTypeFromResult(result);
     Services.telemetry.keyedScalarAdd(
       `urlbar.picked.${telemetryType}`,
       resultIndex,
       1
     );
     if (this.input.searchMode && !this.input.searchMode.isPreview) {
       Services.telemetry.keyedScalarAdd(
         `urlbar.picked.searchmode.${this.input.searchMode.entry}`,
@@ -603,31 +607,31 @@ class UrlbarController {
       result = this.input.view.selectedResult;
     }
 
     if (!result || result.heuristic) {
       return false;
     }
 
     // First call `provider.blockResult()`.
-    let provider = UrlbarProvidersManager.getProvider(result.providerName);
+    let provider = lazy.UrlbarProvidersManager.getProvider(result.providerName);
     if (!provider) {
       Cu.reportError(`Provider not found: ${result.providerName}`);
     }
     let blockedByProvider = provider?.tryMethod(
       "blockResult",
       queryContext,
       result
     );
 
     // If the provider didn't block the result, then continue only if the result
     // is from history.
     if (
       !blockedByProvider &&
-      result.source != UrlbarUtils.RESULT_SOURCE.HISTORY
+      result.source != lazy.UrlbarUtils.RESULT_SOURCE.HISTORY
     ) {
       return false;
     }
 
     let index = queryContext.results.indexOf(result);
     if (index < 0) {
       Cu.reportError("Failed to find the selected result in the results");
       return false;
@@ -636,41 +640,41 @@ class UrlbarController {
     queryContext.results.splice(index, 1);
     this.notify(NOTIFICATIONS.QUERY_RESULT_REMOVED, index);
 
     if (blockedByProvider) {
       return true;
     }
 
     // Form history or url restyled as search.
-    if (result.type == UrlbarUtils.RESULT_TYPE.SEARCH) {
+    if (result.type == lazy.UrlbarUtils.RESULT_TYPE.SEARCH) {
       if (!queryContext.formHistoryName) {
         return false;
       }
       // Generate the search url to remove it from browsing history.
-      let { url } = UrlbarUtils.getUrlFromResult(result);
-      PlacesUtils.history.remove(url).catch(Cu.reportError);
+      let { url } = lazy.UrlbarUtils.getUrlFromResult(result);
+      lazy.PlacesUtils.history.remove(url).catch(Cu.reportError);
       // Now remove form history.
-      FormHistory.update(
+      lazy.FormHistory.update(
         {
           op: "remove",
           fieldname: queryContext.formHistoryName,
           value: result.payload.suggestion,
         },
         {
           handleError(error) {
             Cu.reportError(`Removing form history failed: ${error}`);
           },
         }
       );
       return true;
     }
 
     // Remove browsing history entries from Places.
-    PlacesUtils.history.remove(result.payload.url).catch(Cu.reportError);
+    lazy.PlacesUtils.history.remove(result.payload.url).catch(Cu.reportError);
     return true;
   }
 
   /**
    * Notifies listeners of results.
    *
    * @param {string} name Name of the notification.
    * @param {object} params Parameters to pass with the notification.
@@ -756,17 +760,19 @@ class TelemetryEvent {
       Cu.reportError("Can't start recording from event type: " + event.type);
       return;
     }
 
     let interactionType = "topsites";
     if (event.interactionType) {
       interactionType = event.interactionType;
     } else if (event.type == "input") {
-      interactionType = UrlbarUtils.isPasteEvent(event) ? "pasted" : "typed";
+      interactionType = lazy.UrlbarUtils.isPasteEvent(event)
+        ? "pasted"
+        : "typed";
     } else if (event.type == "drop") {
       interactionType = "dropped";
     } else if (searchString) {
       interactionType = "typed";
     }
 
     this._startEventInfo = {
       timeStamp: event.timeStamp || Cu.now(),
@@ -859,31 +865,31 @@ class TelemetryEvent {
     } else {
       action = MouseEvent.isInstance(event) ? "click" : "enter";
     }
     let method = action == "blur" ? "abandonment" : "engagement";
     let value = this._startEventInfo.interactionType;
 
     // Rather than listening to the pref, just update status when we record an
     // event, if the pref changed from the last time.
-    let recordingEnabled = UrlbarPrefs.get("eventTelemetry.enabled");
+    let recordingEnabled = lazy.UrlbarPrefs.get("eventTelemetry.enabled");
     if (this._eventRecordingEnabled != recordingEnabled) {
       this._eventRecordingEnabled = recordingEnabled;
       Services.telemetry.setEventRecordingEnabled("urlbar", recordingEnabled);
     }
 
     // numWords is not a perfect measurement, since it will return an incorrect
     // value for languages that do not use spaces or URLs containing spaces in
     // its query parameters, for example.
     let extra = {
       elapsed: elapsed.toString(),
       numChars: details.searchString.length.toString(),
       numWords: details.searchString
         .trim()
-        .split(UrlbarTokenizer.REGEXP_SPACES)
+        .split(lazy.UrlbarTokenizer.REGEXP_SPACES)
         .filter(t => t)
         .length.toString(),
     };
     if (method == "engagement") {
       extra.selIndex = details.selIndex.toString();
       extra.selType = details.selType;
       extra.provider = details.provider || "";
     }
@@ -904,17 +910,19 @@ class TelemetryEvent {
         : TELEMETRY_SCALAR_ABANDONMENT,
       1
     );
 
     let { queryContext } = this._controller._lastQueryContextWrapper || {};
 
     if (method === "engagement" && queryContext.results?.[0].autofill) {
       // Record autofill impressions upon engagement.
-      const type = UrlbarUtils.telemetryTypeFromResult(queryContext.results[0]);
+      const type = lazy.UrlbarUtils.telemetryTypeFromResult(
+        queryContext.results[0]
+      );
       Services.telemetry.scalarAdd(`urlbar.impression.${type}`, 1);
     }
 
     this._controller.manager.notifyEngagementChange(
       this._isPrivate,
       method,
       queryContext,
       details
@@ -941,20 +949,20 @@ class TelemetryEvent {
   typeFromElement(element) {
     if (!element) {
       return "none";
     }
     let row = element.closest(".urlbarView-row");
     if (row.result && row.result.providerName != "UrlbarProviderTopSites") {
       // Element handlers go here.
       if (element.classList.contains("urlbarView-button-help")) {
-        return row.result.type == UrlbarUtils.RESULT_TYPE.TIP
+        return row.result.type == lazy.UrlbarUtils.RESULT_TYPE.TIP
           ? "tiphelp"
           : "help";
       }
       if (element.classList.contains("urlbarView-button-block")) {
         return "block";
       }
     }
     // Now handle the result.
-    return UrlbarUtils.telemetryTypeFromResult(row.result);
+    return lazy.UrlbarUtils.telemetryTypeFromResult(row.result);
   }
 }
--- a/browser/components/urlbar/UrlbarEventBufferer.jsm
+++ b/browser/components/urlbar/UrlbarEventBufferer.jsm
@@ -8,24 +8,25 @@ var EXPORTED_SYMBOLS = ["UrlbarEventBuff
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 const { AppConstants } = ChromeUtils.import(
   "resource://gre/modules/AppConstants.jsm"
 );
-XPCOMUtils.defineLazyModuleGetters(this, {
+const lazy = {};
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   clearTimeout: "resource://gre/modules/Timer.jsm",
   setTimeout: "resource://gre/modules/Timer.jsm",
   UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
-XPCOMUtils.defineLazyGetter(this, "logger", () =>
-  UrlbarUtils.getLogger({ prefix: "EventBufferer" })
+XPCOMUtils.defineLazyGetter(lazy, "logger", () =>
+  lazy.UrlbarUtils.getLogger({ prefix: "EventBufferer" })
 );
 
 // Maximum time events can be deferred for. In automation providers can be quite
 // slow, thus we need a longer timeout to avoid intermittent failures.
 const DEFERRING_TIMEOUT_MS = Cu.isInAutomation ? 1000 : 300;
 
 // Array of keyCodes to defer.
 const DEFERRED_KEY_CODES = new Set([
@@ -95,17 +96,17 @@ class UrlbarEventBufferer {
   // UrlbarController listener methods.
   onQueryStarted(queryContext) {
     this._lastQuery = {
       startDate: Cu.now(),
       status: QUERY_STATUS.RUNNING,
       context: queryContext,
     };
     if (this._deferringTimeout) {
-      clearTimeout(this._deferringTimeout);
+      lazy.clearTimeout(this._deferringTimeout);
       this._deferringTimeout = null;
     }
   }
 
   onQueryCancelled(queryContext) {
     this._lastQuery.status = QUERY_STATUS.COMPLETE;
   }
 
@@ -121,22 +122,22 @@ class UrlbarEventBufferer {
   }
 
   /**
    * Handles DOM events.
    * @param {Event} event DOM event from the input.
    */
   handleEvent(event) {
     if (event.type == "blur") {
-      logger.debug("Clearing queue on blur");
+      lazy.logger.debug("Clearing queue on blur");
       // The input field was blurred, pending events don't matter anymore.
       // Clear the timeout and the queue.
       this._eventsQueue.length = 0;
       if (this._deferringTimeout) {
-        clearTimeout(this._deferringTimeout);
+        lazy.clearTimeout(this._deferringTimeout);
         this._deferringTimeout = null;
       }
     }
   }
 
   /**
    * Receives DOM events, eventually queues them up, and calls back when it's
    * the right time to handle the event.
@@ -167,28 +168,28 @@ class UrlbarEventBufferer {
     // following is true for the quantum bar as well: somehow event.defaultPrevented
     // ends up true for deferred events.  Autocomplete ignores defaultPrevented
     // events, which means it would ignore replayed deferred events if we didn't
     // tell it to bypass defaultPrevented through urlbarDeferred.
     // Check we don't try to defer events more than once.
     if (event.urlbarDeferred) {
       throw new Error(`Event ${event.type}:${event.keyCode} already deferred!`);
     }
-    logger.debug(`Deferring ${event.type}:${event.keyCode} event`);
+    lazy.logger.debug(`Deferring ${event.type}:${event.keyCode} event`);
     // Mark the event as deferred.
     event.urlbarDeferred = true;
     // Also store the current search string, as an added safety check. If the
     // string will differ later, the event is stale and should be dropped.
     event.searchString = this._lastQuery.context.searchString;
     this._eventsQueue.push({ event, callback });
 
     if (!this._deferringTimeout) {
       let elapsed = Cu.now() - this._lastQuery.startDate;
       let remaining = DEFERRING_TIMEOUT_MS - elapsed;
-      this._deferringTimeout = setTimeout(() => {
+      this._deferringTimeout = lazy.setTimeout(() => {
         this.replayDeferredEvents(false);
         this._deferringTimeout = null;
       }, Math.max(0, remaining));
     }
   }
 
   /**
    * Replays deferred key events.
--- a/browser/components/urlbar/UrlbarInput.jsm
+++ b/browser/components/urlbar/UrlbarInput.jsm
@@ -9,17 +9,19 @@ var EXPORTED_SYMBOLS = ["UrlbarInput"];
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 const { AppConstants } = ChromeUtils.import(
   "resource://gre/modules/AppConstants.jsm"
 );
 
-XPCOMUtils.defineLazyModuleGetters(this, {
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   BrowserSearchTelemetry: "resource:///modules/BrowserSearchTelemetry.jsm",
   BrowserUIUtils: "resource:///modules/BrowserUIUtils.jsm",
   CONTEXTUAL_SERVICES_PING_TYPES:
     "resource:///modules/PartnerLinkAttribution.jsm",
   ExtensionSearchHandler: "resource://gre/modules/ExtensionSearchHandler.jsm",
   ObjectUtils: "resource://gre/modules/ObjectUtils.jsm",
   PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
   PromiseUtils: "resource://gre/modules/PromiseUtils.jsm",
@@ -35,17 +37,17 @@ XPCOMUtils.defineLazyModuleGetters(this,
   UrlbarSearchUtils: "resource:///modules/UrlbarSearchUtils.jsm",
   UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.jsm",
   UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
   UrlbarValueFormatter: "resource:///modules/UrlbarValueFormatter.jsm",
   UrlbarView: "resource:///modules/UrlbarView.jsm",
 });
 
 XPCOMUtils.defineLazyServiceGetter(
-  this,
+  lazy,
   "ClipboardHelper",
   "@mozilla.org/widget/clipboardhelper;1",
   "nsIClipboardHelper"
 );
 
 const DEFAULT_FORM_HISTORY_NAME = "searchbar-history";
 const SEARCH_BUTTON_ID = "urlbar-search-button";
 
@@ -65,17 +67,17 @@ class UrlbarInput {
    *   The initial options for UrlbarInput.
    * @param {object} options.textbox
    *   The container element.
    */
   constructor(options = {}) {
     this.textbox = options.textbox;
 
     this.window = this.textbox.ownerGlobal;
-    this.isPrivate = PrivateBrowsingUtils.isWindowPrivate(this.window);
+    this.isPrivate = lazy.PrivateBrowsingUtils.isWindowPrivate(this.window);
     this.document = this.window.document;
 
     // Create the panel to contain results.
     this.textbox.appendChild(
       this.window.MozXULElement.parseXULToFragment(`
         <vbox class="urlbarView"
               role="group"
               tooltip="aHTMLTooltip">
@@ -89,26 +91,26 @@ class UrlbarInput {
           <hbox class="search-one-offs"
                 includecurrentengine="true"
                 disabletab="true"/>
         </vbox>
       `)
     );
     this.panel = this.textbox.querySelector(".urlbarView");
 
-    this.searchButton = UrlbarPrefs.get("experimental.searchButton");
+    this.searchButton = lazy.UrlbarPrefs.get("experimental.searchButton");
     if (this.searchButton) {
       this.textbox.classList.add("searchButton");
     }
 
-    this.controller = new UrlbarController({
+    this.controller = new lazy.UrlbarController({
       input: this,
       eventTelemetryCategory: options.eventTelemetryCategory,
     });
-    this.view = new UrlbarView(this);
+    this.view = new lazy.UrlbarView(this);
     this.valueIsTyped = false;
     this.formHistoryName = DEFAULT_FORM_HISTORY_NAME;
     this.lastQueryContextPromise = Promise.resolve();
     this._actionOverrideKeyCount = 0;
     this._autofillPlaceholder = null;
     this._lastSearchString = "";
     this._lastValidURLStr = "";
     this._valueOnLastSearch = "";
@@ -194,17 +196,17 @@ class UrlbarInput {
     );
     this._searchModeIndicatorClose = this._searchModeIndicator.querySelector(
       "#urlbar-search-mode-indicator-close"
     );
     this._searchModeLabel = this.querySelector("#urlbar-label-search-mode");
     this._toolbar = this.textbox.closest("toolbar");
 
     XPCOMUtils.defineLazyGetter(this, "valueFormatter", () => {
-      return new UrlbarValueFormatter(this);
+      return new lazy.UrlbarValueFormatter(this);
     });
 
     XPCOMUtils.defineLazyGetter(this, "addSearchEngineHelper", () => {
       return new AddSearchEngineHelper(this);
     });
 
     // If the toolbar is not visible in this window or the urlbar is readonly,
     // we'll stop here, so that most properties of the input object are valid,
@@ -212,17 +214,17 @@ class UrlbarInput {
     if (!this.window.toolbar.visible || this.readOnly) {
       return;
     }
 
     // The event bufferer can be used to defer events that may affect users
     // muscle memory; for example quickly pressing DOWN+ENTER should end up
     // on a predictable result, regardless of the search status. The event
     // bufferer will invoke the handling code at the right time.
-    this.eventBufferer = new UrlbarEventBufferer(this);
+    this.eventBufferer = new lazy.UrlbarEventBufferer(this);
 
     this._inputFieldEvents = [
       "compositionstart",
       "compositionend",
       "contextmenu",
       "dragover",
       "dragstart",
       "drop",
@@ -263,17 +265,17 @@ class UrlbarInput {
     this.window.addEventListener("aftercustomization", this);
 
     this.updateLayoutBreakout();
 
     this._initCopyCutController();
     this._initPasteAndGo();
 
     // Tracks IME composition.
-    this._compositionState = UrlbarUtils.COMPOSITION.NONE;
+    this._compositionState = lazy.UrlbarUtils.COMPOSITION.NONE;
     this._compositionClosedPopup = false;
 
     this.editor.newlineHandling =
       Ci.nsIEditor.eNewlinesStripSurroundingWhitespace;
   }
 
   /**
    * Applies styling to the text in the urlbar input, depending on the text.
@@ -341,17 +343,17 @@ class UrlbarInput {
       try {
         uri = Services.io.createExposableURI(uri);
       } catch (e) {}
 
       // Replace initial page URIs with an empty string
       // only if there's no opener (bug 370555).
       if (
         this.window.isInitialPage(uri) &&
-        BrowserUIUtils.checkEmptyPageOrigin(
+        lazy.BrowserUIUtils.checkEmptyPageOrigin(
           this.window.gBrowser.selectedBrowser,
           uri
         )
       ) {
         value = "";
       } else {
         // We should deal with losslessDecodeURI throwing for exotic URIs
         try {
@@ -364,17 +366,19 @@ class UrlbarInput {
       // invalid, because we don't have a valid security state to show via site
       // identity yet. See Bug 1746383.
       valid =
         !dueToSessionRestore &&
         (!this.window.isBlankPageURL(uri.spec) ||
           uri.schemeIs("moz-extension"));
     } else if (
       this.window.isInitialPage(value) &&
-      BrowserUIUtils.checkEmptyPageOrigin(this.window.gBrowser.selectedBrowser)
+      lazy.BrowserUIUtils.checkEmptyPageOrigin(
+        this.window.gBrowser.selectedBrowser
+      )
     ) {
       value = "";
       valid = true;
     }
 
     const previousUntrimmedValue = this.untrimmedValue;
     const previousSelectionStart = this.selectionStart;
     const previousSelectionEnd = this.selectionEnd;
@@ -438,17 +442,17 @@ class UrlbarInput {
    * @param {nsIURI} uri
    *   The URI to be converted
    * @returns {nsIURI}
    *   The converted, exposable URI
    */
   makeURIReadable(uri) {
     // Avoid copying 'about:reader?url=', and always provide the original URI:
     // Reader mode ensures we call createExposableURI itself.
-    let readerStrippedURI = ReaderMode.getOriginalUrlObjectForDisplay(
+    let readerStrippedURI = lazy.ReaderMode.getOriginalUrlObjectForDisplay(
       uri.displaySpec
     );
     if (readerStrippedURI) {
       return readerStrippedURI;
     }
 
     try {
       return Services.io.createExposableURI(uri);
@@ -532,32 +536,32 @@ class UrlbarInput {
     // We can't trust element nor _resultForCurrentValue targets in that case,
     // so we'always generate a new heuristic to load.
     let isComposing = this.editor.composing;
 
     // Use the selected element if we have one; this is usually the case
     // when the view is open.
     let selectedPrivateResult =
       result &&
-      result.type == UrlbarUtils.RESULT_TYPE.SEARCH &&
+      result.type == lazy.UrlbarUtils.RESULT_TYPE.SEARCH &&
       result.payload.inPrivateWindow;
     let selectedPrivateEngineResult =
       selectedPrivateResult && result.payload.isPrivateEngine;
     if (
       !isComposing &&
       element &&
       (!oneOffParams?.engine || selectedPrivateEngineResult)
     ) {
       this.pickElement(element, event);
       return;
     }
 
     // Use the hidden heuristic if it exists and there's no selection.
     if (
-      UrlbarPrefs.get("experimental.hideHeuristic") &&
+      lazy.UrlbarPrefs.get("experimental.hideHeuristic") &&
       !element &&
       !isComposing &&
       !oneOffParams?.engine &&
       this._resultForCurrentValue?.heuristic
     ) {
       this.pickResult(this._resultForCurrentValue, event);
       return;
     }
@@ -579,23 +583,23 @@ class UrlbarInput {
       selType = "oneoff";
       typedValue = this._lastSearchString;
       // If there's a selected one-off button then load a search using
       // the button's engine.
       result = this._resultForCurrentValue;
       let searchString =
         (result && (result.payload.suggestion || result.payload.query)) ||
         this._lastSearchString;
-      [url, openParams.postData] = UrlbarUtils.getSearchQueryUrl(
+      [url, openParams.postData] = lazy.UrlbarUtils.getSearchQueryUrl(
         oneOffParams.engine,
         searchString
       );
       this._recordSearch(oneOffParams.engine, event, { url });
 
-      UrlbarUtils.addToFormHistory(
+      lazy.UrlbarUtils.addToFormHistory(
         this,
         searchString,
         oneOffParams.engine.name
       ).catch(Cu.reportError);
     } else {
       // Use the current value if we don't have a UrlbarResult e.g. because the
       // view is closed.
       url = this.untrimmedValue;
@@ -659,17 +663,17 @@ class UrlbarInput {
     // Otherwise, we must fetch the heuristic result for the current value.
     // TODO (Bug 1604927): If the urlbar results are restricted to a specific
     // engine, here we must search with that specific engine; indeed the
     // docshell wouldn't know about our engine restriction.
     // Also remember to invoke this._recordSearch, after replacing url with
     // the appropriate engine submission url.
     let browser = this.window.gBrowser.selectedBrowser;
     let lastLocationChange = browser.lastLocationChange;
-    UrlbarUtils.getHeuristicResultFor(url)
+    lazy.UrlbarUtils.getHeuristicResultFor(url)
       .then(newResult => {
         // Because this happens asynchronously, we must verify that the browser
         // location did not change in the meanwhile.
         if (
           where != "current" ||
           browser.lastLocationChange == lastLocationChange
         ) {
           this.pickResult(newResult, event, null, browser);
@@ -724,17 +728,17 @@ class UrlbarInput {
    *   Optional. If included and the right prefs are set, we will enter search
    *   mode when handing `searchString` from the fake input to the Urlbar.
    * @param {string} newtabSessionId
    *   Optional. The id of the newtab session that handed off this search.
    *
    */
   handoff(searchString, searchEngine, newtabSessionId) {
     this._handoffSession = newtabSessionId;
-    if (UrlbarPrefs.get("shouldHandOffToSearchMode") && searchEngine) {
+    if (lazy.UrlbarPrefs.get("shouldHandOffToSearchMode") && searchEngine) {
       this.search(searchString, {
         searchEngine,
         searchModeEntry: "handoff",
       });
     } else {
       this.search(searchString);
     }
   }
@@ -797,17 +801,17 @@ class UrlbarInput {
     let isCanonized = this.setValueFromResult({ result, event, urlOverride });
     let where = this._whereToOpen(event);
     let openParams = {
       allowInheritPrincipal: false,
     };
 
     if (
       urlOverride &&
-      result.type != UrlbarUtils.RESULT_TYPE.TIP &&
+      result.type != lazy.UrlbarUtils.RESULT_TYPE.TIP &&
       where == "current"
     ) {
       // Open non-tip help links in a new tab unless the user held a modifier.
       // TODO (bug 1696232): Do this for tip help links, too.
       where = "tab";
     }
 
     let selIndex = result.rowIndex;
@@ -825,21 +829,21 @@ class UrlbarInput {
         provider: result.providerName,
       });
       this._loadURL(this.value, event, where, openParams, browser);
       return;
     }
 
     let { url, postData } = urlOverride
       ? { url: urlOverride, postData: null }
-      : UrlbarUtils.getUrlFromResult(result);
+      : lazy.UrlbarUtils.getUrlFromResult(result);
     openParams.postData = postData;
 
     switch (result.type) {
-      case UrlbarUtils.RESULT_TYPE.URL: {
+      case lazy.UrlbarUtils.RESULT_TYPE.URL: {
         // Bug 1578856: both the provider and the docshell run heuristics to
         // decide how to handle a non-url string, either fixing it to a url, or
         // searching for it.
         // Some preferences can control the docshell behavior, for example
         // if dns_first_for_single_words is true, the docshell looks up the word
         // against the dns server, and either loads it as an url or searches for
         // it, depending on the lookup result. The provider instead will always
         // return a fixed url in this case, because URIFixup is synchronous and
@@ -850,39 +854,39 @@ class UrlbarInput {
         // with the input value, and let it pass through to _loadURL(), and
         // finally to the docshell.
         // This also means that in some cases the heuristic result will show a
         // Visit entry, but the docshell will instead execute a search. It's a
         // rare case anyway, most likely to happen for enterprises customizing
         // the urifixup prefs.
         if (
           result.heuristic &&
-          UrlbarPrefs.get("browser.fixup.dns_first_for_single_words") &&
-          UrlbarUtils.looksLikeSingleWordHost(originalUntrimmedValue)
+          lazy.UrlbarPrefs.get("browser.fixup.dns_first_for_single_words") &&
+          lazy.UrlbarUtils.looksLikeSingleWordHost(originalUntrimmedValue)
         ) {
           url = originalUntrimmedValue;
         }
         break;
       }
-      case UrlbarUtils.RESULT_TYPE.KEYWORD: {
+      case lazy.UrlbarUtils.RESULT_TYPE.KEYWORD: {
         // If this result comes from a bookmark keyword, let it inherit the
         // current document's principal, otherwise bookmarklets would break.
         openParams.allowInheritPrincipal = true;
         break;
       }
-      case UrlbarUtils.RESULT_TYPE.TAB_SWITCH: {
+      case lazy.UrlbarUtils.RESULT_TYPE.TAB_SWITCH: {
         if (this.hasAttribute("actionoverride")) {
           where = "current";
           break;
         }
 
         this.handleRevert();
         let prevTab = this.window.gBrowser.selectedTab;
         let loadOpts = {
-          adoptIntoActiveWindow: UrlbarPrefs.get(
+          adoptIntoActiveWindow: lazy.UrlbarPrefs.get(
             "switchTabs.adoptIntoActiveWindow"
           ),
         };
 
         // We cache the search string because switching tab may clear it.
         let searchString = this._lastSearchString;
         this.controller.engagementEvent.record(event, {
           searchString,
@@ -898,43 +902,43 @@ class UrlbarInput {
         );
         if (switched && prevTab.isEmpty) {
           this.window.gBrowser.removeTab(prevTab);
         }
 
         if (switched && !this.isPrivate && !result.heuristic) {
           // We don't await for this, because a rejection should not interrupt
           // the load. Just reportError it.
-          UrlbarUtils.addToInputHistory(url, searchString).catch(
+          lazy.UrlbarUtils.addToInputHistory(url, searchString).catch(
             Cu.reportError
           );
         }
 
         return;
       }
-      case UrlbarUtils.RESULT_TYPE.SEARCH: {
+      case lazy.UrlbarUtils.RESULT_TYPE.SEARCH: {
         if (result.payload.providesSearchMode) {
           let searchModeParams = this._searchModeForResult(result);
           if (searchModeParams) {
             this.searchMode = searchModeParams;
             this.search("");
           }
           return;
         }
 
         if (
           !this.searchMode &&
           result.heuristic &&
           // If we asked the DNS earlier, avoid the post-facto check.
-          !UrlbarPrefs.get("browser.fixup.dns_first_for_single_words") &&
+          !lazy.UrlbarPrefs.get("browser.fixup.dns_first_for_single_words") &&
           // TODO (bug 1642623): for now there is no smart heuristic to skip the
           // DNS lookup, so any value above 0 will run it.
-          UrlbarPrefs.get("dnsResolveSingleWordsAfterSearch") > 0 &&
+          lazy.UrlbarPrefs.get("dnsResolveSingleWordsAfterSearch") > 0 &&
           this.window.gKeywordURIFixup &&
-          UrlbarUtils.looksLikeSingleWordHost(originalUntrimmedValue)
+          lazy.UrlbarUtils.looksLikeSingleWordHost(originalUntrimmedValue)
         ) {
           // When fixing a single word to a search, the docShell would also
           // query the DNS and if resolved ask the user whether they would
           // rather visit that as a host. On a positive answer, it adds the host
           // to the list that we use to make decisions.
           // Because we are directly asking for a search here, bypassing the
           // docShell, we need to do the same ourselves.
           // See also URIFixupChild.jsm and keyword-uri-fixup.
@@ -949,33 +953,34 @@ class UrlbarInput {
 
         if (result.payload.inPrivateWindow) {
           where = "window";
           openParams.private = true;
         }
 
         const actionDetails = {
           isSuggestion: !!result.payload.suggestion,
-          isFormHistory: result.source == UrlbarUtils.RESULT_SOURCE.HISTORY,
+          isFormHistory:
+            result.source == lazy.UrlbarUtils.RESULT_SOURCE.HISTORY,
           alias: result.payload.keyword,
           url,
         };
         const engine = Services.search.getEngineByName(result.payload.engine);
         this._recordSearch(engine, event, actionDetails);
 
         if (!result.payload.inPrivateWindow) {
-          UrlbarUtils.addToFormHistory(
+          lazy.UrlbarUtils.addToFormHistory(
             this,
             result.payload.suggestion || result.payload.query,
             engine.name
           ).catch(Cu.reportError);
         }
         break;
       }
-      case UrlbarUtils.RESULT_TYPE.TIP: {
+      case lazy.UrlbarUtils.RESULT_TYPE.TIP: {
         let scalarName;
         if (element.classList.contains("urlbarView-button-help")) {
           url = result.payload.helpUrl;
           if (!url) {
             Cu.reportError("helpUrl not specified");
             return;
           }
           scalarName = `${result.payload.type}-help`;
@@ -986,37 +991,39 @@ class UrlbarInput {
         if (!url) {
           this.handleRevert();
           this.controller.engagementEvent.record(event, {
             searchString: this._lastSearchString,
             selIndex,
             selType: "tip",
             provider: result.providerName,
           });
-          let provider = UrlbarProvidersManager.getProvider(
+          let provider = lazy.UrlbarProvidersManager.getProvider(
             result.providerName
           );
           if (!provider) {
             Cu.reportError(`Provider not found: ${result.providerName}`);
             return;
           }
           provider.tryMethod("pickResult", result, element);
           return;
         }
         break;
       }
-      case UrlbarUtils.RESULT_TYPE.DYNAMIC: {
+      case lazy.UrlbarUtils.RESULT_TYPE.DYNAMIC: {
         url = result.payload.url;
         // Do not revert the Urlbar if we're going to navigate. We want the URL
         // populated so we can navigate to it.
         if (!url || !result.payload.shouldNavigate) {
           this.handleRevert();
         }
 
-        let provider = UrlbarProvidersManager.getProvider(result.providerName);
+        let provider = lazy.UrlbarProvidersManager.getProvider(
+          result.providerName
+        );
         if (!provider) {
           Cu.reportError(`Provider not found: ${result.providerName}`);
           return;
         }
         provider.tryMethod("pickResult", result, element);
 
         // If we won't be navigating, this is the end of the engagement.
         if (!url || !result.payload.shouldNavigate) {
@@ -1025,34 +1032,34 @@ class UrlbarInput {
             searchString: this._lastSearchString,
             selType: this.controller.engagementEvent.typeFromElement(element),
             provider: result.providerName,
           });
           return;
         }
         break;
       }
-      case UrlbarUtils.RESULT_TYPE.OMNIBOX: {
+      case lazy.UrlbarUtils.RESULT_TYPE.OMNIBOX: {
         this.controller.engagementEvent.record(event, {
           searchString: this._lastSearchString,
           selIndex,
           selType: "extension",
           provider: result.providerName,
         });
 
         // The urlbar needs to revert to the loaded url when a command is
         // handled by the extension.
         this.handleRevert();
         // We don't directly handle a load when an Omnibox API result is picked,
         // instead we forward the request to the WebExtension itself, because
         // the value may not even be a url.
         // We pass the keyword and content, that actually is the retrieved value
         // prefixed by the keyword. ExtensionSearchHandler uses this keyword
         // redundancy as a sanity check.
-        ExtensionSearchHandler.handleInputEntered(
+        lazy.ExtensionSearchHandler.handleInputEntered(
           result.payload.keyword,
           result.payload.content,
           where
         );
         return;
       }
     }
 
@@ -1067,52 +1074,52 @@ class UrlbarInput {
         input = this._lastSearchString;
       } else if (result.autofill?.type == "adaptive") {
         input = result.autofill.adaptiveHistoryInput;
       }
       // `input` may be an empty string, so do a strict comparison here.
       if (input !== undefined) {
         // We don't await for this, because a rejection should not interrupt
         // the load. Just reportError it.
-        UrlbarUtils.addToInputHistory(url, input).catch(Cu.reportError);
+        lazy.UrlbarUtils.addToInputHistory(url, input).catch(Cu.reportError);
       }
     }
 
     this.controller.engagementEvent.record(event, {
       searchString: this._lastSearchString,
       selIndex,
       selType: this.controller.engagementEvent.typeFromElement(element),
       provider: result.providerName,
     });
 
     if (result.payload.sendAttributionRequest) {
-      PartnerLinkAttribution.makeRequest({
+      lazy.PartnerLinkAttribution.makeRequest({
         targetURL: result.payload.url,
         source: "urlbar",
         campaignID: Services.prefs.getStringPref(
           "browser.partnerlink.campaign.topsites"
         ),
       });
       if (!this.isPrivate && result.providerName === "UrlbarProviderTopSites") {
         // The position is 1-based for telemetry
         const position = selIndex + 1;
         Services.telemetry.keyedScalarAdd(
           SCALAR_CATEGORY_TOPSITES,
           `urlbar_${position}`,
           1
         );
-        PartnerLinkAttribution.sendContextualServicesPing(
+        lazy.PartnerLinkAttribution.sendContextualServicesPing(
           {
             position,
             source: "urlbar",
             tile_id: result.payload.sponsoredTileId || -1,
             reporting_url: result.payload.sponsoredClickUrl,
             advertiser: result.payload.title.toLocaleLowerCase(),
           },
-          CONTEXTUAL_SERVICES_PING_TYPES.TOPSITES_SELECTION
+          lazy.CONTEXTUAL_SERVICES_PING_TYPES.TOPSITES_SELECTION
         );
       }
     }
 
     this._loadURL(
       url,
       event,
       where,
@@ -1172,20 +1179,20 @@ class UrlbarInput {
     }
 
     // The value setter clobbers the actiontype attribute, so we need this
     // helper to restore it afterwards.
     const setValueAndRestoreActionType = (value, allowTrim) => {
       this._setValue(value, allowTrim);
 
       switch (result.type) {
-        case UrlbarUtils.RESULT_TYPE.TAB_SWITCH:
+        case lazy.UrlbarUtils.RESULT_TYPE.TAB_SWITCH:
           this.setAttribute("actiontype", "switchtab");
           break;
-        case UrlbarUtils.RESULT_TYPE.OMNIBOX:
+        case lazy.UrlbarUtils.RESULT_TYPE.OMNIBOX:
           this.setAttribute("actiontype", "extension");
           break;
       }
     };
 
     // For autofilled results, the value that should be canonized is not the
     // autofilled value but the value that the user typed.
     let canonizedUrl = this._maybeCanonizeURL(
@@ -1221,22 +1228,22 @@ class UrlbarInput {
       return false;
     }
 
     // If the url is trimmed but it's invalid (for example it has an unknown
     // single word host, or an unknown domain suffix), trimming
     // it would end up executing a search instead of visiting it.
     let allowTrim = true;
     if (
-      (urlOverride || result.type == UrlbarUtils.RESULT_TYPE.URL) &&
-      UrlbarPrefs.get("trimURLs")
+      (urlOverride || result.type == lazy.UrlbarUtils.RESULT_TYPE.URL) &&
+      lazy.UrlbarPrefs.get("trimURLs")
     ) {
       let url = urlOverride || result.payload.url;
-      if (url.startsWith(BrowserUIUtils.trimURLProtocol)) {
-        let fixupInfo = this._getURIFixupInfo(BrowserUIUtils.trimURL(url));
+      if (url.startsWith(lazy.BrowserUIUtils.trimURLProtocol)) {
+        let fixupInfo = this._getURIFixupInfo(lazy.BrowserUIUtils.trimURL(url));
         if (fixupInfo?.keywordAsSent) {
           allowTrim = false;
         }
       }
     }
 
     if (!result.autofill) {
       setValueAndRestoreActionType(
@@ -1393,42 +1400,43 @@ class UrlbarInput {
     }
 
     this._lastSearchString = searchString;
     this._valueOnLastSearch = this.value;
 
     let options = {
       allowAutofill,
       isPrivate: this.isPrivate,
-      maxResults: UrlbarPrefs.get("maxRichResults"),
+      maxResults: lazy.UrlbarPrefs.get("maxRichResults"),
       searchString,
       userContextId: this.window.gBrowser.selectedBrowser.getAttribute(
         "usercontextid"
       ),
       currentPage: this.window.gBrowser.currentURI.spec,
       formHistoryName: this.formHistoryName,
       prohibitRemoteResults:
         event &&
-        UrlbarUtils.isPasteEvent(event) &&
-        UrlbarPrefs.get("maxCharsForSearchSuggestions") < event.data?.length,
+        lazy.UrlbarUtils.isPasteEvent(event) &&
+        lazy.UrlbarPrefs.get("maxCharsForSearchSuggestions") <
+          event.data?.length,
     };
 
     if (this.searchMode) {
       this.confirmSearchMode();
       options.searchMode = this.searchMode;
       if (this.searchMode.source) {
         options.sources = [this.searchMode.source];
       }
     }
 
     // TODO (Bug 1522902): This promise is necessary for tests, because some
     // tests are not listening for completion when starting a query through
     // other methods than startQuery (input events for example).
     this.lastQueryContextPromise = this.controller.startQuery(
-      new UrlbarQueryContext(options)
+      new lazy.UrlbarQueryContext(options)
     );
   }
 
   /**
    * Sets the input's value, starts a search, and opens the view.
    *
    * @param {string} value
    *   The input's value will be set to this value, and the search will
@@ -1443,44 +1451,46 @@ class UrlbarInput {
    *   If true, the urlbar will be focused.  If false, the focus will remain
    *   unchanged.
    */
   search(value, { searchEngine, searchModeEntry, focus = true } = {}) {
     if (focus) {
       this.focus();
     }
     let trimmedValue = value.trim();
-    let end = trimmedValue.search(UrlbarTokenizer.REGEXP_SPACES);
+    let end = trimmedValue.search(lazy.UrlbarTokenizer.REGEXP_SPACES);
     let firstToken = end == -1 ? trimmedValue : trimmedValue.substring(0, end);
     // Enter search mode if the string starts with a restriction token.
-    let searchMode = UrlbarUtils.searchModeForToken(firstToken);
+    let searchMode = lazy.UrlbarUtils.searchModeForToken(firstToken);
     let firstTokenIsRestriction = !!searchMode;
     if (!searchMode && searchEngine) {
       searchMode = { engineName: searchEngine.name };
       firstTokenIsRestriction = searchEngine.aliases.includes(firstToken);
     }
 
     if (searchMode) {
       searchMode.entry = searchModeEntry;
       this.searchMode = searchMode;
       if (firstTokenIsRestriction) {
         // Remove the restriction token/alias from the string to be searched for
         // in search mode.
         value = value.replace(firstToken, "");
       }
-      if (UrlbarTokenizer.REGEXP_SPACES.test(value[0])) {
+      if (lazy.UrlbarTokenizer.REGEXP_SPACES.test(value[0])) {
         // If there was a trailing space after the restriction token/alias,
         // remove it.
         value = value.slice(1);
       }
       this._revertOnBlurValue = value;
-    } else if (Object.values(UrlbarTokenizer.RESTRICT).includes(firstToken)) {
+    } else if (
+      Object.values(lazy.UrlbarTokenizer.RESTRICT).includes(firstToken)
+    ) {
       this.searchMode = null;
       // If the entire value is a restricted token, append a space.
-      if (Object.values(UrlbarTokenizer.RESTRICT).includes(value)) {
+      if (Object.values(lazy.UrlbarTokenizer.RESTRICT).includes(value)) {
         value += " ";
       }
       this._revertOnBlurValue = value;
     }
     this.inputField.value = value;
     // Avoid selecting the text if this method is called twice in a row.
     this.selectionStart = -1;
 
@@ -1579,17 +1589,17 @@ class UrlbarInput {
    *   be interacted with right away. Defaults to true.
    * @param {Browser} browser
    *   The browser for which to set search mode.
    */
   async setSearchMode(searchMode, browser) {
     let currentSearchMode = this.getSearchMode(browser);
     let areSearchModesSame =
       (!currentSearchMode && !searchMode) ||
-      ObjectUtils.deepEqual(currentSearchMode, searchMode);
+      lazy.ObjectUtils.deepEqual(currentSearchMode, searchMode);
 
     // Exit search mode if the passed-in engine is invalid or hidden.
     let engine;
     if (searchMode?.engineName) {
       if (!Services.search.isInitialized) {
         await Services.search.init();
       }
       engine = Services.search.getEngineByName(searchMode.engineName);
@@ -1608,30 +1618,30 @@ class UrlbarInput {
         isGeneralPurposeEngine: engine.isGeneralPurposeEngine,
       };
       if (source) {
         searchMode.source = source;
       } else if (searchMode.isGeneralPurposeEngine) {
         // History results for general-purpose search engines are often not
         // useful, so we hide them in search mode. See bug 1658646 for
         // discussion.
-        searchMode.source = UrlbarUtils.RESULT_SOURCE.SEARCH;
+        searchMode.source = lazy.UrlbarUtils.RESULT_SOURCE.SEARCH;
       }
     } else if (source) {
-      let sourceName = UrlbarUtils.getResultSourceName(source);
+      let sourceName = lazy.UrlbarUtils.getResultSourceName(source);
       if (sourceName) {
         searchMode = { source };
       } else {
         Cu.reportError(`Unrecognized source: ${source}`);
       }
     }
 
     if (searchMode) {
       searchMode.isPreview = isPreview;
-      if (UrlbarUtils.SEARCH_MODE_ENTRY.has(entry)) {
+      if (lazy.UrlbarUtils.SEARCH_MODE_ENTRY.has(entry)) {
         searchMode.entry = entry;
       } else {
         // If we see this value showing up in telemetry, we should review
         // search mode's entry points.
         searchMode.entry = "other";
       }
 
       // Add the search mode to the map.
@@ -1653,17 +1663,17 @@ class UrlbarInput {
       this._updateSearchModeUI(searchMode);
       if (searchMode) {
         // Set userTypedValue to the query string so that it's properly restored
         // when switching back to the current tab and across sessions.
         this.window.gBrowser.userTypedValue = this.untrimmedValue;
         this.valueIsTyped = true;
         if (!searchMode.isPreview && !areSearchModesSame) {
           try {
-            BrowserSearchTelemetry.recordSearchMode(searchMode);
+            lazy.BrowserSearchTelemetry.recordSearchMode(searchMode);
           } catch (ex) {
             Cu.reportError(ex);
           }
         }
       }
     }
   }
 
@@ -1679,18 +1689,18 @@ class UrlbarInput {
 
   /**
    * Enters search mode with the default engine.
    */
   searchModeShortcut() {
     // We restrict to search results when entering search mode from this
     // shortcut to honor historical behaviour.
     this.searchMode = {
-      source: UrlbarUtils.RESULT_SOURCE.SEARCH,
-      engineName: UrlbarSearchUtils.getDefaultEngine(this.isPrivate).name,
+      source: lazy.UrlbarUtils.RESULT_SOURCE.SEARCH,
+      engineName: lazy.UrlbarSearchUtils.getDefaultEngine(this.isPrivate).name,
       entry: "shortcut",
     };
     // The searchMode setter clears the input if pageproxystate is valid, so
     // we know at this point this.value will either be blank or the user's
     // typed string.
     this.search(this.value);
     this.select();
   }
@@ -1776,17 +1786,17 @@ class UrlbarInput {
     ) {
       return;
     }
     if (!this.view.isOpen) {
       return;
     }
 
     if (Cu.isInAutomation) {
-      if (UrlbarPrefs.get("disableExtendForTests")) {
+      if (lazy.UrlbarPrefs.get("disableExtendForTests")) {
         this.setAttribute("breakout-extend-disabled", "true");
         return;
       }
       this.removeAttribute("breakout-extend-disabled");
     }
 
     this._toolbar.setAttribute("urlbar-exceeds-toolbar-bounds", "true");
     this.setAttribute("breakout-extend", "true");
@@ -1903,20 +1913,20 @@ class UrlbarInput {
       this.startQuery({ allowAutofill: false });
     }
 
     return true;
   }
 
   observe(subject, topic, data) {
     switch (topic) {
-      case SearchUtils.TOPIC_ENGINE_MODIFIED: {
+      case lazy.SearchUtils.TOPIC_ENGINE_MODIFIED: {
         switch (data) {
-          case SearchUtils.MODIFIED_TYPE.CHANGED:
-          case SearchUtils.MODIFIED_TYPE.REMOVED: {
+          case lazy.SearchUtils.MODIFIED_TYPE.CHANGED:
+          case lazy.SearchUtils.MODIFIED_TYPE.REMOVED: {
             let searchMode = this.searchMode;
             let engine = subject.QueryInterface(Ci.nsISearchEngine);
             if (searchMode?.engineName == engine.name) {
               // Exit search mode if the current search mode engine was removed.
               this.searchMode = searchMode;
             }
             break;
           }
@@ -1924,17 +1934,21 @@ class UrlbarInput {
         break;
       }
     }
   }
 
   // Private methods below.
 
   _addObservers() {
-    Services.obs.addObserver(this, SearchUtils.TOPIC_ENGINE_MODIFIED, true);
+    Services.obs.addObserver(
+      this,
+      lazy.SearchUtils.TOPIC_ENGINE_MODIFIED,
+      true
+    );
   }
 
   _getURIFixupInfo(searchString) {
     let flags =
       Ci.nsIURIFixup.FIXUP_FLAG_FIX_SCHEME_TYPOS |
       Ci.nsIURIFixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP;
     if (this.isPrivate) {
       flags |= Ci.nsIURIFixup.FIXUP_FLAG_PRIVATE_CONTEXT;
@@ -2004,17 +2018,17 @@ class UrlbarInput {
 
         resolve();
       });
     });
   }
 
   _setValue(val, allowTrim) {
     // Don't expose internal about:reader URLs to the user.
-    let originalUrl = ReaderMode.getOriginalUrlObjectForDisplay(val);
+    let originalUrl = lazy.ReaderMode.getOriginalUrlObjectForDisplay(val);
     if (originalUrl) {
       val = originalUrl.displaySpec;
     }
     this._untrimmedValue = val;
 
     if (allowTrim) {
       val = this._trimValue(val);
     }
@@ -2030,29 +2044,29 @@ class UrlbarInput {
     event.initEvent("ValueChange", true, true);
     this.inputField.dispatchEvent(event);
 
     return val;
   }
 
   _getValueFromResult(result, urlOverride = null) {
     switch (result.type) {
-      case UrlbarUtils.RESULT_TYPE.KEYWORD:
+      case lazy.UrlbarUtils.RESULT_TYPE.KEYWORD:
         return result.payload.input;
-      case UrlbarUtils.RESULT_TYPE.SEARCH: {
+      case lazy.UrlbarUtils.RESULT_TYPE.SEARCH: {
         let value = "";
         if (result.payload.keyword) {
           value += result.payload.keyword + " ";
         }
         value += result.payload.suggestion || result.payload.query;
         return value;
       }
-      case UrlbarUtils.RESULT_TYPE.OMNIBOX:
+      case lazy.UrlbarUtils.RESULT_TYPE.OMNIBOX:
         return result.payload.content;
-      case UrlbarUtils.RESULT_TYPE.DYNAMIC:
+      case lazy.UrlbarUtils.RESULT_TYPE.DYNAMIC:
         return result.payload.input || "";
     }
 
     if (urlOverride === "") {
       // Allow callers to clear the input.
       return "";
     }
 
@@ -2085,17 +2099,17 @@ class UrlbarInput {
    * @returns {boolean}
    *   Whether autofill should be allowed in the new search.
    */
   _maybeAutofillPlaceholder(value) {
     // We allow autofill in local but not remote search modes.
     let allowAutofill =
       this.selectionEnd == value.length &&
       !this.searchMode?.engineName &&
-      this.searchMode?.source != UrlbarUtils.RESULT_SOURCE.SEARCH;
+      this.searchMode?.source != lazy.UrlbarUtils.RESULT_SOURCE.SEARCH;
     if (!allowAutofill) {
       this._autofillPlaceholder = null;
       return false;
     }
 
     // Determine whether we can autofill the placeholder.  The placeholder is a
     // value that we autofill now, when the search starts and before we wait on
     // its first result, in order to prevent a flicker in the input caused by
@@ -2108,17 +2122,17 @@ class UrlbarInput {
       if (this._autofillPlaceholder.type == "adaptive") {
         canAutofillPlaceholder =
           value.length >=
             this._autofillPlaceholder.adaptiveHistoryInput.length &&
           this._autofillPlaceholder.value
             .toLocaleLowerCase()
             .startsWith(value.toLocaleLowerCase());
       } else {
-        canAutofillPlaceholder = UrlbarUtils.canAutofillURL(
+        canAutofillPlaceholder = lazy.UrlbarUtils.canAutofillURL(
           this._autofillPlaceholder.value,
           value
         );
       }
     }
 
     if (!canAutofillPlaceholder) {
       this._autofillPlaceholder = null;
@@ -2258,37 +2272,37 @@ class UrlbarInput {
 
     // If the entire URL is selected, just use the actual loaded URI,
     // unless we want a decoded URI, or it's a data: or javascript: URI,
     // since those are hard to read when encoded.
     if (
       this.value == selectedVal &&
       !uri.schemeIs("javascript") &&
       !uri.schemeIs("data") &&
-      !UrlbarPrefs.get("decodeURLsOnCopy")
+      !lazy.UrlbarPrefs.get("decodeURLsOnCopy")
     ) {
       return displaySpec;
     }
 
     // Just the beginning of the URL is selected, or we want a decoded
     // url. First check for a trimmed value.
 
     if (
-      !selectedVal.startsWith(BrowserUIUtils.trimURLProtocol) &&
+      !selectedVal.startsWith(lazy.BrowserUIUtils.trimURLProtocol) &&
       // Note _trimValue may also trim a trailing slash, thus we can't just do
       // a straight string compare to tell if the protocol was trimmed.
       !displaySpec.startsWith(this._trimValue(displaySpec))
     ) {
-      selectedVal = BrowserUIUtils.trimURLProtocol + selectedVal;
+      selectedVal = lazy.BrowserUIUtils.trimURLProtocol + selectedVal;
     }
 
     // If selection starts from the beginning and part or all of the URL
     // is selected, we check for decoded characters and encode them.
     // Unless decodeURLsOnCopy is set. Do not encode data: URIs.
-    if (!UrlbarPrefs.get("decodeURLsOnCopy") && !uri.schemeIs("data")) {
+    if (!lazy.UrlbarPrefs.get("decodeURLsOnCopy") && !uri.schemeIs("data")) {
       try {
         new URL(selectedVal);
         // Use encodeURI instead of URL.href because we don't want
         // trailing slash.
         selectedVal = encodeURI(selectedVal);
       } catch (ex) {
         // URL is invalid. Return original selected value.
       }
@@ -2358,17 +2372,17 @@ class UrlbarInput {
       // Without checking !isOneOff, we might record the string
       // oneoff_urlbar-searchmode in the SEARCH_COUNTS probe (in addition to
       // oneoff_urlbar and oneoff_searchbar). The extra information is not
       // necessary; the intent is the same regardless of whether the user is
       // in search mode when they do a key-modified click/enter on a one-off.
       source = "urlbar-searchmode";
     }
 
-    BrowserSearchTelemetry.recordSearch(
+    lazy.BrowserSearchTelemetry.recordSearch(
       this.window.gBrowser.selectedBrowser,
       engine,
       source,
       {
         ...searchActionDetails,
         isOneOff,
         newtabSessionId: this._handoffSession,
       }
@@ -2379,17 +2393,19 @@ class UrlbarInput {
    * Shortens the given value, usually by removing http:// and trailing slashes.
    *
    * @param {string} val
    *   The string to be trimmed if it appears to be URI
    * @returns {string}
    *   The trimmed string
    */
   _trimValue(val) {
-    return UrlbarPrefs.get("trimURLs") ? BrowserUIUtils.trimURL(val) : val;
+    return lazy.UrlbarPrefs.get("trimURLs")
+      ? lazy.BrowserUIUtils.trimURL(val)
+      : val;
   }
 
   /**
    * If appropriate, this prefixes a search string with 'www.' and suffixes it
    * with browser.fixup.alternate.suffix prior to navigating.
    *
    * @param {Event} event
    *   The event that triggered this query.
@@ -2400,17 +2416,17 @@ class UrlbarInput {
    */
   _maybeCanonizeURL(event, value) {
     // Only add the suffix when the URL bar value isn't already "URL-like",
     // and only if we get a keyboard event, to match user expectations.
     if (
       !KeyboardEvent.isInstance(event) ||
       event._disableCanonization ||
       !event.ctrlKey ||
-      !UrlbarPrefs.get("ctrlCanonizesURLs") ||
+      !lazy.UrlbarPrefs.get("ctrlCanonizesURLs") ||
       !/^\s*[^.:\/\s]+(?:\/.*|\s*)$/i.test(value)
     ) {
       return null;
     }
 
     let suffix = Services.prefs.getCharPref("browser.fixup.alternate.suffix");
     if (!suffix.endsWith("/")) {
       suffix += "/";
@@ -2521,17 +2537,17 @@ class UrlbarInput {
     if (
       openUILinkWhere != "window" &&
       this.window.gInitialPages.includes(url)
     ) {
       browser.initialPageLoadedFromUserAction = url;
     }
 
     try {
-      UrlbarUtils.addToUrlbarHistory(url, this.window);
+      lazy.UrlbarUtils.addToUrlbarHistory(url, this.window);
     } catch (ex) {
       // Things may go wrong when adding url to session history,
       // but don't let that interfere with the loading of the url.
       Cu.reportError(ex);
     }
 
     // TODO: When bug 1498553 is resolved, we should be able to
     // remove the !triggeringPrincipal condition here.
@@ -2627,25 +2643,25 @@ class UrlbarInput {
       (event.altKey || event.getModifierState("AltGraph"))
     ) {
       // We support using 'alt' to open in a tab, because ctrl/shift
       // might be used for canonizing URLs:
       where = event.shiftKey ? "tabshifted" : "tab";
     } else if (
       isKeyboardEvent &&
       event.ctrlKey &&
-      UrlbarPrefs.get("ctrlCanonizesURLs")
+      lazy.UrlbarPrefs.get("ctrlCanonizesURLs")
     ) {
       // If we're allowing canonization, and this is a key event with ctrl
       // pressed, open in current tab to allow ctrl-enter to canonize URL.
       where = "current";
     } else {
       where = this.window.whereToOpenLink(event, false, false);
     }
-    if (UrlbarPrefs.get("openintab")) {
+    if (lazy.UrlbarPrefs.get("openintab")) {
       if (where == "current") {
         where = "tab";
       } else if (where == "tab") {
         where = "current";
       }
       reuseEmpty = true;
     }
     if (
@@ -2740,17 +2756,19 @@ class UrlbarInput {
    *   entered. See setSearchMode documentation for details.
    */
   _searchModeForResult(result, entry = null) {
     // Search mode is determined by the result's keyword or engine.
     if (!result.payload.keyword && !result.payload.engine) {
       return null;
     }
 
-    let searchMode = UrlbarUtils.searchModeForToken(result.payload.keyword);
+    let searchMode = lazy.UrlbarUtils.searchModeForToken(
+      result.payload.keyword
+    );
     // If result.originalEngine is set, then the user is Alt+Tabbing
     // through the one-offs, so the keyword doesn't match the engine.
     if (
       !searchMode &&
       result.payload.engine &&
       (!result.payload.originalEngine ||
         result.payload.engine == result.payload.originalEngine)
     ) {
@@ -2824,17 +2842,17 @@ class UrlbarInput {
       this.document.l10n.setAttributes(
         this.inputField,
         isGeneralPurposeEngine
           ? "urlbar-placeholder-search-mode-web-2"
           : "urlbar-placeholder-search-mode-other-engine",
         { name: engineName }
       );
     } else if (source) {
-      let sourceName = UrlbarUtils.getResultSourceName(source);
+      let sourceName = lazy.UrlbarUtils.getResultSourceName(source);
       let l10nID = `urlbar-search-mode-${sourceName}`;
       this.document.l10n.setAttributes(this._searchModeIndicatorTitle, l10nID);
       this.document.l10n.setAttributes(this._searchModeLabel, l10nID);
       this.document.l10n.setAttributes(
         this.inputField,
         `urlbar-placeholder-search-mode-other-${sourceName}`
       );
     }
@@ -2853,17 +2871,17 @@ class UrlbarInput {
 
   /**
    * Determines if we should select all the text in the Urlbar based on the
    *  Urlbar state, and whether the selection is empty.
    */
   _maybeSelectAll() {
     if (
       !this._preventClickSelectsAll &&
-      this._compositionState != UrlbarUtils.COMPOSITION.COMPOSING &&
+      this._compositionState != lazy.UrlbarUtils.COMPOSITION.COMPOSING &&
       this.document.activeElement == this.inputField &&
       this.inputField.selectionStart == this.inputField.selectionEnd
     ) {
       this.select();
     }
   }
 
   // Event handlers below.
@@ -2912,23 +2930,23 @@ class UrlbarInput {
 
     // In certain cases, like holding an override key and confirming an entry,
     // we don't key a keyup event for the override key, thus we make this
     // additional cleanup on blur.
     this._clearActionOverride();
 
     // The extension input sessions depends more on blur than on the fact we
     // actually cancel a running query, so we do it here.
-    if (ExtensionSearchHandler.hasActiveInputSession()) {
-      ExtensionSearchHandler.handleInputCancelled();
+    if (lazy.ExtensionSearchHandler.hasActiveInputSession()) {
+      lazy.ExtensionSearchHandler.handleInputCancelled();
     }
 
     // Respect the autohide preference for easier inspecting/debugging via
     // the browser toolbox.
-    if (!UrlbarPrefs.get("ui.popup.disable_autohide")) {
+    if (!lazy.UrlbarPrefs.get("ui.popup.disable_autohide")) {
       this.view.close();
     }
 
     if (this._revertOnBlurValue == this.value) {
       this.handleRevert();
     }
     this._revertOnBlurValue = null;
 
@@ -3027,17 +3045,17 @@ class UrlbarInput {
     Services.obs.notifyObservers(null, "urlbar-focus");
   }
 
   _on_mouseover(event) {
     this._updateUrlTooltip();
   }
 
   _on_draggableregionleftmousedown(event) {
-    if (!UrlbarPrefs.get("ui.popup.disable_autohide")) {
+    if (!lazy.UrlbarPrefs.get("ui.popup.disable_autohide")) {
       this.view.close();
     }
   }
 
   _on_mousedown(event) {
     switch (event.currentTarget) {
       case this.textbox:
         this._mousedownOnUrlbarDescendant = true;
@@ -3068,17 +3086,17 @@ class UrlbarInput {
         // Clear any previous selection unless we are focused, to ensure it
         // doesn't affect drag selection.
         if (this.focusedViaMousedown) {
           this.inputField.setSelectionRange(0, 0);
         }
 
         if (event.target.id == SEARCH_BUTTON_ID) {
           this._preventClickSelectsAll = true;
-          this.search(UrlbarTokenizer.RESTRICT.SEARCH);
+          this.search(lazy.UrlbarTokenizer.RESTRICT.SEARCH);
         } else {
           // Do not suppress the focus border if we are already focused. If we
           // did, we'd hide the focus border briefly then show it again if the
           // user has Top Sites disabled, creating a flashing effect.
           this.view.autoOpen({
             event,
             suppressFocusBorder: !hasFocus,
           });
@@ -3093,17 +3111,17 @@ class UrlbarInput {
         // view open on tab switch, and the TabSelect event arrived earlier.
         if (event.target.closest("tab")) {
           break;
         }
         // Close the view when clicking on toolbars and other UI pieces that
         // might not automatically remove focus from the input.
         // Respect the autohide preference for easier inspecting/debugging via
         // the browser toolbox.
-        if (!UrlbarPrefs.get("ui.popup.disable_autohide")) {
+        if (!lazy.UrlbarPrefs.get("ui.popup.disable_autohide")) {
           this.view.close();
         }
         break;
     }
   }
 
   _on_input(event) {
     let value = this.value;
@@ -3116,18 +3134,18 @@ class UrlbarInput {
     // string, thus there's no valid selection. This is also used by the view
     // to set "aria-activedescendant", thus it should never get stale.
     this.controller.userSelectionBehavior = "none";
 
     let compositionState = this._compositionState;
     let compositionClosedPopup = this._compositionClosedPopup;
 
     // Clear composition values if we're no more composing.
-    if (this._compositionState != UrlbarUtils.COMPOSITION.COMPOSING) {
-      this._compositionState = UrlbarUtils.COMPOSITION.NONE;
+    if (this._compositionState != lazy.UrlbarUtils.COMPOSITION.COMPOSING) {
+      this._compositionState = lazy.UrlbarUtils.COMPOSITION.NONE;
       this._compositionClosedPopup = false;
     }
 
     if (value) {
       this.setAttribute("usertyping", "true");
     } else {
       this.removeAttribute("usertyping");
     }
@@ -3137,17 +3155,17 @@ class UrlbarInput {
       this.getAttribute("pageproxystate") == "valid" &&
       this.value != this._lastValidURLStr
     ) {
       this.setPageProxyState("invalid", true);
     }
 
     if (!this.view.isOpen) {
       this.view.clear();
-    } else if (!value && !UrlbarPrefs.get("suggest.topsites")) {
+    } else if (!value && !lazy.UrlbarPrefs.get("suggest.topsites")) {
       this.view.clear();
       if (!this.searchMode || !this.view.oneOffSearchButtons.hasView) {
         this.view.close();
         return;
       }
     }
 
     this.view.removeAccessibleFocus();
@@ -3156,31 +3174,31 @@ class UrlbarInput {
     // 1. a compositionstart event
     // 2. some input events
     // 3. a compositionend event
     // 4. an input event
 
     // We should do nothing during composition or if composition was canceled
     // and we didn't close the popup on composition start.
     if (
-      !UrlbarPrefs.get("keepPanelOpenDuringImeComposition") &&
-      (compositionState == UrlbarUtils.COMPOSITION.COMPOSING ||
-        (compositionState == UrlbarUtils.COMPOSITION.CANCELED &&
+      !lazy.UrlbarPrefs.get("keepPanelOpenDuringImeComposition") &&
+      (compositionState == lazy.UrlbarUtils.COMPOSITION.COMPOSING ||
+        (compositionState == lazy.UrlbarUtils.COMPOSITION.CANCELED &&
           !compositionClosedPopup))
     ) {
       return;
     }
 
     // Autofill only when text is inserted (i.e., event.data is not empty) and
     // it's not due to pasting.
     const allowAutofill =
-      (!UrlbarPrefs.get("keepPanelOpenDuringImeComposition") ||
-        compositionState !== UrlbarUtils.COMPOSITION.COMPOSING) &&
+      (!lazy.UrlbarPrefs.get("keepPanelOpenDuringImeComposition") ||
+        compositionState !== lazy.UrlbarUtils.COMPOSITION.COMPOSING) &&
       !!event.data &&
-      !UrlbarUtils.isPasteEvent(event) &&
+      !lazy.UrlbarUtils.isPasteEvent(event) &&
       this._maybeAutofillPlaceholder(value);
 
     this.startQuery({
       searchString: value,
       allowAutofill,
       resetSearchState: false,
       event,
     });
@@ -3209,17 +3227,17 @@ class UrlbarInput {
       return;
     }
 
     let val = this._getSelectedValueForClipboard();
     if (!val) {
       return;
     }
 
-    ClipboardHelper.copyStringToClipboard(
+    lazy.ClipboardHelper.copyStringToClipboard(
       val,
       Services.clipboard.kSelectionClipboard
     );
   }
 
   _on_overflow(event) {
     const targetIsPlaceholder =
       event.originalTarget.implementedPseudoElement == "::placeholder";
@@ -3276,17 +3294,17 @@ class UrlbarInput {
     // In some cases, the data pasted will contain newline codes. In order to
     // achive the behavior expected by user, remove newline codes when URL is
     // assumed. When keywords are assumed, replace all whitespace characters
     // including newline with a space.
     let pasteData = isURLAssumed
       ? originalPasteData.replace(/[\r\n]/g, "")
       : originalPasteData.replace(/\s/g, " ");
 
-    pasteData = UrlbarUtils.stripUnsafeProtocolOnPaste(pasteData);
+    pasteData = lazy.UrlbarUtils.stripUnsafeProtocolOnPaste(pasteData);
 
     if (originalPasteData != pasteData) {
       // Unfortunately we're not allowed to set the bits being pasted
       // so cancel this event:
       event.preventDefault();
       event.stopImmediatePropagation();
 
       this.inputField.value = oldStart + pasteData + oldEnd;
@@ -3321,17 +3339,17 @@ class UrlbarInput {
     }
   }
 
   _on_keydown(event) {
     if (event.keyCode === KeyEvent.DOM_VK_RETURN) {
       if (this._keyDownEnterDeferred) {
         this._keyDownEnterDeferred.reject();
       }
-      this._keyDownEnterDeferred = PromiseUtils.defer();
+      this._keyDownEnterDeferred = lazy.PromiseUtils.defer();
       event._disableCanonization = this._isKeyDownWithCtrl;
     } else if (event.keyCode !== KeyEvent.DOM_VK_CONTROL && event.ctrlKey) {
       this._isKeyDownWithCtrl = true;
     }
 
     // Due to event deferring, it's possible preventDefault() won't be invoked
     // soon enough to actually prevent some of the default behaviors, thus we
     // have to handle the event "twice". This first immediate call passes false
@@ -3380,22 +3398,22 @@ class UrlbarInput {
         this._keyDownEnterDeferred.resolve();
       }
 
       this._keyDownEnterDeferred = null;
     }
   }
 
   _on_compositionstart(event) {
-    if (this._compositionState == UrlbarUtils.COMPOSITION.COMPOSING) {
+    if (this._compositionState == lazy.UrlbarUtils.COMPOSITION.COMPOSING) {
       throw new Error("Trying to start a nested composition?");
     }
-    this._compositionState = UrlbarUtils.COMPOSITION.COMPOSING;
-
-    if (UrlbarPrefs.get("keepPanelOpenDuringImeComposition")) {
+    this._compositionState = lazy.UrlbarUtils.COMPOSITION.COMPOSING;
+
+    if (lazy.UrlbarPrefs.get("keepPanelOpenDuringImeComposition")) {
       return;
     }
 
     // Close the view. This will also stop searching.
     if (this.view.isOpen) {
       // We're closing the view, but we want to retain search mode if the
       // selected result was previewing it.
       if (this.searchMode) {
@@ -3411,33 +3429,33 @@ class UrlbarInput {
       this._compositionClosedPopup = true;
       this.view.close();
     } else {
       this._compositionClosedPopup = false;
     }
   }
 
   _on_compositionend(event) {
-    if (this._compositionState != UrlbarUtils.COMPOSITION.COMPOSING) {
+    if (this._compositionState != lazy.UrlbarUtils.COMPOSITION.COMPOSING) {
       throw new Error("Trying to stop a non existing composition?");
     }
 
-    if (!UrlbarPrefs.get("keepPanelOpenDuringImeComposition")) {
+    if (!lazy.UrlbarPrefs.get("keepPanelOpenDuringImeComposition")) {
       // Clear the selection and the cached result, since they refer to the
       // state before this composition. A new input even will be generated
       // after this.
       this.view.clearSelection();
       this._resultForCurrentValue = null;
     }
 
     // We can't yet retrieve the committed value from the editor, since it isn't
     // completely committed yet. We'll handle it at the next input event.
     this._compositionState = event.data
-      ? UrlbarUtils.COMPOSITION.COMMIT
-      : UrlbarUtils.COMPOSITION.CANCELED;
+      ? lazy.UrlbarUtils.COMPOSITION.COMMIT
+      : lazy.UrlbarUtils.COMPOSITION.CANCELED;
   }
 
   _on_dragstart(event) {
     // Drag only if the gesture starts from the input field.
     let nodePosition = this.inputField.compareDocumentPosition(
       event.originalTarget
     );
     if (
@@ -3530,17 +3548,17 @@ function getDroppableData(event) {
     // case we should always return null.
     return null;
   }
   // The URL bar automatically handles inputs with newline characters,
   // so we can get away with treating text/x-moz-url flavours as text/plain.
   if (links.length && links[0].url) {
     event.preventDefault();
     let href = links[0].url;
-    if (UrlbarUtils.stripUnsafeProtocolOnPaste(href) != href) {
+    if (lazy.UrlbarUtils.stripUnsafeProtocolOnPaste(href) != href) {
       // We may have stripped an unsafe protocol like javascript: and if so
       // there's no point in handling a partial drop.
       event.stopImmediatePropagation();
       return null;
     }
 
     try {
       // If this throws, checkLoadURStrWithPrincipal would also throw,
@@ -3695,17 +3713,17 @@ class CopyCutController {
         bubbles: true,
         cancelable: false,
         view: urlbar.window,
         detail: 0,
       });
       urlbar.inputField.dispatchEvent(event);
     }
 
-    ClipboardHelper.copyString(val);
+    lazy.ClipboardHelper.copyString(val);
   }
 
   /**
    * @param {string} command
    * @returns {boolean}
    *   Whether the command is handled by this controller.
    */
   supportsCommand(command) {
@@ -3767,17 +3785,17 @@ class AddSearchEngineHelper {
       this.shortcutButtons.updateWebEngines(engines);
     }
   }
 
   _sameEngines(engines1, engines2) {
     if (engines1?.length != engines2?.length) {
       return false;
     }
-    return ObjectUtils.deepEqual(
+    return lazy.ObjectUtils.deepEqual(
       engines1.map(e => e.title),
       engines2.map(e => e.title)
     );
   }
 
   _createMenuitem(engine, index) {
     let elt = this.input.document.createXULElement("menuitem");
     elt.setAttribute("anonid", `add-engine-${index}`);
@@ -3856,17 +3874,17 @@ class AddSearchEngineHelper {
       } else {
         curElt.insertAdjacentElement("afterend", elt);
       }
       curElt = elt;
     }
   }
 
   async _onCommand(event) {
-    let added = await SearchUIUtils.addOpenSearchEngine(
+    let added = await lazy.SearchUIUtils.addOpenSearchEngine(
       event.target.getAttribute("uri"),
       event.target.getAttribute("image"),
       this.browsingContext
     ).catch(console.error);
     if (added) {
       // Remove the offered engine from the list. The browser updated the
       // engines list at this point, so we just have to refresh the menu.)
       this.refreshContextMenu();
--- a/browser/components/urlbar/UrlbarMuxerUnifiedComplete.jsm
+++ b/browser/components/urlbar/UrlbarMuxerUnifiedComplete.jsm
@@ -9,28 +9,33 @@
  */
 
 var EXPORTED_SYMBOLS = ["UrlbarMuxerUnifiedComplete"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-XPCOMUtils.defineLazyModuleGetters(this, {
+
+const { UrlbarMuxer, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
   UrlbarProviderQuickSuggest:
     "resource:///modules/UrlbarProviderQuickSuggest.jsm",
   UrlbarProviderTabToSearch:
     "resource:///modules/UrlbarProviderTabToSearch.jsm",
-  UrlbarMuxer: "resource:///modules/UrlbarUtils.jsm",
   UrlbarSearchUtils: "resource:///modules/UrlbarSearchUtils.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
-XPCOMUtils.defineLazyGetter(this, "logger", () =>
+XPCOMUtils.defineLazyGetter(lazy, "logger", () =>
   UrlbarUtils.getLogger({ prefix: "MuxerUnifiedComplete" })
 );
 
 /**
  * Class used to create a muxer.
  * The muxer receives and sorts results in a UrlbarQueryContext.
  */
 class MuxerUnifiedComplete extends UrlbarMuxer {
@@ -111,17 +116,17 @@ class MuxerUnifiedComplete extends Urlba
     if (state.maxTabToSearchResultSpan) {
       // Subtract the max tab-to-search span.
       state.availableResultSpan = Math.max(
         state.availableResultSpan - state.maxTabToSearchResultSpan,
         0
       );
     }
     if (state.maxHeuristicResultSpan) {
-      if (UrlbarPrefs.get("experimental.hideHeuristic")) {
+      if (lazy.UrlbarPrefs.get("experimental.hideHeuristic")) {
         // The heuristic is hidden. The muxer will include it but the view will
         // hide it. Increase the available span to compensate so that the total
         // visible span accurately reflects `context.maxResults`.
         state.availableResultSpan += state.maxHeuristicResultSpan;
       } else if (context.maxResults > 0) {
         // `context.maxResults` is positive. Make sure there's room for the
         // heuristic even if it means exceeding `context.maxResults`.
         state.availableResultSpan = Math.max(
@@ -129,19 +134,19 @@ class MuxerUnifiedComplete extends Urlba
           state.maxHeuristicResultSpan
         );
       }
     }
 
     // Determine the result groups to use for this sort.  In search mode with
     // an engine, show search suggestions first.
     let rootGroup = context.searchMode?.engineName
-      ? UrlbarPrefs.makeResultGroups({ showSearchSuggestionsFirst: true })
-      : UrlbarPrefs.get("resultGroups");
-    logger.debug(`Groups: ${rootGroup}`);
+      ? lazy.UrlbarPrefs.makeResultGroups({ showSearchSuggestionsFirst: true })
+      : lazy.UrlbarPrefs.get("resultGroups");
+    lazy.logger.debug(`Groups: ${rootGroup}`);
 
     // Fill the root group.
     let [sortedResults] = this._fillGroup(
       rootGroup,
       { availableSpan: state.availableResultSpan, maxResultCount: Infinity },
       state
     );
 
@@ -531,17 +536,17 @@ class MuxerUnifiedComplete extends Urlba
           });
         }
 
         // Now increment or decrement individual limits until their sum is equal
         // to the group's fillable limit.
         while (summedFillableLimit != fillableLimit) {
           if (!fractionalDataArray.length) {
             // This shouldn't happen, but don't let it break us.
-            logger.error("fractionalDataArray is empty!");
+            lazy.logger.error("fractionalDataArray is empty!");
             break;
           }
           let data = flexDataArray[fractionalDataArray.shift().index];
           data.limits[key] += diff;
           summedFillableLimit += diff;
         }
       }
     }
@@ -578,17 +583,17 @@ class MuxerUnifiedComplete extends Urlba
     }
 
     // For form history, maxHistoricalSearchSuggestions == 0 implies the user
     // has opted out of form history completely, so we override the max result
     // count here in that case. Other values of maxHistoricalSearchSuggestions
     // are ignored and we use the flex defined on the form history group.
     if (
       groupConst == UrlbarUtils.RESULT_GROUP.FORM_HISTORY &&
-      !UrlbarPrefs.get("maxHistoricalSearchSuggestions")
+      !lazy.UrlbarPrefs.get("maxHistoricalSearchSuggestions")
     ) {
       // Create a new `limits` object so we don't modify the caller's.
       limits = { ...limits };
       limits.maxResultCount = 0;
     }
 
     let addedResults = [];
     let groupResults = state.resultsByGroup.get(groupConst);
@@ -636,17 +641,17 @@ class MuxerUnifiedComplete extends Urlba
    *   True if the result can be added and false if it should be discarded.
    */
   // TODO (Bug 1741273): Refactor this method to avoid an eslint complexity
   // error or increase the complexity threshold.
   // eslint-disable-next-line complexity
   _canAddResult(result, state) {
     // Never discard quick suggest results. We may want to change this logic at
     // some point, but for all current use cases, they should always be shown.
-    if (result.providerName == UrlbarProviderQuickSuggest.name) {
+    if (result.providerName == lazy.UrlbarProviderQuickSuggest.name) {
       return true;
     }
 
     // We expect UrlbarProviderPlaces sent us the highest-ranked www. and non-www
     // origins, if any. Now, compare them to each other and to the heuristic
     // result.
     //
     // 1. If the heuristic result is lower ranked than both, discard the www
@@ -694,32 +699,32 @@ class MuxerUnifiedComplete extends Urlba
 
     // Discard results that dupe autofill.
     if (
       state.context.heuristicResult &&
       state.context.heuristicResult.autofill &&
       !result.autofill &&
       state.context.heuristicResult.payload?.url == result.payload.url &&
       state.context.heuristicResult.type == result.type &&
-      !UrlbarPrefs.get("experimental.hideHeuristic")
+      !lazy.UrlbarPrefs.get("experimental.hideHeuristic")
     ) {
       return false;
     }
 
     // HeuristicFallback may add non-heuristic results in some cases, but those
     // should be retained only if the heuristic result comes from it.
     if (
       !result.heuristic &&
       result.providerName == "HeuristicFallback" &&
       state.context.heuristicResult?.providerName != "HeuristicFallback"
     ) {
       return false;
     }
 
-    if (result.providerName == UrlbarProviderTabToSearch.name) {
+    if (result.providerName == lazy.UrlbarProviderTabToSearch.name) {
       // Discard the result if a tab-to-search result was added already.
       if (!state.canAddTabToSearch) {
         return false;
       }
 
       // In cases where the heuristic result is not a URL and we have a
       // tab-to-search result, the tab-to-search provider determined that the
       // typed string is similar to an engine domain. We can let the
@@ -838,32 +843,35 @@ class MuxerUnifiedComplete extends Urlba
           // If the result's URL is the same as a brand new SERP URL created
           // from the query string modulo certain URL params, then treat the
           // result as a dupe and discard it.
           let [newSerpURL] = UrlbarUtils.getSearchQueryUrl(
             submission.engine,
             submission.terms
           );
           if (
-            UrlbarSearchUtils.serpsAreEquivalent(result.payload.url, newSerpURL)
+            lazy.UrlbarSearchUtils.serpsAreEquivalent(
+              result.payload.url,
+              newSerpURL
+            )
           ) {
             return false;
           }
         }
       }
     }
 
     // When in an engine search mode, discard URL results whose hostnames don't
     // include the root domain of the search mode engine.
     if (state.context.searchMode?.engineName && result.payload.url) {
       let engine = Services.search.getEngineByName(
         state.context.searchMode.engineName
       );
       if (engine) {
-        let searchModeRootDomain = UrlbarSearchUtils.getRootDomainFromEngine(
+        let searchModeRootDomain = lazy.UrlbarSearchUtils.getRootDomainFromEngine(
           engine
         );
         let resultUrl = new URL(result.payload.url);
         // Add a trailing "." to increase the stringency of the check. This
         // check covers most general cases. Some edge cases are not covered,
         // like `resultUrl` being ebay.mydomain.com, which would escape this
         // check if `searchModeRootDomain` was "ebay".
         if (!resultUrl.hostname.includes(`${searchModeRootDomain}.`)) {
@@ -872,17 +880,17 @@ class MuxerUnifiedComplete extends Urlba
       }
     }
 
     // Discard history results that dupe the quick suggest result.
     if (
       state.quickSuggestResult &&
       !result.heuristic &&
       result.type == UrlbarUtils.RESULT_TYPE.URL &&
-      UrlbarProviderQuickSuggest.isURLEquivalentToResultURL(
+      lazy.UrlbarProviderQuickSuggest.isURLEquivalentToResultURL(
         result.payload.url,
         state.quickSuggestResult
       )
     ) {
       return false;
     }
 
     // Discard history results whose URLs were originally sponsored. We use the
@@ -961,17 +969,17 @@ class MuxerUnifiedComplete extends Urlba
     // suggestedIndex results will always be shown regardless of the total
     // available result span, `context.maxResults`, and `maxRichResults`.
     if (
       result.hasSuggestedIndex &&
       !result.isSuggestedIndexRelativeToGroup &&
       this._canAddResult(result, state)
     ) {
       let span = UrlbarUtils.getSpanForResult(result);
-      if (result.providerName == UrlbarProviderTabToSearch.name) {
+      if (result.providerName == lazy.UrlbarProviderTabToSearch.name) {
         state.maxTabToSearchResultSpan = Math.max(
           state.maxTabToSearchResultSpan,
           span
         );
       } else {
         state.availableResultSpan = Math.max(
           state.availableResultSpan - span,
           0
@@ -979,17 +987,17 @@ class MuxerUnifiedComplete extends Urlba
       }
     }
 
     // Save some state we'll use later to dedupe URL results.
     if (
       (result.type == UrlbarUtils.RESULT_TYPE.URL ||
         result.type == UrlbarUtils.RESULT_TYPE.KEYWORD) &&
       result.payload.url &&
-      (!result.heuristic || !UrlbarPrefs.get("experimental.hideHeuristic"))
+      (!result.heuristic || !lazy.UrlbarPrefs.get("experimental.hideHeuristic"))
     ) {
       let [strippedUrl, prefix] = UrlbarUtils.stripPrefixAndTrim(
         result.payload.url,
         {
           stripHttp: true,
           stripHttps: true,
           stripWww: true,
           trimEmptyQuery: true,
@@ -1001,17 +1009,17 @@ class MuxerUnifiedComplete extends Urlba
       if (
         topPrefixRank < prefixRank ||
         // If a quick suggest result has the same stripped URL and prefix rank
         // as another result, store the quick suggest as the top rank so we
         // discard the other during deduping. That happens after the user picks
         // the quick suggest: The URL is added to history and later both a
         // history result and the quick suggest may match a query.
         (topPrefixRank == prefixRank &&
-          result.providerName == UrlbarProviderQuickSuggest.name)
+          result.providerName == lazy.UrlbarProviderQuickSuggest.name)
       ) {
         // strippedUrl => { prefix, title, rank, providerName }
         state.strippedUrlToTopPrefixAndTitle.set(strippedUrl, {
           prefix,
           title: result.payload.title,
           rank: prefixRank,
           providerName: result.providerName,
         });
@@ -1036,17 +1044,17 @@ class MuxerUnifiedComplete extends Urlba
       state.canShowTailSuggestions &&
       !result.heuristic &&
       (result.type != UrlbarUtils.RESULT_TYPE.SEARCH ||
         (!result.payload.inPrivateWindow && !result.payload.tail))
     ) {
       state.canShowTailSuggestions = false;
     }
 
-    if (result.providerName == UrlbarProviderQuickSuggest.name) {
+    if (result.providerName == lazy.UrlbarProviderQuickSuggest.name) {
       state.quickSuggestResult = result;
     }
 
     state.hasUnitConversionResult =
       state.hasUnitConversionResult || result.providerName == "UnitConversion";
   }
 
   /**
@@ -1061,17 +1069,17 @@ class MuxerUnifiedComplete extends Urlba
    */
   _updateStatePostAdd(result, state) {
     // Update heuristic state.
     if (result.heuristic) {
       state.context.heuristicResult = result;
       if (
         result.type == UrlbarUtils.RESULT_TYPE.SEARCH &&
         result.payload.query &&
-        !UrlbarPrefs.get("experimental.hideHeuristic")
+        !lazy.UrlbarPrefs.get("experimental.hideHeuristic")
       ) {
         let query = result.payload.query.trim().toLocaleLowerCase();
         if (query) {
           state.suggestions.add(query);
         }
       }
     }
 
@@ -1095,27 +1103,27 @@ class MuxerUnifiedComplete extends Urlba
       let suggestion = result.payload.lowerCaseSuggestion.trim();
       if (suggestion) {
         state.suggestions.add(suggestion);
       }
     }
 
     // Avoid multiple tab-to-search results.
     // TODO (Bug 1670185): figure out better strategies to manage this case.
-    if (result.providerName == UrlbarProviderTabToSearch.name) {
+    if (result.providerName == lazy.UrlbarProviderTabToSearch.name) {
       state.canAddTabToSearch = false;
       // We want to record in urlbar.tips once per engagement per engine. Since
       // whether these results are shown is dependent on the Muxer, we must
       // add to `enginesShown` here.
       if (result.payload.dynamicType) {
-        UrlbarProviderTabToSearch.enginesShown.onboarding.add(
+        lazy.UrlbarProviderTabToSearch.enginesShown.onboarding.add(
           result.payload.engine
         );
       } else {
-        UrlbarProviderTabToSearch.enginesShown.regular.add(
+        lazy.UrlbarProviderTabToSearch.enginesShown.regular.add(
           result.payload.engine
         );
       }
     }
 
     // Sync will send us duplicate remote tabs if multiple copies of a tab are
     // open on a synced client. Keep track of which remote tabs we've added to
     // dedupe these.
@@ -1178,26 +1186,26 @@ class MuxerUnifiedComplete extends Urlba
 
       if (a.providerName === b.providerName) {
         return 0;
       }
 
       // If same suggestedIndex, change the displaying order along to following
       // provider priority.
       // TabToSearch > QuickSuggest > Other providers
-      if (a.providerName === UrlbarProviderTabToSearch.name) {
+      if (a.providerName === lazy.UrlbarProviderTabToSearch.name) {
         return 1;
       }
-      if (b.providerName === UrlbarProviderTabToSearch.name) {
+      if (b.providerName === lazy.UrlbarProviderTabToSearch.name) {
         return -1;
       }
-      if (a.providerName === UrlbarProviderQuickSuggest.name) {
+      if (a.providerName === lazy.UrlbarProviderQuickSuggest.name) {
         return 1;
       }
-      if (b.providerName === UrlbarProviderQuickSuggest.name) {
+      if (b.providerName === lazy.UrlbarProviderQuickSuggest.name) {
         return -1;
       }
 
       return 0;
     });
 
     // Conversely, sort the negative results descending so that results at the
     // front of the array don't end up offset by later insertions at the end.
--- a/browser/components/urlbar/UrlbarPrefs.jsm
+++ b/browser/components/urlbar/UrlbarPrefs.jsm
@@ -12,17 +12,19 @@
 
 var EXPORTED_SYMBOLS = ["UrlbarPrefs", "UrlbarPrefsObserver"];
 
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 
-XPCOMUtils.defineLazyModuleGetters(this, {
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   NimbusFeatures: "resource://nimbus/ExperimentAPI.jsm",
   Region: "resource://gre/modules/Region.jsm",
   UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 const PREF_URLBAR_BRANCH = "browser.urlbar.";
 
 const FIREFOX_SUGGEST_UPDATE_TOPIC = "firefox-suggest-update";
@@ -431,32 +433,32 @@ const PREF_TYPES = new Map([
  */
 function makeResultGroups({ showSearchSuggestionsFirst }) {
   let rootGroup = {
     children: [
       // heuristic
       {
         maxResultCount: 1,
         children: [
-          { group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST },
-          { group: UrlbarUtils.RESULT_GROUP.HEURISTIC_EXTENSION },
-          { group: UrlbarUtils.RESULT_GROUP.HEURISTIC_SEARCH_TIP },
-          { group: UrlbarUtils.RESULT_GROUP.HEURISTIC_OMNIBOX },
-          { group: UrlbarUtils.RESULT_GROUP.HEURISTIC_ENGINE_ALIAS },
-          { group: UrlbarUtils.RESULT_GROUP.HEURISTIC_BOOKMARK_KEYWORD },
-          { group: UrlbarUtils.RESULT_GROUP.HEURISTIC_AUTOFILL },
-          { group: UrlbarUtils.RESULT_GROUP.HEURISTIC_PRELOADED },
-          { group: UrlbarUtils.RESULT_GROUP.HEURISTIC_TOKEN_ALIAS_ENGINE },
-          { group: UrlbarUtils.RESULT_GROUP.HEURISTIC_FALLBACK },
+          { group: lazy.UrlbarUtils.RESULT_GROUP.HEURISTIC_TEST },
+          { group: lazy.UrlbarUtils.RESULT_GROUP.HEURISTIC_EXTENSION },
+          { group: lazy.UrlbarUtils.RESULT_GROUP.HEURISTIC_SEARCH_TIP },
+          { group: lazy.UrlbarUtils.RESULT_GROUP.HEURISTIC_OMNIBOX },
+          { group: lazy.UrlbarUtils.RESULT_GROUP.HEURISTIC_ENGINE_ALIAS },
+          { group: lazy.UrlbarUtils.RESULT_GROUP.HEURISTIC_BOOKMARK_KEYWORD },
+          { group: lazy.UrlbarUtils.RESULT_GROUP.HEURISTIC_AUTOFILL },
+          { group: lazy.UrlbarUtils.RESULT_GROUP.HEURISTIC_PRELOADED },
+          { group: lazy.UrlbarUtils.RESULT_GROUP.HEURISTIC_TOKEN_ALIAS_ENGINE },
+          { group: lazy.UrlbarUtils.RESULT_GROUP.HEURISTIC_FALLBACK },
         ],
       },
       // extensions using the omnibox API
       {
-        group: UrlbarUtils.RESULT_GROUP.OMNIBOX,
-        availableSpan: UrlbarUtils.MAX_OMNIBOX_RESULT_COUNT - 1,
+        group: lazy.UrlbarUtils.RESULT_GROUP.OMNIBOX,
+        availableSpan: lazy.UrlbarUtils.MAX_OMNIBOX_RESULT_COUNT - 1,
       },
     ],
   };
 
   // Prepare the parent group for suggestions and general.
   let mainGroup = {
     flexChildren: true,
     children: [
@@ -465,62 +467,62 @@ function makeResultGroups({ showSearchSu
         children: [
           {
             flexChildren: true,
             children: [
               {
                 // If `maxHistoricalSearchSuggestions` == 0, the muxer forces
                 // `maxResultCount` to be zero and flex is ignored, per query.
                 flex: 2,
-                group: UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
+                group: lazy.UrlbarUtils.RESULT_GROUP.FORM_HISTORY,
               },
               {
                 flex: 4,
-                group: UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
+                group: lazy.UrlbarUtils.RESULT_GROUP.REMOTE_SUGGESTION,
               },
             ],
           },
           {
-            group: UrlbarUtils.RESULT_GROUP.TAIL_SUGGESTION,
+            group: lazy.UrlbarUtils.RESULT_GROUP.TAIL_SUGGESTION,
           },
         ],
       },
       // general
       {
-        group: UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
+        group: lazy.UrlbarUtils.RESULT_GROUP.GENERAL_PARENT,
         children: [
           {
             availableSpan: 3,
-            group: UrlbarUtils.RESULT_GROUP.INPUT_HISTORY,
+            group: lazy.UrlbarUtils.RESULT_GROUP.INPUT_HISTORY,
           },
           {
             flexChildren: true,
             children: [
               {
                 flex: 1,
-                group: UrlbarUtils.RESULT_GROUP.REMOTE_TAB,
+                group: lazy.UrlbarUtils.RESULT_GROUP.REMOTE_TAB,
               },
               {
                 flex: 2,
-                group: UrlbarUtils.RESULT_GROUP.GENERAL,
+                group: lazy.UrlbarUtils.RESULT_GROUP.GENERAL,
               },
               {
                 // We show relatively many about-page results because they're
                 // only added for queries starting with "about:".
                 flex: 2,
-                group: UrlbarUtils.RESULT_GROUP.ABOUT_PAGES,
+                group: lazy.UrlbarUtils.RESULT_GROUP.ABOUT_PAGES,
               },
               {
                 flex: 1,
-                group: UrlbarUtils.RESULT_GROUP.PRELOADED,
+                group: lazy.UrlbarUtils.RESULT_GROUP.PRELOADED,
               },
             ],
           },
           {
-            group: UrlbarUtils.RESULT_GROUP.INPUT_HISTORY,
+            group: lazy.UrlbarUtils.RESULT_GROUP.INPUT_HISTORY,
           },
         ],
       },
     ],
   };
   if (!showSearchSuggestionsFirst) {
     mainGroup.children.reverse();
   }
@@ -565,17 +567,17 @@ class Preferences {
     this._firefoxSuggestScenarioStartupPromise = new Promise(
       resolve => (this._resolveFirefoxSuggestScenarioStartupPromise = resolve)
     );
 
     // This is set to true when we update the Firefox Suggest scenario to
     // prevent re-entry due to pref observers.
     this._updatingFirefoxSuggestScenario = false;
 
-    NimbusFeatures.urlbar.onUpdate(() => this._onNimbusUpdate());
+    lazy.NimbusFeatures.urlbar.onUpdate(() => this._onNimbusUpdate());
   }
 
   /**
    * Returns the value for the preference with the given name.
    * For preferences in the "browser.urlbar."" branch, the passed-in name
    * should be relative to the branch. It's also possible to get prefs from the
    * PREF_OTHER_DEFAULTS Map, specifying their full name.
    *
@@ -688,18 +690,18 @@ class Preferences {
     try {
       this._updatingFirefoxSuggestScenario = true;
 
       // This is called early in startup by BrowserGlue, so make sure the user's
       // region and our Nimbus variables are initialized since the scenario may
       // depend on them. Also note that pref migrations may depend on the
       // scenario, and since each migration is performed only once, at startup,
       // prefs can end up wrong if their migrations use the wrong scenario.
-      await Region.init();
-      await NimbusFeatures.urlbar.ready();
+      await lazy.Region.init();
+      await lazy.NimbusFeatures.urlbar.ready();
       this._clearNimbusCache();
 
       this._updateFirefoxSuggestScenarioHelper(isStartup, testOverrides);
     } finally {
       this._updatingFirefoxSuggestScenario = false;
     }
 
     // Null check `_resolveFirefoxSuggestScenarioStartupPromise` since some
@@ -843,17 +845,17 @@ class Preferences {
   _getIntendedFirefoxSuggestScenario() {
     // If the user is in a Nimbus rollout, then Nimbus will define the scenario.
     // Otherwise the user may be in a "hardcoded" rollout depending on their
     // region and locale. If the user is not in any rollouts, then the scenario
     // is "history", which means no Firefox Suggest suggestions will appear.
     let scenario = this._nimbus.quickSuggestScenario;
     if (!scenario) {
       if (
-        Region.home == "US" &&
+        lazy.Region.home == "US" &&
         Services.locale.appLocaleAsBCP47.substring(0, 2) == "en"
       ) {
         // offline rollout for en locales in the US region
         scenario = "offline";
       } else {
         // no rollout
         scenario = "history";
       }
@@ -1291,17 +1293,17 @@ class Preferences {
       }
       this.__nimbus = null;
     }
     return nimbus || {};
   }
 
   get _nimbus() {
     if (!this.__nimbus) {
-      this.__nimbus = NimbusFeatures.urlbar.getAllVariables({
+      this.__nimbus = lazy.NimbusFeatures.urlbar.getAllVariables({
         defaultValues: NIMBUS_DEFAULTS,
       });
     }
     return this.__nimbus;
   }
 
   /**
    * Returns the raw value of the given preference straight from Services.prefs.
--- a/browser/components/urlbar/UrlbarProviderAboutPages.jsm
+++ b/browser/components/urlbar/UrlbarProviderAboutPages.jsm
@@ -8,21 +8,26 @@
  * This module exports a provider that offers about pages.
  */
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderAboutPages"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
-XPCOMUtils.defineLazyModuleGetters(this, {
+
+const { UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   AboutPagesUtils: "resource://gre/modules/AboutPagesUtils.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 /**
  * Class used to create the provider.
  */
 class ProviderAboutPages extends UrlbarProvider {
   /**
    * Unique name for the provider, used by the context to filter on providers.
@@ -57,22 +62,22 @@ class ProviderAboutPages extends UrlbarP
    * @param {UrlbarQueryContext} queryContext The query context object
    * @param {function} addCallback Callback invoked by the provider to add a new
    *        result. A UrlbarResult should be passed to it.
    * @note Extended classes should return a Promise resolved when the provider
    *       is done searching AND returning results.
    */
   startQuery(queryContext, addCallback) {
     let searchString = queryContext.trimmedSearchString.toLowerCase();
-    for (const aboutUrl of AboutPagesUtils.visibleAboutUrls) {
+    for (const aboutUrl of lazy.AboutPagesUtils.visibleAboutUrls) {
       if (aboutUrl.startsWith(searchString)) {
-        let result = new UrlbarResult(
+        let result = new lazy.UrlbarResult(
           UrlbarUtils.RESULT_TYPE.URL,
           UrlbarUtils.RESULT_SOURCE.HISTORY,
-          ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
+          ...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
             title: [aboutUrl, UrlbarUtils.HIGHLIGHT.TYPED],
             url: [aboutUrl, UrlbarUtils.HIGHLIGHT.TYPED],
             icon: UrlbarUtils.getIconForUrl(aboutUrl),
           })
         );
         addCallback(this, result);
       }
     }
--- a/browser/components/urlbar/UrlbarProviderAliasEngines.jsm
+++ b/browser/components/urlbar/UrlbarProviderAliasEngines.jsm
@@ -9,22 +9,27 @@
  * results.
  */
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderAliasEngines"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
-XPCOMUtils.defineLazyModuleGetters(this, {
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
+
+const { UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
   UrlbarSearchUtils: "resource:///modules/UrlbarSearchUtils.jsm",
   UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 /**
  * Class used to create the provider.
  */
 class ProviderAliasEngines extends UrlbarProvider {
   /**
    * Returns the name of this provider.
@@ -47,43 +52,43 @@ class ProviderAliasEngines extends Urlba
    * If this method returns false, the providers manager won't start a query
    * with this provider, to save on resources.
    * @param {UrlbarQueryContext} queryContext The query context object
    * @returns {boolean} Whether this provider should be invoked for the search.
    */
   isActive(queryContext) {
     return (
       (!queryContext.restrictSource ||
-        queryContext.restrictSource == UrlbarTokenizer.RESTRICT.SEARCH) &&
+        queryContext.restrictSource == lazy.UrlbarTokenizer.RESTRICT.SEARCH) &&
       !queryContext.searchMode &&
       queryContext.tokens.length
     );
   }
 
   /**
    * Starts querying.
    * @param {object} queryContext The query context object
    * @param {function} addCallback Callback invoked by the provider to add a new
    *        result.
    */
   async startQuery(queryContext, addCallback) {
     let instance = this.queryInstance;
     let alias = queryContext.tokens[0]?.value;
-    let engine = await UrlbarSearchUtils.engineForAlias(
+    let engine = await lazy.UrlbarSearchUtils.engineForAlias(
       alias,
       queryContext.searchString
     );
     if (!engine || instance != this.queryInstance) {
       return;
     }
     let query = UrlbarUtils.substringAfter(queryContext.searchString, alias);
-    let result = new UrlbarResult(
+    let result = new lazy.UrlbarResult(
       UrlbarUtils.RESULT_TYPE.SEARCH,
       UrlbarUtils.RESULT_SOURCE.SEARCH,
-      ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
+      ...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
         engine: engine.name,
         keyword: alias,
         query: query.trimStart(),
         icon: engine.iconURI?.spec,
       })
     );
     result.heuristic = true;
     addCallback(this, result);
--- a/browser/components/urlbar/UrlbarProviderAutofill.jsm
+++ b/browser/components/urlbar/UrlbarProviderAutofill.jsm
@@ -8,25 +8,30 @@
  * This module exports a provider that provides an autofill result.
  */
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderAutofill"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
-XPCOMUtils.defineLazyModuleGetters(this, {
+
+const { UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   AboutPagesUtils: "resource://gre/modules/AboutPagesUtils.jsm",
   PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
   UrlbarSearchUtils: "resource:///modules/UrlbarSearchUtils.jsm",
   UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 // AutoComplete query type constants.
 // Describes the various types of queries that we can process rows for.
 const QUERYTYPE = {
   AUTOFILL_ORIGIN: 1,
   AUTOFILL_URL: 2,
   AUTOFILL_ADAPTIVE: 3,
@@ -294,17 +299,17 @@ class ProviderAutofill extends UrlbarPro
 
     // This is usually reset on canceling or completing the query, but since we
     // query in isActive, it may not have been canceled by the previous call.
     // It is an object with values { result: UrlbarResult, instance: Query }.
     // See the documentation for _getAutofillData for more information.
     this._autofillData = null;
 
     // First of all, check for the autoFill pref.
-    if (!UrlbarPrefs.get("autoFill")) {
+    if (!lazy.UrlbarPrefs.get("autoFill")) {
       return false;
     }
 
     if (!queryContext.allowAutofill) {
       return false;
     }
 
     if (queryContext.tokens.length != 1) {
@@ -324,33 +329,33 @@ class ProviderAutofill extends UrlbarPro
     ) {
       return false;
     }
 
     // Autofill doesn't search tags or titles
     if (
       queryContext.tokens.some(
         t =>
-          t.type == UrlbarTokenizer.TYPE.RESTRICT_TAG ||
-          t.type == UrlbarTokenizer.TYPE.RESTRICT_TITLE
+          t.type == lazy.UrlbarTokenizer.TYPE.RESTRICT_TAG ||
+          t.type == lazy.UrlbarTokenizer.TYPE.RESTRICT_TITLE
       )
     ) {
       return false;
     }
 
     [this._strippedPrefix, this._searchString] = UrlbarUtils.stripURLPrefix(
       queryContext.searchString
     );
     this._strippedPrefix = this._strippedPrefix.toLowerCase();
 
     // Don't try to autofill if the search term includes any whitespace.
     // This may confuse completeDefaultIndex cause the AUTOCOMPLETE_MATCH
     // tokenizer ends up trimming the search string and returning a value
     // that doesn't match it, or is even shorter.
-    if (UrlbarTokenizer.REGEXP_SPACES.test(queryContext.searchString)) {
+    if (lazy.UrlbarTokenizer.REGEXP_SPACES.test(queryContext.searchString)) {
       return false;
     }
 
     // Fetch autofill result now, rather than in startQuery. We do this so the
     // muxer doesn't have to wait on autofill for every query, since startQuery
     // will be guaranteed to return a result very quickly using this approach.
     // Bug 1651101 is filed to improve this behaviour.
     let result = await this._getAutofillResult(queryContext);
@@ -417,20 +422,20 @@ class ProviderAutofill extends UrlbarPro
    * Filters hosts by retaining only the ones over the autofill threshold, then
    * sorts them by their frecency, and extracts the one with the highest value.
    * @param {UrlbarQueryContext} queryContext The current queryContext.
    * @param {Array} hosts Array of host names to examine.
    * @returns {Promise} Resolved when the filtering is complete.
    * @resolves {string} The top matching host, or null if not found.
    */
   async getTopHostOverThreshold(queryContext, hosts) {
-    let db = await PlacesUtils.promiseLargeCacheDBConnection();
+    let db = await lazy.PlacesUtils.promiseLargeCacheDBConnection();
     let conditions = [];
     // Pay attention to the order of params, since they are not named.
-    let params = [UrlbarPrefs.get("autoFill.stddevMultiplier"), ...hosts];
+    let params = [lazy.UrlbarPrefs.get("autoFill.stddevMultiplier"), ...hosts];
     let sources = queryContext.sources;
     if (
       sources.includes(UrlbarUtils.RESULT_SOURCE.HISTORY) &&
       sources.includes(UrlbarUtils.RESULT_SOURCE.BOOKMARKS)
     ) {
       conditions.push(`(bookmarked OR ${SQL_AUTOFILL_FRECENCY_THRESHOLD})`);
     } else if (sources.includes(UrlbarUtils.RESULT_SOURCE.HISTORY)) {
       conditions.push(`visited AND ${SQL_AUTOFILL_FRECENCY_THRESHOLD}`);
@@ -489,17 +494,17 @@ class ProviderAutofill extends UrlbarPro
     // string because it may be an origin.
     let searchStr = this._searchString.endsWith("/")
       ? this._searchString.slice(0, -1)
       : this._searchString;
 
     let opts = {
       query_type: QUERYTYPE.AUTOFILL_ORIGIN,
       searchString: searchStr.toLowerCase(),
-      stddevMultiplier: UrlbarPrefs.get("autoFill.stddevMultiplier"),
+      stddevMultiplier: lazy.UrlbarPrefs.get("autoFill.stddevMultiplier"),
     };
     if (this._strippedPrefix) {
       opts.prefix = this._strippedPrefix;
     }
 
     if (
       queryContext.sources.includes(UrlbarUtils.RESULT_SOURCE.HISTORY) &&
       queryContext.sources.includes(UrlbarUtils.RESULT_SOURCE.BOOKMARKS)
@@ -641,17 +646,17 @@ class ProviderAutofill extends UrlbarPro
     } else {
       selectTitle = "matched.title";
       joinBookmarks = "";
     }
 
     const params = {
       queryType: QUERYTYPE.AUTOFILL_ADAPTIVE,
       searchString: queryContext.searchString.toLowerCase(),
-      useCountThreshold: UrlbarPrefs.get(
+      useCountThreshold: lazy.UrlbarPrefs.get(
         "autoFillAdaptiveHistoryUseCountThreshold"
       ),
     };
 
     const query = `
       WITH matched(input, url, title, stripped_url, is_exact_match, id) AS (
         SELECT
           i.input AS input,
@@ -798,20 +803,20 @@ class ProviderAutofill extends UrlbarPro
       let [autofilled] = UrlbarUtils.stripPrefixAndTrim(finalCompleteValue, {
         stripHttp: true,
         trimEmptyQuery: true,
         trimSlash: !this._searchString.includes("/"),
       });
       title = [autofilled, UrlbarUtils.HIGHLIGHT.TYPED];
     }
 
-    let result = new UrlbarResult(
+    let result = new lazy.UrlbarResult(
       UrlbarUtils.RESULT_TYPE.URL,
       UrlbarUtils.RESULT_SOURCE.HISTORY,
-      ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
+      ...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
         title,
         url: [finalCompleteValue, UrlbarUtils.HIGHLIGHT.TYPED],
         icon: UrlbarUtils.getIconForUrl(finalCompleteValue),
       })
     );
     result.autofill = {
       adaptiveHistoryInput,
       value: autofilledValue,
@@ -847,27 +852,27 @@ class ProviderAutofill extends UrlbarPro
 
   _matchAboutPageForAutofill(queryContext) {
     // Check that the typed query is at least one character longer than the
     // about: prefix.
     if (this._strippedPrefix != "about:" || !this._searchString) {
       return null;
     }
 
-    for (const aboutUrl of AboutPagesUtils.visibleAboutUrls) {
+    for (const aboutUrl of lazy.AboutPagesUtils.visibleAboutUrls) {
       if (aboutUrl.startsWith(`about:${this._searchString.toLowerCase()}`)) {
         let [trimmedUrl] = UrlbarUtils.stripPrefixAndTrim(aboutUrl, {
           stripHttp: true,
           trimEmptyQuery: true,
           trimSlash: !this._searchString.includes("/"),
         });
-        let result = new UrlbarResult(
+        let result = new lazy.UrlbarResult(
           UrlbarUtils.RESULT_TYPE.URL,
           UrlbarUtils.RESULT_SOURCE.HISTORY,
-          ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
+          ...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
             title: [trimmedUrl, UrlbarUtils.HIGHLIGHT.TYPED],
             url: [aboutUrl, UrlbarUtils.HIGHLIGHT.TYPED],
             icon: UrlbarUtils.getIconForUrl(aboutUrl),
           })
         );
         let autofilledValue =
           queryContext.searchString +
           aboutUrl.substring(queryContext.searchString.length);
@@ -879,25 +884,25 @@ class ProviderAutofill extends UrlbarPro
         };
         return result;
       }
     }
     return null;
   }
 
   async _matchKnownUrl(queryContext) {
-    let conn = await PlacesUtils.promiseLargeCacheDBConnection();
+    let conn = await lazy.PlacesUtils.promiseLargeCacheDBConnection();
     if (!conn) {
       return null;
     }
 
     // We try to autofill with adaptive history first.
     if (
-      UrlbarPrefs.get("autoFillAdaptiveHistoryEnabled") &&
-      UrlbarPrefs.get("autoFillAdaptiveHistoryMinCharsThreshold") <=
+      lazy.UrlbarPrefs.get("autoFillAdaptiveHistoryEnabled") &&
+      lazy.UrlbarPrefs.get("autoFillAdaptiveHistoryMinCharsThreshold") <=
         queryContext.searchString.length
     ) {
       const [query, params] = this._getAdaptiveHistoryQuery(queryContext);
       if (query) {
         const resultSet = await conn.executeCached(query, params);
         if (resultSet.length) {
           return this._processRow(resultSet[0], queryContext);
         }
@@ -913,17 +918,17 @@ class ProviderAutofill extends UrlbarPro
       return null;
     }
 
     // If search string looks like an origin, try to autofill against origins.
     // Otherwise treat it as a possible URL.  When the string has only one slash
     // at the end, we still treat it as an URL.
     let query, params;
     if (
-      UrlbarTokenizer.looksLikeOrigin(this._searchString, {
+      lazy.UrlbarTokenizer.looksLikeOrigin(this._searchString, {
         ignoreKnownDomains: true,
       })
     ) {
       [query, params] = this._getOriginQuery(queryContext);
     } else {
       [query, params] = this._getUrlQuery(queryContext);
     }
 
@@ -934,41 +939,45 @@ class ProviderAutofill extends UrlbarPro
         return this._processRow(rows[0], queryContext);
       }
     }
     return null;
   }
 
   async _matchSearchEngineDomain(queryContext) {
     if (
-      !UrlbarPrefs.get("autoFill.searchEngines") ||
+      !lazy.UrlbarPrefs.get("autoFill.searchEngines") ||
       !this._searchString.length
     ) {
       return null;
     }
 
     // enginesForDomainPrefix only matches against engine domains.
     // Remove an eventual trailing slash from the search string (without the
     // prefix) and check if the resulting string is worth matching.
     // Later, we'll verify that the found result matches the original
     // searchString and eventually discard it.
     let searchStr = this._searchString;
     if (searchStr.indexOf("/") == searchStr.length - 1) {
       searchStr = searchStr.slice(0, -1);
     }
     // If the search string looks more like a url than a domain, bail out.
     if (
-      !UrlbarTokenizer.looksLikeOrigin(searchStr, { ignoreKnownDomains: true })
+      !lazy.UrlbarTokenizer.looksLikeOrigin(searchStr, {
+        ignoreKnownDomains: true,
+      })
     ) {
       return null;
     }
 
     // Since we are autofilling, we can only pick one matching engine. Use the
     // first.
-    let engine = (await UrlbarSearchUtils.enginesForDomainPrefix(searchStr))[0];
+    let engine = (
+      await lazy.UrlbarSearchUtils.enginesForDomainPrefix(searchStr)
+    )[0];
     if (!engine) {
       return null;
     }
     let url = engine.searchForm;
     let domain = engine.getResultDomain();
     // Verify that the match we got is acceptable. Autofilling "example/" to
     // "example.com/" would not be good.
     if (
@@ -979,20 +988,20 @@ class ProviderAutofill extends UrlbarPro
     }
 
     // The value that's autofilled in the input is the prefix the user typed, if
     // any, plus the portion of the engine domain that the user typed.  Append a
     // trailing slash too, as is usual with autofill.
     let value =
       this._strippedPrefix + domain.substr(domain.indexOf(searchStr)) + "/";
 
-    let result = new UrlbarResult(
+    let result = new lazy.UrlbarResult(
       UrlbarUtils.RESULT_TYPE.SEARCH,
       UrlbarUtils.RESULT_SOURCE.SEARCH,
-      ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
+      ...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
         engine: [engine.name, UrlbarUtils.HIGHLIGHT.TYPED],
         icon: engine.iconURI?.spec,
       })
     );
     let autofilledValue =
       queryContext.searchString +
       value.substring(queryContext.searchString.length);
     result.autofill = {
--- a/browser/components/urlbar/UrlbarProviderBookmarkKeywords.jsm
+++ b/browser/components/urlbar/UrlbarProviderBookmarkKeywords.jsm
@@ -8,22 +8,27 @@
  * This module exports a provider that offers bookmarks with keywords.
  */
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderBookmarkKeywords"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
-XPCOMUtils.defineLazyModuleGetters(this, {
+
+const { UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   KeywordUtils: "resource://gre/modules/KeywordUtils.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
   UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 /**
  * Class used to create the provider.
  */
 class ProviderBookmarkKeywords extends UrlbarProvider {
   /**
    * Returns the name of this provider.
@@ -46,17 +51,18 @@ class ProviderBookmarkKeywords extends U
    * If this method returns false, the providers manager won't start a query
    * with this provider, to save on resources.
    * @param {UrlbarQueryContext} queryContext The query context object
    * @returns {boolean} Whether this provider should be invoked for the search.
    */
   isActive(queryContext) {
     return (
       (!queryContext.restrictSource ||
-        queryContext.restrictSource == UrlbarTokenizer.RESTRICT.BOOKMARK) &&
+        queryContext.restrictSource ==
+          lazy.UrlbarTokenizer.RESTRICT.BOOKMARK) &&
       !queryContext.searchMode &&
       queryContext.tokens.length
     );
   }
 
   /**
    * Starts querying.
    * @param {object} queryContext The query context object
@@ -65,17 +71,17 @@ class ProviderBookmarkKeywords extends U
    */
   async startQuery(queryContext, addCallback) {
     let keyword = queryContext.tokens[0]?.value;
 
     let searchString = UrlbarUtils.substringAfter(
       queryContext.searchString,
       keyword
     ).trim();
-    let { entry, url, postData } = await KeywordUtils.getBindableKeyword(
+    let { entry, url, postData } = await lazy.KeywordUtils.getBindableKeyword(
       keyword,
       searchString
     );
     if (!entry || !url) {
       return;
     }
 
     let title;
@@ -91,20 +97,20 @@ class ProviderBookmarkKeywords extends U
             .map(t => t.value)
             .join(" "),
         ]
       );
     } else {
       title = UrlbarUtils.unEscapeURIForUI(url);
     }
 
-    let result = new UrlbarResult(
+    let result = new lazy.UrlbarResult(
       UrlbarUtils.RESULT_TYPE.KEYWORD,
       UrlbarUtils.RESULT_SOURCE.BOOKMARKS,
-      ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
+      ...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
         title: [title, UrlbarUtils.HIGHLIGHT.TYPED],
         url: [url, UrlbarUtils.HIGHLIGHT.TYPED],
         keyword: [keyword, UrlbarUtils.HIGHLIGHT.TYPED],
         input: queryContext.searchString,
         postData,
         icon: UrlbarUtils.getIconForUrl(entry.url),
       })
     );
--- a/browser/components/urlbar/UrlbarProviderCalculator.jsm
+++ b/browser/components/urlbar/UrlbarProviderCalculator.jsm
@@ -5,26 +5,30 @@
 "use strict";
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderCalculator", "Calculator"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 
-XPCOMUtils.defineLazyModuleGetters(this, {
+const { UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
   UrlbarView: "resource:///modules/UrlbarView.jsm",
 });
 
 XPCOMUtils.defineLazyServiceGetter(
-  this,
+  lazy,
   "ClipboardHelper",
   "@mozilla.org/widget/clipboardhelper;1",
   "nsIClipboardHelper"
 );
 
 // This pref is relative to the `browser.urlbar` branch.
 const ENABLED_PREF = "suggest.calculator";
 
@@ -63,18 +67,18 @@ const MIN_EXPRESSION_LENGTH = 3;
 
 /**
  * A provider that returns a suggested url to the user based on what
  * they have currently typed so they can navigate directly.
  */
 class ProviderCalculator extends UrlbarProvider {
   constructor() {
     super();
-    UrlbarResult.addDynamicResultType(DYNAMIC_RESULT_TYPE);
-    UrlbarView.addDynamicViewTemplate(DYNAMIC_RESULT_TYPE, VIEW_TEMPLATE);
+    lazy.UrlbarResult.addDynamicResultType(DYNAMIC_RESULT_TYPE);
+    lazy.UrlbarView.addDynamicViewTemplate(DYNAMIC_RESULT_TYPE, VIEW_TEMPLATE);
   }
 
   /**
    * Returns the name of this provider.
    * @returns {string} the name of this provider.
    */
   get name() {
     return DYNAMIC_RESULT_TYPE;
@@ -93,17 +97,17 @@ class ProviderCalculator extends UrlbarP
    * with this provider, to save on resources.
    * @param {UrlbarQueryContext} queryContext The query context object
    * @returns {boolean} Whether this provider should be invoked for the search.
    */
   isActive(queryContext) {
     return (
       queryContext.trimmedSearchString &&
       !queryContext.searchMode &&
-      UrlbarPrefs.get(ENABLED_PREF)
+      lazy.UrlbarPrefs.get(ENABLED_PREF)
     );
   }
 
   /**
    * Starts querying.
    * @param {UrlbarQueryContext} queryContext The query context object
    * @param {function} addCallback Callback invoked by the provider to add a new
    *        result. A UrlbarResult should be passed to it.
@@ -114,17 +118,17 @@ class ProviderCalculator extends UrlbarP
     try {
       // Calculator will throw when given an invalid expression, therefore
       // addCallback will never be called.
       let postfix = Calculator.infix2postfix(queryContext.searchString);
       if (postfix.length < MIN_EXPRESSION_LENGTH) {
         return;
       }
       let value = Calculator.evaluatePostfix(postfix);
-      const result = new UrlbarResult(
+      const result = new lazy.UrlbarResult(
         UrlbarUtils.RESULT_TYPE.DYNAMIC,
         UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
         {
           value,
           input: queryContext.searchString,
           dynamicType: DYNAMIC_RESULT_TYPE,
         }
       );
@@ -150,17 +154,17 @@ class ProviderCalculator extends UrlbarP
         l10n: { id: "urlbar-result-action-copy-to-clipboard" },
       },
     };
 
     return viewUpdate;
   }
 
   async pickResult({ payload }) {
-    ClipboardHelper.copyString(payload.value);
+    lazy.ClipboardHelper.copyString(payload.value);
   }
 }
 
 /**
  * Base implementation of a basic calculator.
  */
 class BaseCalculator {
   // Holds the current symbols for calculation
--- a/browser/components/urlbar/UrlbarProviderExtension.jsm
+++ b/browser/components/urlbar/UrlbarProviderExtension.jsm
@@ -10,24 +10,28 @@
  */
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderExtension"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-XPCOMUtils.defineLazyModuleGetters(this, {
-  SkippableTimer: "resource:///modules/UrlbarUtils.jsm",
+
+const { SkippableTimer, UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarProvidersManager: "resource:///modules/UrlbarProvidersManager.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
   UrlbarSearchUtils: "resource:///modules/UrlbarSearchUtils.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 /**
  * The browser.urlbar extension API allows extensions to create their own urlbar
  * providers.  The results from extension providers are integrated into the
  * urlbar view just like the results from providers that are built into Firefox.
  *
  * This class is the interface between the provider-related parts of the
@@ -47,20 +51,20 @@ class UrlbarProviderExtension extends Ur
    * it doesn't exist.
    *
    * @param {string} name
    *   The provider name.
    * @returns {UrlbarProviderExtension}
    *   The provider.
    */
   static getOrCreate(name) {
-    let provider = UrlbarProvidersManager.getProvider(name);
+    let provider = lazy.UrlbarProvidersManager.getProvider(name);
     if (!provider) {
       provider = new UrlbarProviderExtension(name);
-      UrlbarProvidersManager.registerProvider(provider);
+      lazy.UrlbarProvidersManager.registerProvider(provider);
     }
     return provider;
   }
 
   /**
    * Constructor.
    *
    * @param {string} name
@@ -150,17 +154,17 @@ class UrlbarProviderExtension extends Ur
    *   The function that will be called when the event is fired.
    */
   setEventListener(eventName, listener) {
     if (listener) {
       this._eventListeners.set(eventName, listener);
     } else {
       this._eventListeners.delete(eventName);
       if (!this._eventListeners.size) {
-        UrlbarProvidersManager.unregisterProvider(this);
+        lazy.UrlbarProvidersManager.unregisterProvider(this);
       }
     }
   }
 
   /**
    * This method is called by the providers manager before a query starts to
    * update each extension provider's behavior.  It fires the behaviorRequested
    * event.
@@ -286,17 +290,17 @@ class UrlbarProviderExtension extends Ur
       this.logger.error(error);
       return undefined;
     }
     if (result.catch) {
       // The result is a promise, so wait for it to be resolved.  Set up a timer
       // so that we're not stuck waiting forever.
       let timer = new SkippableTimer({
         name: "UrlbarProviderExtension notification timer",
-        time: UrlbarPrefs.get("extension.timeout"),
+        time: lazy.UrlbarPrefs.get("extension.timeout"),
         reportErrorOnTimeout: true,
         logger: this.logger,
       });
       result = await Promise.race([
         timer.promise,
         result.catch(ex => this.logger.error(ex)),
       ]);
       timer.cancel();
@@ -323,45 +327,47 @@ class UrlbarProviderExtension extends Ur
     // one domain can have many engines.
     if (extResult.type == "search") {
       let engine;
       if (extResult.payload.engine) {
         // Validate the engine name by looking it up.
         engine = Services.search.getEngineByName(extResult.payload.engine);
       } else if (extResult.payload.keyword) {
         // Look up the engine by its alias.
-        engine = await UrlbarSearchUtils.engineForAlias(
+        engine = await lazy.UrlbarSearchUtils.engineForAlias(
           extResult.payload.keyword
         );
       } else if (extResult.payload.url) {
         // Look up the engine by its domain.
         let host;
         try {
           host = new URL(extResult.payload.url).hostname;
         } catch (err) {}
         if (host) {
-          engine = (await UrlbarSearchUtils.enginesForDomainPrefix(host))[0];
+          engine = (
+            await lazy.UrlbarSearchUtils.enginesForDomainPrefix(host)
+          )[0];
         }
       }
       if (!engine) {
         // No engine found.
         throw new Error("Invalid or missing engine specified by extension");
       }
       extResult.payload.engine = engine.name;
     }
 
     let type = UrlbarProviderExtension.RESULT_TYPES[extResult.type];
     if (type == UrlbarUtils.RESULT_TYPE.TIP) {
       extResult.payload.type = extResult.payload.type || "extension";
     }
 
-    let result = new UrlbarResult(
+    let result = new lazy.UrlbarResult(
       UrlbarProviderExtension.RESULT_TYPES[extResult.type],
       UrlbarProviderExtension.SOURCE_TYPES[extResult.source],
-      ...UrlbarResult.payloadAndSimpleHighlights(
+      ...lazy.UrlbarResult.payloadAndSimpleHighlights(
         context.tokens,
         extResult.payload || {}
       )
     );
     if (extResult.heuristic && this.behavior == "restricting") {
       // The muxer chooses the final heuristic result by taking the first one
       // that claims to be the heuristic.  We don't want extensions to clobber
       // the default heuristic, so we allow this only if the provider is
--- a/browser/components/urlbar/UrlbarProviderHeuristicFallback.jsm
+++ b/browser/components/urlbar/UrlbarProviderHeuristicFallback.jsm
@@ -11,23 +11,28 @@
  */
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderHeuristicFallback"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-XPCOMUtils.defineLazyModuleGetters(this, {
+
+const { UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
   UrlbarSearchUtils: "resource:///modules/UrlbarSearchUtils.jsm",
   UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 /**
  * Class used to create the provider.
  */
 class ProviderHeuristicFallback extends UrlbarProvider {
   constructor() {
     super();
@@ -85,22 +90,22 @@ class ProviderHeuristicFallback extends 
       // Since we can't tell if this is a real URL and whether the user wants
       // to visit or search for it, we provide an alternative searchengine
       // match if the string looks like an alphanumeric origin or an e-mail.
       let str = queryContext.searchString;
       try {
         new URL(str);
       } catch (ex) {
         if (
-          UrlbarPrefs.get("keyword.enabled") &&
-          (UrlbarTokenizer.looksLikeOrigin(str, {
+          lazy.UrlbarPrefs.get("keyword.enabled") &&
+          (lazy.UrlbarTokenizer.looksLikeOrigin(str, {
             noIp: true,
             noPort: true,
           }) ||
-            UrlbarTokenizer.REGEXP_COMMON_EMAIL.test(str))
+            lazy.UrlbarTokenizer.REGEXP_COMMON_EMAIL.test(str))
         ) {
           let searchResult = this._engineSearchResult(queryContext);
           if (instance != this.queryInstance) {
             return;
           }
           addCallback(this, searchResult);
         }
       }
@@ -127,17 +132,17 @@ class ProviderHeuristicFallback extends 
   // scheme isn't specificed.
   _matchUnknownUrl(queryContext) {
     // The user may have typed something like "word?" to run a search.  We
     // should not convert that to a URL.  We should also never convert actual
     // URLs into URL results when search mode is active or a search mode
     // restriction token was typed.
     if (
       queryContext.restrictSource == UrlbarUtils.RESULT_SOURCE.SEARCH ||
-      UrlbarTokenizer.SEARCH_MODE_RESTRICT.has(
+      lazy.UrlbarTokenizer.SEARCH_MODE_RESTRICT.has(
         queryContext.restrictToken?.value
       ) ||
       queryContext.searchMode
     ) {
       return null;
     }
 
     let unescapedSearchString = UrlbarUtils.unEscapeURIForUI(
@@ -150,22 +155,22 @@ class ProviderHeuristicFallback extends 
       return null;
     }
 
     let searchUrl = queryContext.trimmedSearchString;
 
     if (queryContext.fixupError) {
       if (
         queryContext.fixupError == Cr.NS_ERROR_MALFORMED_URI &&
-        !UrlbarPrefs.get("keyword.enabled")
+        !lazy.UrlbarPrefs.get("keyword.enabled")
       ) {
-        let result = new UrlbarResult(
+        let result = new lazy.UrlbarResult(
           UrlbarUtils.RESULT_TYPE.URL,
           UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
-          ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
+          ...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
             title: [searchUrl, UrlbarUtils.HIGHLIGHT.NONE],
             url: [searchUrl, UrlbarUtils.HIGHLIGHT.NONE],
           })
         );
         result.heuristic = true;
         return result;
       }
 
@@ -210,36 +215,36 @@ class ProviderHeuristicFallback extends 
     if (hostExpected && (searchUrl.endsWith("/") || uri.pathname.length > 1)) {
       // Look for an icon with the entire URL except for the pathname, including
       // scheme, usernames, passwords, hostname, and port.
       let pathIndex = uri.toString().lastIndexOf(uri.pathname);
       let prePath = uri.toString().slice(0, pathIndex);
       iconUri = `page-icon:${prePath}/`;
     }
 
-    let result = new UrlbarResult(
+    let result = new lazy.UrlbarResult(
       UrlbarUtils.RESULT_TYPE.URL,
       UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
-      ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
+      ...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
         title: [displayURL, UrlbarUtils.HIGHLIGHT.NONE],
         url: [escapedURL, UrlbarUtils.HIGHLIGHT.NONE],
         icon: iconUri,
       })
     );
     result.heuristic = true;
     return result;
   }
 
   _searchModeKeywordResult(queryContext) {
     if (!queryContext.tokens.length) {
       return null;
     }
 
     let firstToken = queryContext.tokens[0].value;
-    if (!UrlbarTokenizer.SEARCH_MODE_RESTRICT.has(firstToken)) {
+    if (!lazy.UrlbarTokenizer.SEARCH_MODE_RESTRICT.has(firstToken)) {
       return null;
     }
 
     // At this point, the search string starts with a token that can be
     // converted into search mode.
     // Now we need to determine what to do based on the remainder of the search
     // string.  If the remainder starts with a space, then we should enter
     // search mode, so we should continue below and create the result.
@@ -255,70 +260,70 @@ class ProviderHeuristicFallback extends 
     //
     // If we return null here and thereby do not enter search mode, then we'll
     // continue on to _engineSearchResult, and the heuristic will be a
     // default engine search result.
     let query = UrlbarUtils.substringAfter(
       queryContext.searchString,
       firstToken
     );
-    if (!UrlbarTokenizer.REGEXP_SPACES_START.test(query)) {
+    if (!lazy.UrlbarTokenizer.REGEXP_SPACES_START.test(query)) {
       return null;
     }
 
     let result;
     if (queryContext.restrictSource == UrlbarUtils.RESULT_SOURCE.SEARCH) {
       result = this._engineSearchResult(queryContext, firstToken);
     } else {
-      result = new UrlbarResult(
+      result = new lazy.UrlbarResult(
         UrlbarUtils.RESULT_TYPE.SEARCH,
         UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
-        ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
+        ...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
           query: [query.trimStart(), UrlbarUtils.HIGHLIGHT.NONE],
           keyword: [firstToken, UrlbarUtils.HIGHLIGHT.NONE],
         })
       );
     }
     result.heuristic = true;
     return result;
   }
 
   _engineSearchResult(queryContext, keyword = null) {
     let engine;
     if (queryContext.searchMode?.engineName) {
       engine = Services.search.getEngineByName(
         queryContext.searchMode.engineName
       );
     } else {
-      engine = UrlbarSearchUtils.getDefaultEngine(queryContext.isPrivate);
+      engine = lazy.UrlbarSearchUtils.getDefaultEngine(queryContext.isPrivate);
     }
 
     if (!engine) {
       return null;
     }
 
     // Strip a leading search restriction char, because we prepend it to text
     // when the search shortcut is used and it's not user typed. Don't strip
     // other restriction chars, so that it's possible to search for things
     // including one of those (e.g. "c#").
     let query = queryContext.searchString;
     if (
       queryContext.tokens[0] &&
-      queryContext.tokens[0].value === UrlbarTokenizer.RESTRICT.SEARCH
+      queryContext.tokens[0].value === lazy.UrlbarTokenizer.RESTRICT.SEARCH
     ) {
       query = UrlbarUtils.substringAfter(
         query,
         queryContext.tokens[0].value
       ).trim();
     }
 
-    return new UrlbarResult(
+    return new lazy.UrlbarResult(
       UrlbarUtils.RESULT_TYPE.SEARCH,
       UrlbarUtils.RESULT_SOURCE.SEARCH,
-      ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
+      ...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
         engine: [engine.name, UrlbarUtils.HIGHLIGHT.TYPED],
         icon: engine.iconURI?.spec,
         query: [query, UrlbarUtils.HIGHLIGHT.NONE],
         keyword: keyword ? [keyword, UrlbarUtils.HIGHLIGHT.NONE] : undefined,
       })
     );
   }
 }
--- a/browser/components/urlbar/UrlbarProviderInputHistory.jsm
+++ b/browser/components/urlbar/UrlbarProviderInputHistory.jsm
@@ -11,23 +11,28 @@
  * string.
  */
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderInputHistory"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
-XPCOMUtils.defineLazyModuleGetters(this, {
+
+const { UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarProviderOpenTabs: "resource:///modules/UrlbarProviderOpenTabs.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 // Sqlite result row index constants.
 const QUERYINDEX = {
   URL: 0,
   TITLE: 1,
   BOOKMARKED: 2,
   BOOKMARKTITLE: 3,
@@ -94,35 +99,35 @@ class ProviderInputHistory extends Urlba
    * Whether this provider should be invoked for the given context.
    * If this method returns false, the providers manager won't start a query
    * with this provider, to save on resources.
    * @param {UrlbarQueryContext} queryContext The query context object
    * @returns {boolean} Whether this provider should be invoked for the search.
    */
   isActive(queryContext) {
     return (
-      (UrlbarPrefs.get("suggest.history") ||
-        UrlbarPrefs.get("suggest.bookmark") ||
-        UrlbarPrefs.get("suggest.openpage")) &&
+      (lazy.UrlbarPrefs.get("suggest.history") ||
+        lazy.UrlbarPrefs.get("suggest.bookmark") ||
+        lazy.UrlbarPrefs.get("suggest.openpage")) &&
       !queryContext.searchMode
     );
   }
 
   /**
    * Starts querying.
    * @param {UrlbarQueryContext} queryContext The query context object
    * @param {function} addCallback Callback invoked by the provider to add a new
    *        result. A UrlbarResult should be passed to it.
    * @note Extended classes should return a Promise resolved when the provider
    *       is done searching AND returning results.
    */
   async startQuery(queryContext, addCallback) {
     let instance = this.queryInstance;
 
-    let conn = await PlacesUtils.promiseLargeCacheDBConnection();
+    let conn = await lazy.PlacesUtils.promiseLargeCacheDBConnection();
     if (instance != this.queryInstance) {
       return;
     }
 
     let [query, params] = this._getAdaptiveQuery(queryContext);
     let rows = await conn.executeCached(query, params);
     if (instance != this.queryInstance) {
       return;
@@ -134,59 +139,59 @@ class ProviderInputHistory extends Urlba
       const historyTitle = row.getResultByIndex(QUERYINDEX.TITLE) || "";
       const bookmarked = row.getResultByIndex(QUERYINDEX.BOOKMARKED);
       const bookmarkTitle = bookmarked
         ? row.getResultByIndex(QUERYINDEX.BOOKMARKTITLE)
         : null;
       const tags = row.getResultByIndex(QUERYINDEX.TAGS) || "";
 
       let resultTitle = historyTitle;
-      if (openPageCount > 0 && UrlbarPrefs.get("suggest.openpage")) {
+      if (openPageCount > 0 && lazy.UrlbarPrefs.get("suggest.openpage")) {
         if (url == queryContext.currentPage) {
           // Don't suggest switching to the current page.
           continue;
         }
-        let result = new UrlbarResult(
+        let result = new lazy.UrlbarResult(
           UrlbarUtils.RESULT_TYPE.TAB_SWITCH,
           UrlbarUtils.RESULT_SOURCE.TABS,
-          ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
+          ...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
             url: [url, UrlbarUtils.HIGHLIGHT.TYPED],
             title: [resultTitle, UrlbarUtils.HIGHLIGHT.TYPED],
             icon: UrlbarUtils.getIconForUrl(url),
           })
         );
         addCallback(this, result);
         continue;
       }
 
       let resultSource;
-      if (bookmarked && UrlbarPrefs.get("suggest.bookmark")) {
+      if (bookmarked && lazy.UrlbarPrefs.get("suggest.bookmark")) {
         resultSource = UrlbarUtils.RESULT_SOURCE.BOOKMARKS;
         resultTitle = bookmarkTitle || historyTitle;
-      } else if (UrlbarPrefs.get("suggest.history")) {
+      } else if (lazy.UrlbarPrefs.get("suggest.history")) {
         resultSource = UrlbarUtils.RESULT_SOURCE.HISTORY;
       } else {
         continue;
       }
 
       let resultTags = tags
         .split(",")
         .map(t => t.trim())
         .filter(tag => {
           let lowerCaseTag = tag.toLocaleLowerCase();
           return queryContext.tokens.some(token =>
             lowerCaseTag.includes(token.lowerCaseValue)
           );
         })
         .sort();
 
-      let result = new UrlbarResult(
+      let result = new lazy.UrlbarResult(
         UrlbarUtils.RESULT_TYPE.URL,
         resultSource,
-        ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
+        ...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
           url: [url, UrlbarUtils.HIGHLIGHT.TYPED],
           title: [resultTitle, UrlbarUtils.HIGHLIGHT.TYPED],
           tags: [resultTags, UrlbarUtils.HIGHLIGHT.TYPED],
           icon: UrlbarUtils.getIconForUrl(url),
         })
       );
 
       addCallback(this, result);
@@ -199,21 +204,21 @@ class ProviderInputHistory extends Urlba
    *   The current queryContext.
    * @returns {array} Contains the optimized query with which to search the
    *  database and an object containing the params to bound.
    */
   _getAdaptiveQuery(queryContext) {
     return [
       SQL_ADAPTIVE_QUERY,
       {
-        parent: PlacesUtils.tagsFolderId,
+        parent: lazy.PlacesUtils.tagsFolderId,
         search_string: queryContext.searchString.toLowerCase(),
         matchBehavior: Ci.mozIPlacesAutoComplete.MATCH_ANYWHERE,
-        searchBehavior: UrlbarPrefs.get("defaultBehavior"),
-        userContextId: UrlbarProviderOpenTabs.getUserContextIdForOpenPagesTable(
+        searchBehavior: lazy.UrlbarPrefs.get("defaultBehavior"),
+        userContextId: lazy.UrlbarProviderOpenTabs.getUserContextIdForOpenPagesTable(
           queryContext.userContextId,
           queryContext.isPrivate
         ),
         maxResults: queryContext.maxResults,
       },
     ];
   }
 }
--- a/browser/components/urlbar/UrlbarProviderInterventions.jsm
+++ b/browser/components/urlbar/UrlbarProviderInterventions.jsm
@@ -1,36 +1,39 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderInterventions", "QueryScorer"];
-var gGlobalScope = this;
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
-XPCOMUtils.defineLazyModuleGetters(this, {
+const { UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   AppUpdater: "resource:///modules/AppUpdater.jsm",
   BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
   NLP: "resource://gre/modules/NLP.jsm",
   PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
   ResetProfile: "resource://gre/modules/ResetProfile.jsm",
   Sanitizer: "resource:///modules/Sanitizer.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
   UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
-XPCOMUtils.defineLazyGetter(this, "appUpdater", () => new AppUpdater());
+XPCOMUtils.defineLazyGetter(lazy, "appUpdater", () => new lazy.AppUpdater());
 
 // The possible tips to show.  These names (except NONE) are used in the names
 // of keys in the `urlbar.tips` keyed scalar telemetry (see telemetry.rst).
 // Don't modify them unless you've considered that.  If you do modify them or
 // add new tips, then you are also adding new `urlbar.tips` keys and therefore
 // need an expanded data collection review.
 const TIPS = {
   NONE: "",
@@ -353,17 +356,17 @@ class QueryScorer {
       // node.  No match; the query has matched a phrase(s) up to this point,
       // but it doesn't have enough words.
       return minDistanceByDoc;
     }
 
     // Compare each word in the node to the current query word.
     let queryWord = queryWords[queryWordsIndex];
     for (let [childWord, child] of node.childrenByWord) {
-      let distance = NLP.levenshtein(queryWord, childWord);
+      let distance = lazy.NLP.levenshtein(queryWord, childWord);
       if (distance <= this._distanceThreshold) {
         // The word represented by this child node matches the current query
         // word.  Recurse into the child node.
         this._traverse({
           node: child,
           queryWords,
           queryWordsIndex: queryWordsIndex + 1,
           phraseDistance: phraseDistance + distance,
@@ -485,17 +488,19 @@ class ProviderInterventions extends Urlb
    * with this provider, to save on resources.
    * @param {UrlbarQueryContext} queryContext The query context object
    * @returns {boolean} Whether this provider should be invoked for the search.
    */
   isActive(queryContext) {
     if (
       !queryContext.searchString ||
       queryContext.searchString.length > UrlbarUtils.MAX_TEXT_LENGTH ||
-      UrlbarTokenizer.REGEXP_LIKE_PROTOCOL.test(queryContext.searchString) ||
+      lazy.UrlbarTokenizer.REGEXP_LIKE_PROTOCOL.test(
+        queryContext.searchString
+      ) ||
       !EN_LOCALE_MATCH.test(Services.locale.appLocaleAsBCP47) ||
       !Services.policies.isAllowed("urlbarinterventions")
     ) {
       return false;
     }
 
     this.currentTip = TIPS.NONE;
 
@@ -514,18 +519,18 @@ class ProviderInterventions extends Urlb
       }
     }
 
     // Determine the tip to show, if any. If there are multiple top-score docs,
     // prefer them in the following order.
     if (topDocIDs.has("update")) {
       this._setCurrentTipFromAppUpdaterStatus();
     } else if (topDocIDs.has("clear")) {
-      let window = BrowserWindowTracker.getTopWindow();
-      if (!PrivateBrowsingUtils.isWindowPrivate(window)) {
+      let window = lazy.BrowserWindowTracker.getTopWindow();
+      if (!lazy.PrivateBrowsingUtils.isWindowPrivate(window)) {
         this.currentTip = TIPS.CLEAR;
       }
     } else if (topDocIDs.has("refresh")) {
       // Note that the "update" case can set currentTip to TIPS.REFRESH too.
       this.currentTip = TIPS.REFRESH;
     }
 
     return (
@@ -546,37 +551,37 @@ class ProviderInterventions extends Urlb
     // (at least) so be careful not to do it the first time the urlbar is used.
     try {
       this.checkForBrowserUpdate();
     } catch (ex) {
       return;
     }
 
     // There are several update tips. Figure out which one to show.
-    switch (appUpdater.status) {
-      case AppUpdater.STATUS.READY_FOR_RESTART:
+    switch (lazy.appUpdater.status) {
+      case lazy.AppUpdater.STATUS.READY_FOR_RESTART:
         // Prompt the user to restart.
         this.currentTip = TIPS.UPDATE_RESTART;
         break;
-      case AppUpdater.STATUS.DOWNLOAD_AND_INSTALL:
+      case lazy.AppUpdater.STATUS.DOWNLOAD_AND_INSTALL:
         // There's an update available, but the user's pref says we should ask
         // them to download and apply it.
         this.currentTip = TIPS.UPDATE_ASK;
         break;
-      case AppUpdater.STATUS.NO_UPDATES_FOUND:
+      case lazy.AppUpdater.STATUS.NO_UPDATES_FOUND:
         // We show a special refresh tip when the browser is up to date.
         this.currentTip = TIPS.UPDATE_REFRESH;
         break;
-      case AppUpdater.STATUS.CHECKING:
+      case lazy.AppUpdater.STATUS.CHECKING:
         // This will be the case the first time we check.  See startQuery for
         // how this special tip is handled.
         this.currentTip = TIPS.UPDATE_CHECKING;
         break;
-      case AppUpdater.STATUS.NO_UPDATER:
-      case AppUpdater.STATUS.UPDATE_DISABLED_BY_POLICY:
+      case lazy.AppUpdater.STATUS.NO_UPDATER:
+      case lazy.AppUpdater.STATUS.UPDATE_DISABLED_BY_POLICY:
         // If the updater is disabled at build time or at runtime, either by
         // policy or because we're in a package, do not select any update tips.
         this.currentTip = TIPS.NONE;
         break;
       default:
         // Give up and ask the user to download the latest version from the
         // web. We default to this case when the update is still downloading
         // because an update doesn't actually occur if the user were to
@@ -611,21 +616,21 @@ class ProviderInterventions extends Urlb
     if (this.currentTip == TIPS.UPDATE_CHECKING) {
       // First check the status because it may have changed between the time
       // isActive was called and now.
       this._setCurrentTipFromAppUpdaterStatus();
       if (this.currentTip == TIPS.UPDATE_CHECKING) {
         // The updater is still checking, so wait for it to finish.
         await new Promise(resolve => {
           this._appUpdaterListener = () => {
-            appUpdater.removeListener(this._appUpdaterListener);
+            lazy.appUpdater.removeListener(this._appUpdaterListener);
             delete this._appUpdaterListener;
             resolve();
           };
-          appUpdater.addListener(this._appUpdaterListener);
+          lazy.appUpdater.addListener(this._appUpdaterListener);
         });
         if (instance != this.queryInstance) {
           // The query was canceled before the check finished.
           return;
         }
         // Finally, set the tip from the updater status.  The updater should no
         // longer be checking, but guard against it just in case by returning
         // early.
@@ -633,17 +638,17 @@ class ProviderInterventions extends Urlb
         if (this.currentTip == TIPS.UPDATE_CHECKING) {
           return;
         }
       }
     }
     // At this point, this.currentTip != TIPS.UPDATE_CHECKING because we
     // returned early above if it was.
 
-    let result = new UrlbarResult(
+    let result = new lazy.UrlbarResult(
       UrlbarUtils.RESULT_TYPE.TIP,
       UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
       {
         type: this.currentTip,
       }
     );
 
     result.suggestedIndex = 1;
@@ -663,17 +668,17 @@ class ProviderInterventions extends Urlb
    * Cancels a running query,
    * @param {UrlbarQueryContext} queryContext the query context object to cancel
    *        query for.
    */
   cancelQuery(queryContext) {
     // If we're waiting for appUpdater to finish its update check,
     // this._appUpdaterListener will be defined.  We can stop listening now.
     if (this._appUpdaterListener) {
-      appUpdater.removeListener(this._appUpdaterListener);
+      lazy.appUpdater.removeListener(this._appUpdaterListener);
       delete this._appUpdaterListener;
     }
   }
 
   /**
    * Called when a result from the provider without a URL is picked, but
    * currently only for tip results.  The provider should handle the pick.
    * @param {UrlbarResult} result
@@ -693,17 +698,17 @@ class ProviderInterventions extends Urlb
         break;
       case TIPS.UPDATE_ASK:
         installBrowserUpdateAndRestart();
         break;
       case TIPS.UPDATE_RESTART:
         restartBrowser();
         break;
       case TIPS.UPDATE_WEB:
-        let window = BrowserWindowTracker.getTopWindow();
+        let window = lazy.BrowserWindowTracker.getTopWindow();
         window.gBrowser.selectedTab = window.gBrowser.addWebTab(
           "https://www.mozilla.org/firefox/new/"
         );
         break;
     }
   }
 
   onEngagement(isPrivate, state, queryContext, details) {
@@ -724,71 +729,71 @@ class ProviderInterventions extends Urlb
    */
   checkForBrowserUpdate(force = false) {
     if (
       force ||
       !this._lastUpdateCheckTime ||
       Date.now() - this._lastUpdateCheckTime >= UPDATE_CHECK_PERIOD_MS
     ) {
       this._lastUpdateCheckTime = Date.now();
-      appUpdater.check();
+      lazy.appUpdater.check();
     }
   }
 
   /**
    * Resets the provider's app updater state by making a new app updater.  This
    * is intended to be used by tests.
    */
   resetAppUpdater() {
     // Reset only if the object has already been initialized.
-    if (!Object.getOwnPropertyDescriptor(gGlobalScope, "appUpdater").get) {
-      appUpdater = new AppUpdater();
+    if (!Object.getOwnPropertyDescriptor(lazy, "appUpdater").get) {
+      lazy.appUpdater = new lazy.AppUpdater();
     }
   }
 }
 
 var UrlbarProviderInterventions = new ProviderInterventions();
 
 /**
  * Tip callbacks follow.
  */
 
 function installBrowserUpdateAndRestart() {
-  if (appUpdater.status != AppUpdater.STATUS.DOWNLOAD_AND_INSTALL) {
+  if (lazy.appUpdater.status != lazy.AppUpdater.STATUS.DOWNLOAD_AND_INSTALL) {
     return Promise.resolve();
   }
   return new Promise(resolve => {
     let listener = () => {
       // Once we call startDownload, there are two possible end
       // states: DOWNLOAD_FAILED and READY_FOR_RESTART.
       if (
-        appUpdater.status != AppUpdater.STATUS.READY_FOR_RESTART &&
-        appUpdater.status != AppUpdater.STATUS.DOWNLOAD_FAILED
+        lazy.appUpdater.status != lazy.AppUpdater.STATUS.READY_FOR_RESTART &&
+        lazy.appUpdater.status != lazy.AppUpdater.STATUS.DOWNLOAD_FAILED
       ) {
         return;
       }
-      appUpdater.removeListener(listener);
-      if (appUpdater.status == AppUpdater.STATUS.READY_FOR_RESTART) {
+      lazy.appUpdater.removeListener(listener);
+      if (lazy.appUpdater.status == lazy.AppUpdater.STATUS.READY_FOR_RESTART) {
         restartBrowser();
       }
       resolve();
     };
-    appUpdater.addListener(listener);
-    appUpdater.startDownload();
+    lazy.appUpdater.addListener(listener);
+    lazy.appUpdater.startDownload();
   });
 }
 
 function openClearHistoryDialog() {
-  let window = BrowserWindowTracker.getTopWindow();
+  let window = lazy.BrowserWindowTracker.getTopWindow();
   // The behaviour of the Clear Recent History dialog in PBM does
   // not have the expected effect (bug 463607).
-  if (PrivateBrowsingUtils.isWindowPrivate(window)) {
+  if (lazy.PrivateBrowsingUtils.isWindowPrivate(window)) {
     return;
   }
-  Sanitizer.showUI(window);
+  lazy.Sanitizer.showUI(window);
 }
 
 function restartBrowser() {
   // Notify all windows that an application quit has been requested.
   let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(
     Ci.nsISupportsPRBool
   );
   Services.obs.notifyObservers(
@@ -806,14 +811,14 @@ function restartBrowser() {
   } else {
     Services.startup.quit(
       Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart
     );
   }
 }
 
 function resetBrowser() {
-  if (!ResetProfile.resetSupported()) {
+  if (!lazy.ResetProfile.resetSupported()) {
     return;
   }
-  let window = BrowserWindowTracker.getTopWindow();
-  ResetProfile.openConfirmationDialog(window);
+  let window = lazy.BrowserWindowTracker.getTopWindow();
+  lazy.ResetProfile.openConfirmationDialog(window);
 }
--- a/browser/components/urlbar/UrlbarProviderOmnibox.jsm
+++ b/browser/components/urlbar/UrlbarProviderOmnibox.jsm
@@ -9,22 +9,26 @@
  * extensions using the `omnibox` API.
  */
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderOmnibox"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
-XPCOMUtils.defineLazyModuleGetters(this, {
+
+const { SkippableTimer, UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   ExtensionSearchHandler: "resource://gre/modules/ExtensionSearchHandler.jsm",
-  SkippableTimer: "resource:///modules/UrlbarUtils.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 // After this time, we'll give up waiting for the extension to return matches.
 const MAXIMUM_ALLOWED_EXTENSION_TIME_MS = 3000;
 
 /**
  * This provider handles results returned by extensions using the WebExtensions
  * Omnibox API. If the user types a registered keyword, we send subsequent
@@ -60,33 +64,33 @@ class ProviderOmnibox extends UrlbarProv
    *   The query context object.
    * @returns {boolean}
    *   Whether this provider should be invoked for the search.
    */
   isActive(queryContext) {
     if (
       queryContext.tokens[0] &&
       queryContext.tokens[0].value.length &&
-      ExtensionSearchHandler.isKeywordRegistered(
+      lazy.ExtensionSearchHandler.isKeywordRegistered(
         queryContext.tokens[0].value
       ) &&
       UrlbarUtils.substringAfter(
         queryContext.searchString,
         queryContext.tokens[0].value
       )
     ) {
       return true;
     }
 
     // We need to handle cancellation here since isActive is called once per
     // query but cancelQuery can be called multiple times per query.
     // The frequent cancels can cause the extension's state to drift from the
     // provider's state.
-    if (ExtensionSearchHandler.hasActiveInputSession()) {
-      ExtensionSearchHandler.handleInputCancelled();
+    if (lazy.ExtensionSearchHandler.hasActiveInputSession()) {
+      lazy.ExtensionSearchHandler.handleInputCancelled();
     }
 
     return false;
   }
 
   /**
    * Gets the provider's priority.
    *
@@ -108,59 +112,62 @@ class ProviderOmnibox extends UrlbarProv
    * @param {function} addCallback
    *   The callback invoked by this method to add each result.
    */
   async startQuery(queryContext, addCallback) {
     let instance = this.queryInstance;
 
     // Fetch heuristic result.
     let keyword = queryContext.tokens[0].value;
-    let description = ExtensionSearchHandler.getDescription(keyword);
-    let heuristicResult = new UrlbarResult(
+    let description = lazy.ExtensionSearchHandler.getDescription(keyword);
+    let heuristicResult = new lazy.UrlbarResult(
       UrlbarUtils.RESULT_TYPE.OMNIBOX,
       UrlbarUtils.RESULT_SOURCE.OTHER_NETWORK,
-      ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
+      ...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
         title: [description, UrlbarUtils.HIGHLIGHT.TYPED],
         content: [queryContext.searchString, UrlbarUtils.HIGHLIGHT.TYPED],
         keyword: [queryContext.tokens[0].value, UrlbarUtils.HIGHLIGHT.TYPED],
         icon: UrlbarUtils.ICON.EXTENSION,
       })
     );
     heuristicResult.heuristic = true;
     addCallback(this, heuristicResult);
 
     // Fetch non-heuristic results.
     let data = {
       keyword,
       text: queryContext.searchString,
       inPrivateWindow: queryContext.isPrivate,
     };
-    this._resultsPromise = ExtensionSearchHandler.handleSearch(
+    this._resultsPromise = lazy.ExtensionSearchHandler.handleSearch(
       data,
       suggestions => {
         if (instance != this.queryInstance) {
           return;
         }
         for (let suggestion of suggestions) {
           let content = `${queryContext.tokens[0].value} ${suggestion.content}`;
           if (content == heuristicResult.payload.content) {
             continue;
           }
-          let result = new UrlbarResult(
+          let result = new lazy.UrlbarResult(
             UrlbarUtils.RESULT_TYPE.OMNIBOX,
             UrlbarUtils.RESULT_SOURCE.OTHER_NETWORK,
-            ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
-              title: [suggestion.description, UrlbarUtils.HIGHLIGHT.TYPED],
-              content: [content, UrlbarUtils.HIGHLIGHT.TYPED],
-              keyword: [
-                queryContext.tokens[0].value,
-                UrlbarUtils.HIGHLIGHT.TYPED,
-              ],
-              icon: UrlbarUtils.ICON.EXTENSION,
-            })
+            ...lazy.UrlbarResult.payloadAndSimpleHighlights(
+              queryContext.tokens,
+              {
+                title: [suggestion.description, UrlbarUtils.HIGHLIGHT.TYPED],
+                content: [content, UrlbarUtils.HIGHLIGHT.TYPED],
+                keyword: [
+                  queryContext.tokens[0].value,
+                  UrlbarUtils.HIGHLIGHT.TYPED,
+                ],
+                icon: UrlbarUtils.ICON.EXTENSION,
+              }
+            )
           );
           addCallback(this, result);
         }
       }
     );
 
     // Since the extension has no way to signal when it's done pushing results,
     // we add a timer racing with the addition.
--- a/browser/components/urlbar/UrlbarProviderOpenTabs.jsm
+++ b/browser/components/urlbar/UrlbarProviderOpenTabs.jsm
@@ -9,22 +9,27 @@
  * It is also used to register and unregister open tabs.
  */
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderOpenTabs"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
-XPCOMUtils.defineLazyModuleGetters(this, {
+
+const { UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarProvidersManager: "resource:///modules/UrlbarProvidersManager.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 const PRIVATE_USER_CONTEXT_ID = -1;
 
 /**
  * Class used to create the provider.
  */
 class UrlbarProviderOpenTabs extends UrlbarProvider {
@@ -96,17 +101,17 @@ class UrlbarProviderOpenTabs extends Url
   static getUserContextIdForOpenPagesTable(userContextId, isInPrivateWindow) {
     return isInPrivateWindow ? PRIVATE_USER_CONTEXT_ID : userContextId;
   }
 
   /**
    * Copy over cached open tabs to the memory table once the Urlbar
    * connection has been initialized.
    */
-  static promiseDBPopulated = PlacesUtils.largeCacheDBConnDeferred.promise.then(
+  static promiseDBPopulated = lazy.PlacesUtils.largeCacheDBConnDeferred.promise.then(
     async () => {
       // Must be set before populating.
       UrlbarProviderOpenTabs.memoryTableInitialized = true;
       // Populate the table with the current cached tabs.
       for (let [userContextId, urls] of UrlbarProviderOpenTabs._openTabs) {
         for (let url of urls) {
           await addToMemoryTable(url, userContextId).catch(Cu.reportError);
         }
@@ -164,32 +169,32 @@ class UrlbarProviderOpenTabs extends Url
    */
   async startQuery(queryContext, addCallback) {
     // Note: this is not actually expected to be used as an internal provider,
     // because normal history search will already coalesce with the open tabs
     // temp table to return proper frecency.
     // TODO:
     //  * properly search and handle tokens, this is just a mock for now.
     let instance = this.queryInstance;
-    let conn = await PlacesUtils.promiseLargeCacheDBConnection();
+    let conn = await lazy.PlacesUtils.promiseLargeCacheDBConnection();
     await UrlbarProviderOpenTabs.promiseDBPopulated;
     await conn.executeCached(
       `
       SELECT url, userContextId
       FROM moz_openpages_temp
     `,
       {},
       (row, cancel) => {
         if (instance != this.queryInstance) {
           cancel();
           return;
         }
         addCallback(
           this,
-          new UrlbarResult(
+          new lazy.UrlbarResult(
             UrlbarUtils.RESULT_TYPE.TAB_SWITCH,
             UrlbarUtils.RESULT_SOURCE.TABS,
             {
               url: row.getResultByName("url"),
               userContextId: row.getResultByName("userContextId"),
             }
           )
         );
@@ -203,18 +208,18 @@ class UrlbarProviderOpenTabs extends Url
  * @param {string} url Address of the page
  * @param {number} userContextId Containers user context id
  * @returns {Promise} resolved after the addition.
  */
 async function addToMemoryTable(url, userContextId) {
   if (!UrlbarProviderOpenTabs.memoryTableInitialized) {
     return;
   }
-  await UrlbarProvidersManager.runInCriticalSection(async () => {
-    let conn = await PlacesUtils.promiseLargeCacheDBConnection();
+  await lazy.UrlbarProvidersManager.runInCriticalSection(async () => {
+    let conn = await lazy.PlacesUtils.promiseLargeCacheDBConnection();
     await conn.executeCached(
       `
       INSERT OR REPLACE INTO moz_openpages_temp (url, userContextId, open_count)
       VALUES ( :url,
                 :userContextId,
                 IFNULL( ( SELECT open_count + 1
                           FROM moz_openpages_temp
                           WHERE url = :url
@@ -233,18 +238,18 @@ async function addToMemoryTable(url, use
  * @param {string} url Address of the page
  * @param {number} userContextId Containers user context id
  * @returns {Promise} resolved after the removal.
  */
 async function removeFromMemoryTable(url, userContextId) {
   if (!UrlbarProviderOpenTabs.memoryTableInitialized) {
     return;
   }
-  await UrlbarProvidersManager.runInCriticalSection(async () => {
-    let conn = await PlacesUtils.promiseLargeCacheDBConnection();
+  await lazy.UrlbarProvidersManager.runInCriticalSection(async () => {
+    let conn = await lazy.PlacesUtils.promiseLargeCacheDBConnection();
     await conn.executeCached(
       `
       UPDATE moz_openpages_temp
       SET open_count = open_count - 1
       WHERE url = :url
         AND userContextId = :userContextId
     `,
       { url, userContextId }
--- a/browser/components/urlbar/UrlbarProviderPlaces.jsm
+++ b/browser/components/urlbar/UrlbarProviderPlaces.jsm
@@ -98,52 +98,56 @@ const SQL_SWITCHTAB_QUERY = `SELECT :que
 
 // Getters
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
-XPCOMUtils.defineLazyModuleGetters(this, {
+const { UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   KeywordUtils: "resource://gre/modules/KeywordUtils.jsm",
   ObjectUtils: "resource://gre/modules/ObjectUtils.jsm",
   PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
   PromiseUtils: "resource://gre/modules/PromiseUtils.jsm",
   Sqlite: "resource://gre/modules/Sqlite.jsm",
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarProviderOpenTabs: "resource:///modules/UrlbarProviderOpenTabs.jsm",
   UrlbarProvidersManager: "resource:///modules/UrlbarProvidersManager.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
   UrlbarSearchUtils: "resource:///modules/UrlbarSearchUtils.jsm",
   UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 function setTimeout(callback, ms) {
   let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
   timer.initWithCallback(callback, ms, timer.TYPE_ONE_SHOT);
   return timer;
 }
 
 // Maps restriction character types to textual behaviors.
-XPCOMUtils.defineLazyGetter(this, "typeToBehaviorMap", () => {
+XPCOMUtils.defineLazyGetter(lazy, "typeToBehaviorMap", () => {
   return new Map([
-    [UrlbarTokenizer.TYPE.RESTRICT_HISTORY, "history"],
-    [UrlbarTokenizer.TYPE.RESTRICT_BOOKMARK, "bookmark"],
-    [UrlbarTokenizer.TYPE.RESTRICT_TAG, "tag"],
-    [UrlbarTokenizer.TYPE.RESTRICT_OPENPAGE, "openpage"],
-    [UrlbarTokenizer.TYPE.RESTRICT_SEARCH, "search"],
-    [UrlbarTokenizer.TYPE.RESTRICT_TITLE, "title"],
-    [UrlbarTokenizer.TYPE.RESTRICT_URL, "url"],
+    [lazy.UrlbarTokenizer.TYPE.RESTRICT_HISTORY, "history"],
+    [lazy.UrlbarTokenizer.TYPE.RESTRICT_BOOKMARK, "bookmark"],
+    [lazy.UrlbarTokenizer.TYPE.RESTRICT_TAG, "tag"],
+    [lazy.UrlbarTokenizer.TYPE.RESTRICT_OPENPAGE, "openpage"],
+    [lazy.UrlbarTokenizer.TYPE.RESTRICT_SEARCH, "search"],
+    [lazy.UrlbarTokenizer.TYPE.RESTRICT_TITLE, "title"],
+    [lazy.UrlbarTokenizer.TYPE.RESTRICT_URL, "url"],
   ]);
 });
 
-XPCOMUtils.defineLazyGetter(this, "sourceToBehaviorMap", () => {
+XPCOMUtils.defineLazyGetter(lazy, "sourceToBehaviorMap", () => {
   return new Map([
     [UrlbarUtils.RESULT_SOURCE.HISTORY, "history"],
     [UrlbarUtils.RESULT_SOURCE.BOOKMARKS, "bookmark"],
     [UrlbarUtils.RESULT_SOURCE.TABS, "openpage"],
     [UrlbarUtils.RESULT_SOURCE.SEARCH, "search"],
   ]);
 });
 
@@ -158,17 +162,17 @@ XPCOMUtils.defineLazyGetter(this, "sourc
  *
  * @param   {object} match
  *          The match object.
  * @returns {value} Some opaque key object.  Use ObjectUtils.deepEqual() to
  *          compare keys.
  */
 function makeKeyForMatch(match) {
   let key, prefix;
-  let action = PlacesUtils.parseActionUrl(match.value);
+  let action = lazy.PlacesUtils.parseActionUrl(match.value);
   if (!action) {
     [key, prefix] = UrlbarUtils.stripPrefixAndTrim(match.value, {
       stripHttp: true,
       stripHttps: true,
       stripWww: true,
       trimSlash: true,
       trimEmptyQuery: true,
       trimEmptyHash: true,
@@ -274,70 +278,70 @@ function convertLegacyMatches(context, m
 
 /**
  * Creates a new UrlbarResult from the provided data.
  * @param {array} tokens the search tokens.
  * @param {object} info includes properties from the legacy result.
  * @returns {object} an UrlbarResult
  */
 function makeUrlbarResult(tokens, info) {
-  let action = PlacesUtils.parseActionUrl(info.url);
+  let action = lazy.PlacesUtils.parseActionUrl(info.url);
   if (action) {
     switch (action.type) {
       case "searchengine": {
         if (action.params.isSearchHistory) {
           // Return a form history result.
-          return new UrlbarResult(
+          return new lazy.UrlbarResult(
             UrlbarUtils.RESULT_TYPE.SEARCH,
             UrlbarUtils.RESULT_SOURCE.HISTORY,
-            ...UrlbarResult.payloadAndSimpleHighlights(tokens, {
+            ...lazy.UrlbarResult.payloadAndSimpleHighlights(tokens, {
               engine: action.params.engineName,
               suggestion: [
                 action.params.searchSuggestion,
                 UrlbarUtils.HIGHLIGHT.SUGGESTED,
               ],
               lowerCaseSuggestion: action.params.searchSuggestion.toLocaleLowerCase(),
             })
           );
         }
 
-        return new UrlbarResult(
+        return new lazy.UrlbarResult(
           UrlbarUtils.RESULT_TYPE.SEARCH,
           UrlbarUtils.RESULT_SOURCE.SEARCH,
-          ...UrlbarResult.payloadAndSimpleHighlights(tokens, {
+          ...lazy.UrlbarResult.payloadAndSimpleHighlights(tokens, {
             engine: [action.params.engineName, UrlbarUtils.HIGHLIGHT.TYPED],
             suggestion: [
               action.params.searchSuggestion,
               UrlbarUtils.HIGHLIGHT.SUGGESTED,
             ],
             lowerCaseSuggestion: action.params.searchSuggestion?.toLocaleLowerCase(),
             keyword: action.params.alias,
             query: [
               action.params.searchQuery.trim(),
               UrlbarUtils.HIGHLIGHT.NONE,
             ],
             icon: info.icon,
           })
         );
       }
       case "switchtab":
-        return new UrlbarResult(
+        return new lazy.UrlbarResult(
           UrlbarUtils.RESULT_TYPE.TAB_SWITCH,
           UrlbarUtils.RESULT_SOURCE.TABS,
-          ...UrlbarResult.payloadAndSimpleHighlights(tokens, {
+          ...lazy.UrlbarResult.payloadAndSimpleHighlights(tokens, {
             url: [action.params.url, UrlbarUtils.HIGHLIGHT.TYPED],
             title: [info.comment, UrlbarUtils.HIGHLIGHT.TYPED],
             icon: info.icon,
           })
         );
       case "visiturl":
-        return new UrlbarResult(
+        return new lazy.UrlbarResult(
           UrlbarUtils.RESULT_TYPE.URL,
           UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
-          ...UrlbarResult.payloadAndSimpleHighlights(tokens, {
+          ...lazy.UrlbarResult.payloadAndSimpleHighlights(tokens, {
             title: [info.comment, UrlbarUtils.HIGHLIGHT.TYPED],
             url: [action.params.url, UrlbarUtils.HIGHLIGHT.TYPED],
             icon: info.icon,
           })
         );
       default:
         Cu.reportError(`Unexpected action type: ${action.type}`);
         return null;
@@ -379,20 +383,20 @@ function makeUrlbarResult(tokens, info) 
         let lowerCaseTag = tag.toLocaleLowerCase();
         return tokens.some(token =>
           lowerCaseTag.includes(token.lowerCaseValue)
         );
       })
       .sort();
   }
 
-  return new UrlbarResult(
+  return new lazy.UrlbarResult(
     UrlbarUtils.RESULT_TYPE.URL,
     source,
-    ...UrlbarResult.payloadAndSimpleHighlights(tokens, {
+    ...lazy.UrlbarResult.payloadAndSimpleHighlights(tokens, {
       url: [info.url, UrlbarUtils.HIGHLIGHT.TYPED],
       icon: info.icon,
       title: [comment, UrlbarUtils.HIGHLIGHT.TYPED],
       tags: [tags, UrlbarUtils.HIGHLIGHT.TYPED],
     })
   );
 }
 
@@ -419,51 +423,51 @@ function Search(queryContext, listener, 
   );
   let [prefix, suffix] = UrlbarUtils.stripURLPrefix(unescapedSearchString);
   this._searchString = suffix;
   this._strippedPrefix = prefix.toLowerCase();
 
   this._matchBehavior = Ci.mozIPlacesAutoComplete.MATCH_BOUNDARY;
   // Set the default behavior for this search.
   this._behavior = this._searchString
-    ? UrlbarPrefs.get("defaultBehavior")
+    ? lazy.UrlbarPrefs.get("defaultBehavior")
     : this._emptySearchDefaultBehavior;
 
   this._inPrivateWindow = queryContext.isPrivate;
   this._prohibitAutoFill = !queryContext.allowAutofill;
   this._maxResults = queryContext.maxResults;
   this._userContextId = queryContext.userContextId;
   this._currentPage = queryContext.currentPage;
   this._searchModeEngine = queryContext.searchMode?.engineName;
   this._searchMode = queryContext.searchMode;
   if (this._searchModeEngine) {
     // Filter Places results on host.
     let engine = Services.search.getEngineByName(this._searchModeEngine);
     this._filterOnHost = engine.getResultDomain();
   }
 
-  this._userContextId = UrlbarProviderOpenTabs.getUserContextIdForOpenPagesTable(
+  this._userContextId = lazy.UrlbarProviderOpenTabs.getUserContextIdForOpenPagesTable(
     this._userContextId,
     this._inPrivateWindow
   );
 
   // Use the original string here, not the stripped one, so the tokenizer can
   // properly recognize token types.
-  let { tokens } = UrlbarTokenizer.tokenize({
+  let { tokens } = lazy.UrlbarTokenizer.tokenize({
     searchString: unescapedSearchString,
     trimmedSearchString: unescapedSearchString.trim(),
   });
 
   // This allows to handle leading or trailing restriction characters specially.
   this._leadingRestrictionToken = null;
   if (tokens.length) {
     if (
-      UrlbarTokenizer.isRestrictionToken(tokens[0]) &&
+      lazy.UrlbarTokenizer.isRestrictionToken(tokens[0]) &&
       (tokens.length > 1 ||
-        tokens[0].type == UrlbarTokenizer.TYPE.RESTRICT_SEARCH)
+        tokens[0].type == lazy.UrlbarTokenizer.TYPE.RESTRICT_SEARCH)
     ) {
       this._leadingRestrictionToken = tokens[0].value;
     }
 
     // Check if the first token has a strippable prefix and remove it, but don't
     // create an empty token.
     if (prefix && tokens[0].value.length > prefix.length) {
       tokens[0].value = tokens[0].value.substring(prefix.length);
@@ -479,21 +483,21 @@ function Search(queryContext, listener, 
       : tokens;
 
   // The behavior can be set through:
   // 1. a specific restrictSource in the QueryContext
   // 2. typed restriction tokens
   if (
     queryContext &&
     queryContext.restrictSource &&
-    sourceToBehaviorMap.has(queryContext.restrictSource)
+    lazy.sourceToBehaviorMap.has(queryContext.restrictSource)
   ) {
     this._behavior = 0;
     this.setBehavior("restrict");
-    let behavior = sourceToBehaviorMap.get(queryContext.restrictSource);
+    let behavior = lazy.sourceToBehaviorMap.get(queryContext.restrictSource);
     this.setBehavior(behavior);
 
     // When we are in restrict mode, all the tokens are valid for searching, so
     // there is no _heuristicToken.
     this._heuristicToken = null;
   } else {
     // The heuristic token is the first filtered search token, but only when it's
     // actually the first thing in the search string.  If a prefix or restriction
@@ -504,17 +508,17 @@ function Search(queryContext, listener, 
       firstToken && this._trimmedOriginalSearchString.startsWith(firstToken)
         ? firstToken
         : null;
   }
 
   // Set the right JavaScript behavior based on our preference.  Note that the
   // preference is whether or not we should filter JavaScript, and the
   // behavior is if we should search it or not.
-  if (!UrlbarPrefs.get("filter.javascript")) {
+  if (!lazy.UrlbarPrefs.get("filter.javascript")) {
     this.setBehavior("javascript");
   }
 
   this._listener = listener;
   this._provider = provider;
   this._matches = [];
 
   // These are used to avoid adding duplicate entries to the results.
@@ -560,21 +564,21 @@ Search.prototype = {
    *        An array of search tokens.
    * @returns {array} A new, filtered array of tokens.
    */
   filterTokens(tokens) {
     let foundToken = false;
     // Set the proper behavior while filtering tokens.
     let filtered = [];
     for (let token of tokens) {
-      if (!UrlbarTokenizer.isRestrictionToken(token)) {
+      if (!lazy.UrlbarTokenizer.isRestrictionToken(token)) {
         filtered.push(token);
         continue;
       }
-      let behavior = typeToBehaviorMap.get(token.type);
+      let behavior = lazy.typeToBehaviorMap.get(token.type);
       if (!behavior) {
         throw new Error(`Unknown token type ${token.type}`);
       }
       // Don't use the suggest preferences if it is a token search and
       // set the restrict bit to 1 (to intersect the search results).
       if (!foundToken) {
         foundToken = true;
         // Do not take into account previous behavior (e.g.: history, bookmark)
@@ -625,28 +629,28 @@ Search.prototype = {
     // A search might be canceled before it starts.
     if (!this.pending) {
       return;
     }
 
     // Used by stop() to interrupt an eventual running statement.
     this.interrupt = () => {
       // Interrupt any ongoing statement to run the search sooner.
-      if (!UrlbarProvidersManager.interruptLevel) {
+      if (!lazy.UrlbarProvidersManager.interruptLevel) {
         conn.interrupt();
       }
     };
 
     // For any given search, we run these queries:
     // 1) open pages not supported by history (this._switchToTabQuery)
     // 2) query based on match behavior
 
     // If the query is simply "@" and we have tokenAliasEngines then return
     // early. UrlbarProviderTokenAliasEngines will add engine results.
-    let tokenAliasEngines = await UrlbarSearchUtils.tokenAliasEngines();
+    let tokenAliasEngines = await lazy.UrlbarSearchUtils.tokenAliasEngines();
     if (this._trimmedOriginalSearchString == "@" && tokenAliasEngines.length) {
       this._provider.finishSearch(true);
       return;
     }
 
     // Check if the first token is an action. If it is, we should set a flag
     // so we don't include it in our searches.
     this._firstTokenIsKeyword =
@@ -656,17 +660,17 @@ Search.prototype = {
     }
 
     if (this._trimmedOriginalSearchString) {
       // If the user typed the search restriction char or we're in
       // search-restriction mode, then we're done.
       // UrlbarProviderSearchSuggestions will handle suggestions, if any.
       let emptySearchRestriction =
         this._trimmedOriginalSearchString.length <= 3 &&
-        this._leadingRestrictionToken == UrlbarTokenizer.RESTRICT.SEARCH &&
+        this._leadingRestrictionToken == lazy.UrlbarTokenizer.RESTRICT.SEARCH &&
         /\s*\S?$/.test(this._trimmedOriginalSearchString);
       if (
         emptySearchRestriction ||
         (tokenAliasEngines &&
           this._trimmedOriginalSearchString.startsWith("@")) ||
         (this.hasBehavior("search") && this.hasBehavior("restrict"))
       ) {
         this._provider.finishSearch(true);
@@ -707,26 +711,26 @@ Search.prototype = {
     }
   },
 
   async _checkIfFirstTokenIsKeyword() {
     if (!this._heuristicToken) {
       return false;
     }
 
-    let aliasEngine = await UrlbarSearchUtils.engineForAlias(
+    let aliasEngine = await lazy.UrlbarSearchUtils.engineForAlias(
       this._heuristicToken,
       this._originalSearchString
     );
 
     if (aliasEngine) {
       return true;
     }
 
-    let { entry } = await KeywordUtils.getBindableKeyword(
+    let { entry } = await lazy.KeywordUtils.getBindableKeyword(
       this._heuristicToken,
       this._originalSearchString
     );
     if (entry) {
       this._filterOnHost = entry.url.host;
       return true;
     }
 
@@ -839,17 +843,17 @@ Search.prototype = {
       parseResult.engine,
       this._searchTokens.map(t => t.value).join(" ")
     );
 
     // We ignore termsParameterName when checking for a subset because we
     // already checked that the typed query is a subset of the search history
     // query above with this._searchTokens.every(...).
     if (
-      !UrlbarSearchUtils.serpsAreEquivalent(
+      !lazy.UrlbarSearchUtils.serpsAreEquivalent(
         historyUrl,
         generatedSuggestionUrl,
         [parseResult.termsParameterName]
       )
     ) {
       return false;
     }
 
@@ -882,20 +886,23 @@ Search.prototype = {
       return;
     }
 
     match.style = match.style || "favicon";
 
     // Restyle past searches, unless they are bookmarks or special results.
     if (
       match.style == "favicon" &&
-      (UrlbarPrefs.get("restyleSearches") || this._searchModeEngine)
+      (lazy.UrlbarPrefs.get("restyleSearches") || this._searchModeEngine)
     ) {
       let restyled = this._maybeRestyleSearchMatch(match);
-      if (restyled && UrlbarPrefs.get("maxHistoricalSearchSuggestions") == 0) {
+      if (
+        restyled &&
+        lazy.UrlbarPrefs.get("maxHistoricalSearchSuggestions") == 0
+      ) {
         // The user doesn't want search history.
         return;
       }
     }
 
     match.icon = match.icon || "";
     match.finalCompleteValue = match.finalCompleteValue || "";
 
@@ -928,25 +935,25 @@ Search.prototype = {
    *   True if the match should replace the result already at
    *   matchPosition.index.
    *
    */
   _getInsertIndexForMatch(match) {
     let [urlMapKey, prefix, action] = makeKeyForMatch(match);
     if (
       (match.placeId && this._usedPlaceIds.has(match.placeId)) ||
-      this._usedURLs.some(e => ObjectUtils.deepEqual(e.key, urlMapKey))
+      this._usedURLs.some(e => lazy.ObjectUtils.deepEqual(e.key, urlMapKey))
     ) {
       let isDupe = true;
       if (action && ["switchtab", "remotetab"].includes(action.type)) {
         // The new entry is a switch/remote tab entry, look for the duplicate
         // among current matches.
         for (let i = 0; i < this._usedURLs.length; ++i) {
           let { key: matchKey, action: matchAction } = this._usedURLs[i];
-          if (ObjectUtils.deepEqual(matchKey, urlMapKey)) {
+          if (lazy.ObjectUtils.deepEqual(matchKey, urlMapKey)) {
             isDupe = true;
             if (!matchAction || action.type == "switchtab") {
               this._usedURLs[i] = {
                 key: urlMapKey,
                 action,
                 type: match.type,
                 prefix,
                 comment: match.comment,
@@ -967,17 +974,17 @@ Search.prototype = {
           if (!this._usedURLs[i]) {
             // This is true when the result at [i] is a searchengine result.
             continue;
           }
 
           let { key: existingKey, prefix: existingPrefix } = this._usedURLs[i];
 
           let existingPrefixRank = UrlbarUtils.getPrefixRank(existingPrefix);
-          if (ObjectUtils.deepEqual(existingKey, urlMapKey)) {
+          if (lazy.ObjectUtils.deepEqual(existingKey, urlMapKey)) {
             isDupe = true;
 
             if (prefix == existingPrefix) {
               // The URLs are identical. Throw out the new result.
               break;
             }
 
             if (prefix.endsWith("www.") == existingPrefix.endsWith("www.")) {
@@ -1020,17 +1027,17 @@ Search.prototype = {
     // are faster too.
     if (match.placeId) {
       this._usedPlaceIds.add(match.placeId);
     }
 
     let index = 0;
     if (!this._groups) {
       this._groups = [];
-      this._makeGroups(UrlbarPrefs.get("resultGroups"), this._maxResults);
+      this._makeGroups(lazy.UrlbarPrefs.get("resultGroups"), this._maxResults);
     }
 
     let replace = 0;
     for (let group of this._groups) {
       // Move to the next group if the match type is incompatible, or if there
       // is no available space or if the frecency is below the threshold.
       if (match.type != group.type || !group.available) {
         index += group.count;
@@ -1173,17 +1180,17 @@ Search.prototype = {
     let conditions = [];
     if (this._filterOnHost) {
       conditions.push("h.rev_host = get_unreversed_host(:host || '.') || '.'");
       // When filtering on a host we are in some sort of site specific search,
       // thus we want a cleaner set of results, compared to a general search.
       // This means removing less interesting urls, like redirects or
       // non-bookmarked title-less pages.
 
-      if (UrlbarPrefs.get("restyleSearches") || this._searchModeEngine) {
+      if (lazy.UrlbarPrefs.get("restyleSearches") || this._searchModeEngine) {
         // If restyle is enabled, we want to filter out redirect targets,
         // because sources are urls built using search engines definitions that
         // we can reverse-parse.
         // In this case we can't filter on title-less pages because redirect
         // sources likely don't have a title and recognizing sources is costly.
         // Bug 468710 may help with this.
         conditions.push(`NOT EXISTS (
           WITH visits(type) AS (
@@ -1242,19 +1249,19 @@ Search.prototype = {
   },
 
   get _emptySearchDefaultBehavior() {
     // Further restrictions to apply for "empty searches" (searching for
     // "").  The empty behavior is typed history, if history is enabled.
     // Otherwise, it is bookmarks, if they are enabled. If both history and
     // bookmarks are disabled, it defaults to open pages.
     let val = Ci.mozIPlacesAutoComplete.BEHAVIOR_RESTRICT;
-    if (UrlbarPrefs.get("suggest.history")) {
+    if (lazy.UrlbarPrefs.get("suggest.history")) {
       val |= Ci.mozIPlacesAutoComplete.BEHAVIOR_HISTORY;
-    } else if (UrlbarPrefs.get("suggest.bookmark")) {
+    } else if (lazy.UrlbarPrefs.get("suggest.bookmark")) {
       val |= Ci.mozIPlacesAutoComplete.BEHAVIOR_BOOKMARK;
     } else {
       val |= Ci.mozIPlacesAutoComplete.BEHAVIOR_OPENPAGE;
     }
     return val;
   },
 
   /**
@@ -1275,17 +1282,17 @@ Search.prototype = {
    * preferences (accessed by this.hasBehavior).
    *
    * @returns {array}
    *   An array consisting of the correctly optimized query to search the
    *   database with and an object containing the params to bound.
    */
   get _searchQuery() {
     let params = {
-      parent: PlacesUtils.tagsFolderId,
+      parent: lazy.PlacesUtils.tagsFolderId,
       query_type: QUERYTYPE_FILTERED,
       matchBehavior: this._matchBehavior,
       searchBehavior: this._behavior,
       // We only want to search the tokens that we are left with - not the
       // original search string.
       searchString: this._keywordFilteredSearchString,
       userContextId: this._userContextId,
       // Limit the query to the the maximum number of desired results.
@@ -1390,20 +1397,20 @@ class ProviderPlaces extends UrlbarProvi
    *
    * @returns {Promise}
    * @resolves to the Sqlite database handle (according to Sqlite.jsm).
    * @rejects javascript exception.
    */
   getDatabaseHandle() {
     if (!this._promiseDatabase) {
       this._promiseDatabase = (async () => {
-        let conn = await PlacesUtils.promiseLargeCacheDBConnection();
+        let conn = await lazy.PlacesUtils.promiseLargeCacheDBConnection();
 
         // We don't catch exceptions here as it is too late to block shutdown.
-        Sqlite.shutdown.addBlocker("UrlbarProviderPlaces closing", () => {
+        lazy.Sqlite.shutdown.addBlocker("UrlbarProviderPlaces closing", () => {
           // Break a possible cycle through the
           // previous result, the controller and
           // ourselves.
           this._currentSearch = null;
         });
 
         return conn;
       })().catch(ex => {
@@ -1420,17 +1427,17 @@ class ProviderPlaces extends UrlbarProvi
    * with this provider, to save on resources.
    * @param {UrlbarQueryContext} queryContext The query context object
    * @returns {boolean} Whether this provider should be invoked for the search.
    */
   isActive(queryContext) {
     if (
       !queryContext.trimmedSearchString &&
       queryContext.searchMode?.engineName &&
-      UrlbarPrefs.get("update2.emptySearchBehavior") < 2
+      lazy.UrlbarPrefs.get("update2.emptySearchBehavior") < 2
     ) {
       return false;
     }
     return true;
   }
 
   /**
    * Starts querying.
@@ -1498,17 +1505,17 @@ class ProviderPlaces extends UrlbarProvi
     // _currentSearch, and on return the execution will continue here, after
     // notifyResult.
     // Thus, ensure that notifyResult is the last call in this method,
     // otherwise you might be touching the wrong search.
     search.notifyResult(false);
   }
 
   _startLegacyQuery(queryContext, callback) {
-    let deferred = PromiseUtils.defer();
+    let deferred = lazy.PromiseUtils.defer();
     let listener = (matches, searchOngoing) => {
       callback(matches);
       if (!searchOngoing) {
         deferred.resolve();
       }
     };
     this._startSearch(queryContext.searchString, listener, queryContext);
     this._deferred = deferred;
--- a/browser/components/urlbar/UrlbarProviderPreloadedSites.jsm
+++ b/browser/components/urlbar/UrlbarProviderPreloadedSites.jsm
@@ -12,23 +12,27 @@
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderPreloadedSites"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
-XPCOMUtils.defineLazyModuleGetters(this, {
+const { UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   ProfileAge: "resource://gre/modules/ProfileAge.jsm",
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
   UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 const MS_PER_DAY = 86400000; // 24 * 60 * 60 * 1000
 
 function PreloadedSite(url, title) {
   this.uri = Services.io.newURI(url);
   this.title = title;
   this._matchTitle = title.toLowerCase();
@@ -37,17 +41,17 @@ function PreloadedSite(url, title) {
 }
 
 /**
  * Storage object for Preloaded Sites.
  *   add(url, title): adds a site to storage
  *   populate(sites) : populates the  storage with array of [url,title]
  *   sites[]: resulting array of sites (PreloadedSite objects)
  */
-XPCOMUtils.defineLazyGetter(this, "PreloadedSiteStorage", () =>
+XPCOMUtils.defineLazyGetter(lazy, "PreloadedSiteStorage", () =>
   Object.seal({
     sites: [],
 
     add(url, title) {
       let site = new PreloadedSite(url, title);
       this.sites.push(site);
     },
 
@@ -55,32 +59,32 @@ XPCOMUtils.defineLazyGetter(this, "Prelo
       this.sites = [];
       for (let site of sites) {
         this.add(site[0], site[1]);
       }
     },
   })
 );
 
-XPCOMUtils.defineLazyGetter(this, "ProfileAgeCreatedPromise", async () => {
-  let times = await ProfileAge();
+XPCOMUtils.defineLazyGetter(lazy, "ProfileAgeCreatedPromise", async () => {
+  let times = await lazy.ProfileAge();
   return times.created;
 });
 
 /**
  * Class used to create the provider.
  */
 class ProviderPreloadedSites extends UrlbarProvider {
   constructor() {
     super();
 
-    if (UrlbarPrefs.get("usepreloadedtopurls.enabled")) {
+    if (lazy.UrlbarPrefs.get("usepreloadedtopurls.enabled")) {
       fetch("chrome://browser/content/urlbar/preloaded-top-urls.json")
         .then(response => response.json())
-        .then(sites => PreloadedSiteStorage.populate(sites))
+        .then(sites => lazy.PreloadedSiteStorage.populate(sites))
         .catch(ex => this.logger.error(ex));
     }
   }
 
   /**
    * Returns the name of this provider.
    * @returns {string} the name of this provider.
    */
@@ -112,22 +116,22 @@ class ProviderPreloadedSites extends Url
     // See the documentation for _getAutofillData for more information.
     this._autofillData = null;
 
     await this._checkPreloadedSitesExpiry();
     if (instance != this.queryInstance) {
       return false;
     }
 
-    if (!UrlbarPrefs.get("usepreloadedtopurls.enabled")) {
+    if (!lazy.UrlbarPrefs.get("usepreloadedtopurls.enabled")) {
       return false;
     }
 
     if (
-      !UrlbarPrefs.get("autoFill") ||
+      !lazy.UrlbarPrefs.get("autoFill") ||
       !queryContext.allowAutofill ||
       queryContext.tokens.length != 1
     ) {
       return false;
     }
 
     // Trying to autofill an extremely long string would be expensive, and
     // not particularly useful since the filled part falls out of screen anyway.
@@ -141,17 +145,17 @@ class ProviderPreloadedSites extends Url
     if (!this._searchString || !this._searchString.length) {
       return false;
     }
     this._lowerCaseSearchString = this._searchString.toLowerCase();
     this._strippedPrefix = this._strippedPrefix.toLowerCase();
 
     // As an optimization, don't try to autofill if the search term includes any
     // whitespace.
-    if (UrlbarTokenizer.REGEXP_SPACES.test(queryContext.searchString)) {
+    if (lazy.UrlbarTokenizer.REGEXP_SPACES.test(queryContext.searchString)) {
       return false;
     }
 
     // Fetch autofill result now, rather than in startQuery. We do this so the
     // muxer doesn't have to wait on autofill for every query, since startQuery
     // will be guaranteed to return a result very quickly using this approach.
     // Bug 1651101 is filed to improve this behaviour.
     let result = await this._getAutofillResult(queryContext);
@@ -178,27 +182,27 @@ class ProviderPreloadedSites extends Url
       this._autofillData.instance == this.queryInstance
     ) {
       this._autofillData.result.heuristic = true;
       addCallback(this, this._autofillData.result);
       this._autofillData = null;
     }
 
     // Now, add non-autofill preloaded sites.
-    for (let site of PreloadedSiteStorage.sites) {
+    for (let site of lazy.PreloadedSiteStorage.sites) {
       let url = site.uri.spec;
       if (
         (!this._strippedPrefix || url.startsWith(this._strippedPrefix)) &&
         (site.uri.host.includes(this._lowerCaseSearchString) ||
           site._matchTitle.includes(this._lowerCaseSearchString))
       ) {
-        let result = new UrlbarResult(
+        let result = new lazy.UrlbarResult(
           UrlbarUtils.RESULT_TYPE.URL,
           UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
-          ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
+          ...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
             title: [site.title, UrlbarUtils.HIGHLIGHT.TYPED],
             url: [url, UrlbarUtils.HIGHLIGHT.TYPED],
             icon: UrlbarUtils.getIconForUrl(url),
           })
         );
         addCallback(this, result);
       }
     }
@@ -217,21 +221,21 @@ class ProviderPreloadedSites extends Url
   /**
    * Populates the preloaded site cache with a list of sites. Intended for tests
    * only.
    * @param {array} list
    *   An array of URLs mapped to titles. See preloaded-top-urls.json for
    *   the format.
    */
   populatePreloadedSiteStorage(list) {
-    PreloadedSiteStorage.populate(list);
+    lazy.PreloadedSiteStorage.populate(list);
   }
 
   async _getAutofillResult(queryContext) {
-    let matchedSite = PreloadedSiteStorage.sites.find(site => {
+    let matchedSite = lazy.PreloadedSiteStorage.sites.find(site => {
       return (
         (!this._strippedPrefix ||
           site.uri.spec.startsWith(this._strippedPrefix)) &&
         (site.uri.host.startsWith(this._lowerCaseSearchString) ||
           site.uri.host.startsWith("www." + this._lowerCaseSearchString))
       );
     });
     if (!matchedSite) {
@@ -241,20 +245,20 @@ class ProviderPreloadedSites extends Url
     let url = matchedSite.uri.spec;
 
     let [title] = UrlbarUtils.stripPrefixAndTrim(url, {
       stripHttp: true,
       trimEmptyQuery: true,
       trimSlash: !this._searchString.includes("/"),
     });
 
-    let result = new UrlbarResult(
+    let result = new lazy.UrlbarResult(
       UrlbarUtils.RESULT_TYPE.URL,
       UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
-      ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
+      ...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
         title: [title, UrlbarUtils.HIGHLIGHT.TYPED],
         url: [url, UrlbarUtils.HIGHLIGHT.TYPED],
         icon: UrlbarUtils.getIconForUrl(url),
       })
     );
 
     let value = UrlbarUtils.stripURLPrefix(url)[1];
     value =
@@ -267,25 +271,25 @@ class ProviderPreloadedSites extends Url
       value: autofilledValue,
       selectionStart: queryContext.searchString.length,
       selectionEnd: autofilledValue.length,
     };
     return result;
   }
 
   async _checkPreloadedSitesExpiry() {
-    if (!UrlbarPrefs.get("usepreloadedtopurls.enabled")) {
+    if (!lazy.UrlbarPrefs.get("usepreloadedtopurls.enabled")) {
       return;
     }
-    let profileCreationDate = await ProfileAgeCreatedPromise;
+    let profileCreationDate = await lazy.ProfileAgeCreatedPromise;
     let daysSinceProfileCreation =
       (Date.now() - profileCreationDate) / MS_PER_DAY;
     if (
       daysSinceProfileCreation >
-      UrlbarPrefs.get("usepreloadedtopurls.expire_days")
+      lazy.UrlbarPrefs.get("usepreloadedtopurls.expire_days")
     ) {
       Services.prefs.setBoolPref(
         "browser.urlbar.usepreloadedtopurls.enabled",
         false
       );
     }
   }
 }
--- a/browser/components/urlbar/UrlbarProviderPrivateSearch.jsm
+++ b/browser/components/urlbar/UrlbarProviderPrivateSearch.jsm
@@ -9,23 +9,27 @@
  */
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderPrivateSearch"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-XPCOMUtils.defineLazyModuleGetters(this, {
-  SkippableTimer: "resource:///modules/UrlbarUtils.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
+
+const { SkippableTimer, UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
   UrlbarSearchUtils: "resource:///modules/UrlbarSearchUtils.jsm",
   UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 /**
  * Class used to create the provider.
  */
 class ProviderPrivateSearch extends UrlbarProvider {
   constructor() {
     super();
@@ -53,54 +57,54 @@ class ProviderPrivateSearch extends Urlb
    * Whether this provider should be invoked for the given context.
    * If this method returns false, the providers manager won't start a query
    * with this provider, to save on resources.
    * @param {UrlbarQueryContext} queryContext The query context object
    * @returns {boolean} Whether this provider should be invoked for the search.
    */
   isActive(queryContext) {
     return (
-      UrlbarSearchUtils.separatePrivateDefaultUIEnabled &&
+      lazy.UrlbarSearchUtils.separatePrivateDefaultUIEnabled &&
       !queryContext.isPrivate &&
       queryContext.tokens.length
     );
   }
 
   /**
    * Starts querying.
    * @param {object} queryContext The query context object
    * @param {function} addCallback Callback invoked by the provider to add a new
    *        match.
    * @returns {Promise} resolved when the query stops.
    */
   async startQuery(queryContext, addCallback) {
     let searchString = queryContext.trimmedSearchString;
     if (
       queryContext.tokens.some(
-        t => t.type == UrlbarTokenizer.TYPE.RESTRICT_SEARCH
+        t => t.type == lazy.UrlbarTokenizer.TYPE.RESTRICT_SEARCH
       )
     ) {
       if (queryContext.tokens.length == 1) {
         // There's only the restriction token, bail out.
         return;
       }
       // Remove the restriction char from the search string.
       searchString = queryContext.tokens
-        .filter(t => t.type != UrlbarTokenizer.TYPE.RESTRICT_SEARCH)
+        .filter(t => t.type != lazy.UrlbarTokenizer.TYPE.RESTRICT_SEARCH)
         .map(t => t.value)
         .join(" ");
     }
 
     let instance = this.queryInstance;
 
     let engine = queryContext.searchMode?.engineName
       ? Services.search.getEngineByName(queryContext.searchMode.engineName)
       : await Services.search.getDefaultPrivate();
     let isPrivateEngine =
-      UrlbarSearchUtils.separatePrivateDefault &&
+      lazy.UrlbarSearchUtils.separatePrivateDefault &&
       engine != (await Services.search.getDefault());
     this.logger.info(`isPrivateEngine: ${isPrivateEngine}`);
 
     // This is a delay added before returning results, to avoid flicker.
     // Our result must appear only when all results are searches, but if search
     // results arrive first, then the muxer would insert our result and then
     // immediately remove it when non-search results arrive.
     await new SkippableTimer({
@@ -108,20 +112,20 @@ class ProviderPrivateSearch extends Urlb
       time: 100,
       logger: this.logger,
     }).promise;
 
     if (instance != this.queryInstance) {
       return;
     }
 
-    let result = new UrlbarResult(
+    let result = new lazy.UrlbarResult(
       UrlbarUtils.RESULT_TYPE.SEARCH,
       UrlbarUtils.RESULT_SOURCE.SEARCH,
-      ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
+      ...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
         engine: [engine.name, UrlbarUtils.HIGHLIGHT.TYPED],
         query: [searchString, UrlbarUtils.HIGHLIGHT.NONE],
         icon: engine.iconURI?.spec,
         inPrivateWindow: true,
         isPrivateEngine,
       })
     );
     result.suggestedIndex = 1;
--- a/browser/components/urlbar/UrlbarProviderQuickActions.jsm
+++ b/browser/components/urlbar/UrlbarProviderQuickActions.jsm
@@ -5,27 +5,27 @@
 "use strict";
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderQuickActions"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { UrlbarProvider } = ChromeUtils.import(
+const { UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
   "resource:///modules/UrlbarUtils.jsm"
 );
 
-XPCOMUtils.defineLazyModuleGetters(this, {
+const lazy = {};
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   QuickActionsLoaderDefault:
     "resource:///modules/QuickActionsLoaderDefault.jsm",
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
   UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 // These prefs are relative to the `browser.urlbar` branch.
 const ENABLED_PREF = "quickactions.enabled";
 const DYNAMIC_TYPE_NAME = "quickactions";
 
 // When the urlbar is first focused and no search term has been
 // entered we show a limited number of results.
@@ -39,19 +39,19 @@ const SUGGESTED_INDEX = 1;
 
 /**
  * A provider that returns a suggested url to the user based on what
  * they have currently typed so they can navigate directly.
  */
 class ProviderQuickActions extends UrlbarProvider {
   constructor() {
     super();
-    UrlbarResult.addDynamicResultType(DYNAMIC_TYPE_NAME);
+    lazy.UrlbarResult.addDynamicResultType(DYNAMIC_TYPE_NAME);
     Services.tm.idleDispatchToMainThread(() =>
-      QuickActionsLoaderDefault.load()
+      lazy.QuickActionsLoaderDefault.load()
     );
   }
 
   /**
    * Returns the name of this provider.
    * @returns {string} the name of this provider.
    */
   get name() {
@@ -76,19 +76,19 @@ class ProviderQuickActions extends Urlba
    * Whether this provider should be invoked for the given context.
    * If this method returns false, the providers manager won't start a query
    * with this provider, to save on resources.
    * @param {UrlbarQueryContext} queryContext The query context object
    * @returns {boolean} Whether this provider should be invoked for the search.
    */
   isActive(queryContext) {
     return (
-      UrlbarPrefs.get(ENABLED_PREF) &&
+      lazy.UrlbarPrefs.get(ENABLED_PREF) &&
       (!queryContext.restrictSource ||
-        queryContext.restrictSource == UrlbarTokenizer.RESTRICT.ACTIONS) &&
+        queryContext.restrictSource == lazy.UrlbarTokenizer.RESTRICT.ACTIONS) &&
       !queryContext.searchMode
     );
   }
 
   /**
    * Starts querying.
    * @param {UrlbarQueryContext} queryContext The query context object
    * @param {function} addCallback Callback invoked by the provider to add a new
@@ -113,17 +113,17 @@ class ProviderQuickActions extends Urlba
     if (
       results.length > ACTIONS_SHOWN_FOCUS &&
       !queryContext.searchString &&
       !queryContext.searchMode
     ) {
       results.length = ACTIONS_SHOWN_FOCUS;
     }
 
-    const result = new UrlbarResult(
+    const result = new lazy.UrlbarResult(
       UrlbarUtils.RESULT_TYPE.DYNAMIC,
       UrlbarUtils.RESULT_SOURCE.ACTIONS,
       {
         results: results.map(key => ({ key })),
         dynamicType: DYNAMIC_TYPE_NAME,
       }
     );
     result.suggestedIndex = SUGGESTED_INDEX;
--- a/browser/components/urlbar/UrlbarProviderQuickSuggest.jsm
+++ b/browser/components/urlbar/UrlbarProviderQuickSuggest.jsm
@@ -6,31 +6,36 @@
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderQuickSuggest", "QUICK_SUGGEST_SOURCE"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
-XPCOMUtils.defineLazyModuleGetters(this, {
+const {
+  SkippableTimer,
+  TaskQueue,
+  UrlbarProvider,
+  UrlbarUtils,
+} = ChromeUtils.import("resource:///modules/UrlbarUtils.jsm");
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   AsyncShutdown: "resource://gre/modules/AsyncShutdown.jsm",
   clearInterval: "resource://gre/modules/Timer.jsm",
   CONTEXTUAL_SERVICES_PING_TYPES:
     "resource:///modules/PartnerLinkAttribution.jsm",
   NimbusFeatures: "resource://nimbus/ExperimentAPI.jsm",
   PartnerLinkAttribution: "resource:///modules/PartnerLinkAttribution.jsm",
   setInterval: "resource://gre/modules/Timer.jsm",
-  SkippableTimer: "resource:///modules/UrlbarUtils.jsm",
-  TaskQueue: "resource:///modules/UrlbarUtils.jsm",
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
   UrlbarQuickSuggest: "resource:///modules/UrlbarQuickSuggest.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 const TIMESTAMP_TEMPLATE = "%YYYYMMDDHH%";
 const TIMESTAMP_LENGTH = 10;
 const TIMESTAMP_REGEXP = /^\d{10}$/;
 
 const MERINO_PARAMS = {
   CLIENT_VARIANTS: "client_variants",
@@ -100,29 +105,31 @@ const QUICK_SUGGEST_SOURCE = {
 /**
  * A provider that returns a suggested url to the user based on what
  * they have currently typed so they can navigate directly.
  */
 class ProviderQuickSuggest extends UrlbarProvider {
   constructor(...args) {
     super(...args);
 
-    UrlbarQuickSuggest.init();
-    UrlbarQuickSuggest.on("config-set", () => this._validateImpressionStats());
+    lazy.UrlbarQuickSuggest.init();
+    lazy.UrlbarQuickSuggest.on("config-set", () =>
+      this._validateImpressionStats()
+    );
 
     this._updateFeatureState();
-    NimbusFeatures.urlbar.onUpdate(() => this._updateFeatureState());
+    lazy.NimbusFeatures.urlbar.onUpdate(() => this._updateFeatureState());
 
-    UrlbarPrefs.addObserver(this);
+    lazy.UrlbarPrefs.addObserver(this);
 
     // Periodically record impression counters reset telemetry.
     this._setImpressionCountersResetInterval();
 
     // On shutdown, record any final impression counters reset telemetry.
-    AsyncShutdown.profileChangeTeardown.addBlocker(
+    lazy.AsyncShutdown.profileChangeTeardown.addBlocker(
       "UrlbarProviderQuickSuggest: Record impression counters reset telemetry",
       () => this._resetElapsedImpressionCounters()
     );
   }
 
   /**
    * Returns the name of this provider.
    * @returns {string} the name of this provider.
@@ -201,20 +208,20 @@ class ProviderQuickSuggest extends Urlba
         queryContext.restrictSource != UrlbarUtils.RESULT_SOURCE.SEARCH)
     ) {
       return false;
     }
     return (
       queryContext.trimmedSearchString &&
       !queryContext.searchMode &&
       !queryContext.isPrivate &&
-      UrlbarPrefs.get("quickSuggestEnabled") &&
-      (UrlbarPrefs.get("suggest.quicksuggest.nonsponsored") ||
-        UrlbarPrefs.get("suggest.quicksuggest.sponsored") ||
-        UrlbarPrefs.get("quicksuggest.dataCollection.enabled"))
+      lazy.UrlbarPrefs.get("quickSuggestEnabled") &&
+      (lazy.UrlbarPrefs.get("suggest.quicksuggest.nonsponsored") ||
+        lazy.UrlbarPrefs.get("suggest.quicksuggest.sponsored") ||
+        lazy.UrlbarPrefs.get("quicksuggest.dataCollection.enabled"))
     );
   }
 
   /**
    * Starts querying.
    * @param {UrlbarQueryContext} queryContext The query context object
    * @param {function} addCallback Callback invoked by the provider to add a new
    *        result. A UrlbarResult should be passed to it.
@@ -226,24 +233,24 @@ class ProviderQuickSuggest extends Urlba
 
     // Trim only the start of the search string because a trailing space can
     // affect the suggestions.
     let searchString = queryContext.searchString.trimStart();
 
     // There are two sources for quick suggest: remote settings (from
     // `UrlbarQuickSuggest`) and Merino.
     let promises = [];
-    if (UrlbarPrefs.get("quickSuggestRemoteSettingsEnabled")) {
+    if (lazy.UrlbarPrefs.get("quickSuggestRemoteSettingsEnabled")) {
       promises.push(
         this._fetchRemoteSettingsSuggestions(queryContext, searchString)
       );
     }
     if (
-      UrlbarPrefs.get("merinoEnabled") &&
-      UrlbarPrefs.get("quicksuggest.dataCollection.enabled") &&
+      lazy.UrlbarPrefs.get("merinoEnabled") &&
+      lazy.UrlbarPrefs.get("quicksuggest.dataCollection.enabled") &&
       queryContext.allowRemoteResults()
     ) {
       promises.push(this._fetchMerinoSuggestions(queryContext, searchString));
     }
 
     // Wait for both sources to finish before adding a suggestion.
     let allSuggestions = await Promise.all(promises);
     if (instance != this.queryInstance) {
@@ -290,59 +297,62 @@ class ProviderQuickSuggest extends Urlba
       source: suggestion.source,
       requestId: suggestion.request_id,
     };
 
     // Determine if the suggestion itself is a best match.
     let isSuggestionBestMatch = false;
     if (typeof suggestion._test_is_best_match == "boolean") {
       isSuggestionBestMatch = suggestion._test_is_best_match;
-    } else if (UrlbarQuickSuggest.config.best_match) {
-      let { best_match } = UrlbarQuickSuggest.config;
+    } else if (lazy.UrlbarQuickSuggest.config.best_match) {
+      let { best_match } = lazy.UrlbarQuickSuggest.config;
       isSuggestionBestMatch =
         best_match.min_search_string_length <= searchString.length &&
         !best_match.blocked_suggestion_ids.includes(suggestion.block_id);
     }
 
     // Determine if the urlbar result should be a best match.
     let isResultBestMatch =
       isSuggestionBestMatch &&
-      UrlbarPrefs.get("bestMatchEnabled") &&
-      UrlbarPrefs.get("suggest.bestmatch");
+      lazy.UrlbarPrefs.get("bestMatchEnabled") &&
+      lazy.UrlbarPrefs.get("suggest.bestmatch");
     if (isResultBestMatch) {
       // Show the result as a best match. Best match titles don't include the
       // `full_keyword`, and the user's search string is highlighted.
       payload.title = [suggestion.title, UrlbarUtils.HIGHLIGHT.TYPED];
     } else {
       // Show the result as a usual quick suggest. Include the `full_keyword`
       // and highlight the parts that aren't in the search string.
       payload.title = suggestion.title;
       payload.qsSuggestion = [
         suggestion.full_keyword,
         UrlbarUtils.HIGHLIGHT.SUGGESTED,
       ];
     }
 
-    let result = new UrlbarResult(
+    let result = new lazy.UrlbarResult(
       UrlbarUtils.RESULT_TYPE.URL,
       UrlbarUtils.RESULT_SOURCE.SEARCH,
-      ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, payload)
+      ...lazy.UrlbarResult.payloadAndSimpleHighlights(
+        queryContext.tokens,
+        payload
+      )
     );
 
     if (isResultBestMatch) {
       result.isBestMatch = true;
       result.suggestedIndex = 1;
     } else if (
       !isNaN(suggestion.position) &&
-      UrlbarPrefs.get("quickSuggestAllowPositionInSuggestions")
+      lazy.UrlbarPrefs.get("quickSuggestAllowPositionInSuggestions")
     ) {
       result.suggestedIndex = suggestion.position;
     } else {
       result.isSuggestedIndexRelativeToGroup = true;
-      result.suggestedIndex = UrlbarPrefs.get(
+      result.suggestedIndex = lazy.UrlbarPrefs.get(
         suggestion.is_sponsored
           ? "quickSuggestSponsoredIndex"
           : "quickSuggestNonSponsoredIndex"
       );
     }
 
     addCallback(this, result);
 
@@ -356,28 +366,28 @@ class ProviderQuickSuggest extends Urlba
     //   following are true:
     //   * The best match feature is enabled (i.e., the user is in a treatment
     //     branch), and the user has not disabled best match
     //   * The best match feature is disabled (i.e., the user is in the control
     //     branch)
     // Else if the user is not in a modal experiment:
     //   Record the event
     if (
-      UrlbarPrefs.get("isBestMatchExperiment") ||
-      UrlbarPrefs.get("experimentType") === "best-match"
+      lazy.UrlbarPrefs.get("isBestMatchExperiment") ||
+      lazy.UrlbarPrefs.get("experimentType") === "best-match"
     ) {
       if (
         isSuggestionBestMatch &&
-        (!UrlbarPrefs.get("bestMatchEnabled") ||
-          UrlbarPrefs.get("suggest.bestmatch"))
+        (!lazy.UrlbarPrefs.get("bestMatchEnabled") ||
+          lazy.UrlbarPrefs.get("suggest.bestmatch"))
       ) {
-        UrlbarQuickSuggest.ensureExposureEventRecorded();
+        lazy.UrlbarQuickSuggest.ensureExposureEventRecorded();
       }
-    } else if (UrlbarPrefs.get("experimentType") !== "modal") {
-      UrlbarQuickSuggest.ensureExposureEventRecorded();
+    } else if (lazy.UrlbarPrefs.get("experimentType") !== "modal") {
+      lazy.UrlbarQuickSuggest.ensureExposureEventRecorded();
     }
   }
 
   /**
    * Called when the result's block button is picked. If the provider can block
    * the result, it should do so and return true. If the provider cannot block
    * the result, it should return false. The meaning of "blocked" depends on the
    * provider and the type of result.
@@ -386,18 +396,18 @@ class ProviderQuickSuggest extends Urlba
    * @param {UrlbarResult} result
    *   The result that should be blocked.
    * @returns {boolean}
    *   Whether the result was blocked.
    */
   blockResult(queryContext, result) {
     if (
       (!result.isBestMatch &&
-        !UrlbarPrefs.get("quickSuggestBlockingEnabled")) ||
-      (result.isBestMatch && !UrlbarPrefs.get("bestMatchBlockingEnabled"))
+        !lazy.UrlbarPrefs.get("quickSuggestBlockingEnabled")) ||
+      (result.isBestMatch && !lazy.UrlbarPrefs.get("bestMatchBlockingEnabled"))
     ) {
       this.logger.info("Blocking disabled, ignoring block");
       return false;
     }
 
     this.logger.info("Blocking result: " + JSON.stringify(result));
     this.blockSuggestion(result.payload.originalUrl);
     this._recordEngagementTelemetry(result, queryContext.isPrivate, "block");
@@ -415,17 +425,17 @@ class ProviderQuickSuggest extends Urlba
     await this._blockTaskQueue.queue(async () => {
       this.logger.info(`Blocking suggestion: ${originalUrl}`);
       let digest = await this._getDigest(originalUrl);
       this.logger.debug(`Got digest for '${originalUrl}': ${digest}`);
       this._blockedDigests.add(digest);
       let json = JSON.stringify([...this._blockedDigests]);
       this._updatingBlockedDigests = true;
       try {
-        UrlbarPrefs.set("quicksuggest.blockedDigests", json);
+        lazy.UrlbarPrefs.set("quicksuggest.blockedDigests", json);
       } finally {
         this._updatingBlockedDigests = false;
       }
       this.logger.debug(`All blocked suggestions: ${json}`);
     });
   }
 
   /**
@@ -451,17 +461,17 @@ class ProviderQuickSuggest extends Urlba
   /**
    * Unblocks all suggestions.
    */
   async clearBlockedSuggestions() {
     this.logger.debug(`Queueing clearBlockedSuggestions`);
     await this._blockTaskQueue.queue(() => {
       this.logger.info(`Clearing all blocked suggestions`);
       this._blockedDigests.clear();
-      UrlbarPrefs.clear("quicksuggest.blockedDigests");
+      lazy.UrlbarPrefs.clear("quicksuggest.blockedDigests");
     });
   }
 
   /**
    * Called when the user starts and ends an engagement with the urlbar.  For
    * details on parameters, see UrlbarProvider.onEngagement().
    *
    * @param {boolean} isPrivate
@@ -623,52 +633,52 @@ class ProviderQuickSuggest extends Urlba
       // be "quicksuggest" in that case. See this method's JSDoc for all
       // possible `selType` values.
       let is_clicked = selType == "quicksuggest";
       let payload = {
         match_type,
         // Always use lowercase to make the reporting consistent
         advertiser: result.payload.sponsoredAdvertiser.toLocaleLowerCase(),
         block_id: result.payload.sponsoredBlockId,
-        improve_suggest_experience_checked: UrlbarPrefs.get(
+        improve_suggest_experience_checked: lazy.UrlbarPrefs.get(
           "quicksuggest.dataCollection.enabled"
         ),
         position: telemetryResultIndex,
         request_id: result.payload.requestId,
       };
 
       // impression
-      PartnerLinkAttribution.sendContextualServicesPing(
+      lazy.PartnerLinkAttribution.sendContextualServicesPing(
         {
           ...payload,
           is_clicked,
           reporting_url: result.payload.sponsoredImpressionUrl,
         },
-        CONTEXTUAL_SERVICES_PING_TYPES.QS_IMPRESSION
+        lazy.CONTEXTUAL_SERVICES_PING_TYPES.QS_IMPRESSION
       );
 
       // click
       if (is_clicked) {
-        PartnerLinkAttribution.sendContextualServicesPing(
+        lazy.PartnerLinkAttribution.sendContextualServicesPing(
           {
             ...payload,
             reporting_url: result.payload.sponsoredClickUrl,
           },
-          CONTEXTUAL_SERVICES_PING_TYPES.QS_SELECTION
+          lazy.CONTEXTUAL_SERVICES_PING_TYPES.QS_SELECTION
         );
       }
 
       // block
       if (selType == "block") {
-        PartnerLinkAttribution.sendContextualServicesPing(
+        lazy.PartnerLinkAttribution.sendContextualServicesPing(
           {
             ...payload,
             iab_category: result.payload.sponsoredIabCategory,
           },
-          CONTEXTUAL_SERVICES_PING_TYPES.QS_BLOCK
+          lazy.CONTEXTUAL_SERVICES_PING_TYPES.QS_BLOCK
         );
       }
     }
   }
 
   /**
    * Called when a urlbar pref changes.
    *
@@ -689,39 +699,39 @@ class ProviderQuickSuggest extends Urlba
         if (!this._updatingImpressionStats) {
           this.logger.info(
             "browser.urlbar.quicksuggest.impressionCaps.stats changed"
           );
           this._loadImpressionStats();
         }
         break;
       case "quicksuggest.dataCollection.enabled":
-        if (!UrlbarPrefs.updatingFirefoxSuggestScenario) {
+        if (!lazy.UrlbarPrefs.updatingFirefoxSuggestScenario) {
           Services.telemetry.recordEvent(
             TELEMETRY_EVENT_CATEGORY,
             "data_collect_toggled",
-            UrlbarPrefs.get(pref) ? "enabled" : "disabled"
+            lazy.UrlbarPrefs.get(pref) ? "enabled" : "disabled"
           );
         }
         break;
       case "suggest.quicksuggest.nonsponsored":
-        if (!UrlbarPrefs.updatingFirefoxSuggestScenario) {
+        if (!lazy.UrlbarPrefs.updatingFirefoxSuggestScenario) {
           Services.telemetry.recordEvent(
             TELEMETRY_EVENT_CATEGORY,
             "enable_toggled",
-            UrlbarPrefs.get(pref) ? "enabled" : "disabled"
+            lazy.UrlbarPrefs.get(pref) ? "enabled" : "disabled"
           );
         }
         break;
       case "suggest.quicksuggest.sponsored":
-        if (!UrlbarPrefs.updatingFirefoxSuggestScenario) {
+        if (!lazy.UrlbarPrefs.updatingFirefoxSuggestScenario) {
           Services.telemetry.recordEvent(
             TELEMETRY_EVENT_CATEGORY,
             "sponsored_toggled",
-            UrlbarPrefs.get(pref) ? "enabled" : "disabled"
+            lazy.UrlbarPrefs.get(pref) ? "enabled" : "disabled"
           );
         }
         break;
     }
   }
 
   /**
    * Cancels the current query.
@@ -807,17 +817,17 @@ class ProviderQuickSuggest extends Urlba
    *   is returned.
    */
   async _fetchRemoteSettingsSuggestions(queryContext, searchString) {
     let instance = this.queryInstance;
 
     let suggestions;
     TelemetryStopwatch.start(TELEMETRY_REMOTE_SETTINGS_LATENCY, queryContext);
     try {
-      suggestions = await UrlbarQuickSuggest.query(searchString);
+      suggestions = await lazy.UrlbarQuickSuggest.query(searchString);
       TelemetryStopwatch.finish(
         TELEMETRY_REMOTE_SETTINGS_LATENCY,
         queryContext
       );
       if (instance != this.queryInstance) {
         return [];
       }
     } catch (error) {
@@ -858,17 +868,17 @@ class ProviderQuickSuggest extends Urlba
         time: this._merinoSessionTimeoutMs,
         logger: this.logger,
         callback: () => this._resetMerinoSessionID(),
       });
     }
 
     // Get the endpoint URL. It's empty by default when running tests so they
     // don't hit the network.
-    let endpointString = UrlbarPrefs.get("merino.endpointURL");
+    let endpointString = lazy.UrlbarPrefs.get("merino.endpointURL");
     if (!endpointString) {
       return null;
     }
     let url;
     try {
       url = new URL(endpointString);
     } catch (error) {
       this.logger.error("Could not make Merino endpoint URL: " + error);
@@ -876,43 +886,43 @@ class ProviderQuickSuggest extends Urlba
     }
     url.searchParams.set(MERINO_PARAMS.QUERY, searchString);
     url.searchParams.set(MERINO_PARAMS.SESSION_ID, this._merinoSessionID);
     url.searchParams.set(
       MERINO_PARAMS.SEQUENCE_NUMBER,
       this._merinoSequenceNumber
     );
 
-    let clientVariants = UrlbarPrefs.get("merino.clientVariants");
+    let clientVariants = lazy.UrlbarPrefs.get("merino.clientVariants");
     if (clientVariants) {
       url.searchParams.set(MERINO_PARAMS.CLIENT_VARIANTS, clientVariants);
     }
 
-    let providers = UrlbarPrefs.get("merino.providers");
+    let providers = lazy.UrlbarPrefs.get("merino.providers");
     if (providers) {
       url.searchParams.set(MERINO_PARAMS.PROVIDERS, providers);
     } else if (
-      !UrlbarPrefs.get("suggest.quicksuggest.nonsponsored") &&
-      !UrlbarPrefs.get("suggest.quicksuggest.sponsored")
+      !lazy.UrlbarPrefs.get("suggest.quicksuggest.nonsponsored") &&
+      !lazy.UrlbarPrefs.get("suggest.quicksuggest.sponsored")
     ) {
       // Data collection is enabled but suggestions are not. Set the providers
       // param to an empty string to tell Merino not to fetch any suggestions.
       url.searchParams.set(MERINO_PARAMS.PROVIDERS, "");
     }
 
     let responseHistogram = Services.telemetry.getHistogramById(
       TELEMETRY_MERINO_RESPONSE
     );
     let maybeRecordResponse = category => {
       responseHistogram?.add(category);
       responseHistogram = null;
     };
 
     // Set up the timeout timer.
-    let timeout = UrlbarPrefs.get("merinoTimeoutMs");
+    let timeout = lazy.UrlbarPrefs.get("merinoTimeoutMs");
     let timer = (this._merinoTimeoutTimer = new SkippableTimer({
       name: "Merino timeout",
       time: timeout,
       logger: this.logger,
       callback: () => {
         // The fetch timed out.
         this.logger.info(`Merino fetch timed out (timeout = ${timeout}ms)`);
         maybeRecordResponse("timeout");
@@ -1028,30 +1038,30 @@ class ProviderQuickSuggest extends Urlba
    */
   async _canAddSuggestion(suggestion) {
     this.logger.info("Checking if suggestion can be added");
     this.logger.debug(JSON.stringify({ suggestion }));
 
     // Return false if suggestions are disabled.
     if (
       (suggestion.is_sponsored &&
-        !UrlbarPrefs.get("suggest.quicksuggest.sponsored")) ||
+        !lazy.UrlbarPrefs.get("suggest.quicksuggest.sponsored")) ||
       (!suggestion.is_sponsored &&
-        !UrlbarPrefs.get("suggest.quicksuggest.nonsponsored"))
+        !lazy.UrlbarPrefs.get("suggest.quicksuggest.nonsponsored"))
     ) {
       this.logger.info("Suggestions disabled, not adding suggestion");
       return false;
     }
 
     // Return false if an impression cap has been hit.
     if (
       (suggestion.is_sponsored &&
-        UrlbarPrefs.get("quickSuggestImpressionCapsSponsoredEnabled")) ||
+        lazy.UrlbarPrefs.get("quickSuggestImpressionCapsSponsoredEnabled")) ||
       (!suggestion.is_sponsored &&
-        UrlbarPrefs.get("quickSuggestImpressionCapsNonSponsoredEnabled"))
+        lazy.UrlbarPrefs.get("quickSuggestImpressionCapsNonSponsoredEnabled"))
     ) {
       this._resetElapsedImpressionCounters();
       let type = suggestion.is_sponsored ? "sponsored" : "nonsponsored";
       let stats = this._impressionStats[type];
       if (stats) {
         let hitStats = stats.filter(s => s.maxCount <= s.count);
         if (hitStats.length) {
           this.logger.info("Impression cap(s) hit, not adding suggestion");
@@ -1122,26 +1132,26 @@ class ProviderQuickSuggest extends Urlba
    *   Whether the impression was recorded for a sponsored suggestion.
    */
   _updateImpressionStats(isSponsored) {
     this.logger.info("Starting impression stats update");
     this.logger.debug(
       JSON.stringify({
         isSponsored,
         currentStats: this._impressionStats,
-        impression_caps: UrlbarQuickSuggest.config.impression_caps,
+        impression_caps: lazy.UrlbarQuickSuggest.config.impression_caps,
       })
     );
 
     // Don't bother recording anything if caps are disabled.
     if (
       (isSponsored &&
-        !UrlbarPrefs.get("quickSuggestImpressionCapsSponsoredEnabled")) ||
+        !lazy.UrlbarPrefs.get("quickSuggestImpressionCapsSponsoredEnabled")) ||
       (!isSponsored &&
-        !UrlbarPrefs.get("quickSuggestImpressionCapsNonSponsoredEnabled"))
+        !lazy.UrlbarPrefs.get("quickSuggestImpressionCapsNonSponsoredEnabled"))
     ) {
       this.logger.info("Impression caps disabled, skipping update");
       return;
     }
 
     // Get the user's impression stats. Since stats are synced from caps, if the
     // stats don't exist then the caps don't exist, and don't bother recording
     // anything in that case.
@@ -1167,33 +1177,33 @@ class ProviderQuickSuggest extends Urlba
           suggestionType: type,
         });
       }
     }
 
     // Save the stats.
     this._updatingImpressionStats = true;
     try {
-      UrlbarPrefs.set(
+      lazy.UrlbarPrefs.set(
         "quicksuggest.impressionCaps.stats",
         JSON.stringify(this._impressionStats)
       );
     } finally {
       this._updatingImpressionStats = false;
     }
 
     this.logger.info("Finished impression stats update");
     this.logger.debug(JSON.stringify({ newStats: this._impressionStats }));
   }
 
   /**
    * Loads and validates impression stats.
    */
   _loadImpressionStats() {
-    let json = UrlbarPrefs.get("quicksuggest.impressionCaps.stats");
+    let json = lazy.UrlbarPrefs.get("quicksuggest.impressionCaps.stats");
     if (!json) {
       this._impressionStats = {};
     } else {
       try {
         this._impressionStats = JSON.parse(
           json,
           // Infinity, which is the `intervalSeconds` for the lifetime cap, is
           // stringified as `null` in the JSON, so convert it back to Infinity.
@@ -1210,17 +1220,17 @@ class ProviderQuickSuggest extends Urlba
    *
    * - Type checks stats and discards any that are invalid. We do this because
    *   stats are stored in prefs where anyone can modify them.
    * - Syncs stats with impression caps so that there is one stats object
    *   corresponding to each impression cap. See the `_impressionStats` comment
    *   for more info.
    */
   _validateImpressionStats() {
-    let { impression_caps } = UrlbarQuickSuggest.config;
+    let { impression_caps } = lazy.UrlbarQuickSuggest.config;
 
     this.logger.info("Validating impression stats");
     this.logger.debug(
       JSON.stringify({
         impression_caps,
         currentStats: this._impressionStats,
       })
     );
@@ -1331,17 +1341,17 @@ class ProviderQuickSuggest extends Urlba
   /**
    * Resets the counters of impression stats whose intervals have elapased.
    */
   _resetElapsedImpressionCounters() {
     this.logger.info("Checking for elapsed impression cap intervals");
     this.logger.debug(
       JSON.stringify({
         currentStats: this._impressionStats,
-        impression_caps: UrlbarQuickSuggest.config.impression_caps,
+        impression_caps: lazy.UrlbarQuickSuggest.config.impression_caps,
       })
     );
 
     let now = Date.now();
     for (let [type, stats] of Object.entries(this._impressionStats)) {
       for (let stat of stats) {
         let elapsedMs = now - stat.startDateMs;
         let intervalMs = 1000 * stat.intervalSeconds;
@@ -1454,19 +1464,19 @@ class ProviderQuickSuggest extends Urlba
    *
    * @param {number} ms
    *   The number of milliseconds in the interval.
    */
   _setImpressionCountersResetInterval(
     ms = IMPRESSION_COUNTERS_RESET_INTERVAL_MS
   ) {
     if (this._impressionCountersResetInterval) {
-      clearInterval(this._impressionCountersResetInterval);
+      lazy.clearInterval(this._impressionCountersResetInterval);
     }
-    this._impressionCountersResetInterval = setInterval(
+    this._impressionCountersResetInterval = lazy.setInterval(
       () => this._resetElapsedImpressionCounters(),
       ms
     );
   }
 
   /**
    * Gets the timestamp of app startup in ms since Unix epoch. This is only
    * defined as its own method so tests can override it to simulate arbitrary
@@ -1481,17 +1491,17 @@ class ProviderQuickSuggest extends Urlba
 
   /**
    * Loads blocked suggestion digests from the pref into `_blockedDigests`.
    */
   async _loadBlockedDigests() {
     this.logger.debug(`Queueing _loadBlockedDigests`);
     await this._blockTaskQueue.queue(() => {
       this.logger.info(`Loading blocked suggestion digests`);
-      let json = UrlbarPrefs.get("quicksuggest.blockedDigests");
+      let json = lazy.UrlbarPrefs.get("quicksuggest.blockedDigests");
       this.logger.debug(
         `browser.urlbar.quicksuggest.blockedDigests value: ${json}`
       );
       if (!json) {
         this.logger.info(`There are no blocked suggestion digests`);
         this._blockedDigests.clear();
       } else {
         try {
@@ -1519,17 +1529,17 @@ class ProviderQuickSuggest extends Urlba
     let hashArray = new Uint8Array(hashBuffer);
     return Array.from(hashArray, b => b.toString(16).padStart(2, "0")).join("");
   }
 
   /**
    * Updates state based on the `browser.urlbar.quicksuggest.enabled` pref.
    */
   _updateFeatureState() {
-    let enabled = UrlbarPrefs.get("quickSuggestEnabled");
+    let enabled = lazy.UrlbarPrefs.get("quickSuggestEnabled");
     if (enabled == this._quickSuggestEnabled) {
       // This method is a Nimbus `onUpdate()` callback, which means it's called
       // each time any pref is changed that is a fallback for a Nimbus variable.
       // We have many such prefs. The point of this method is to set up and tear
       // down state when quick suggest's enabled status changes, so ignore
       // updates that do not modify `quickSuggestEnabled`.
       return;
     }
--- a/browser/components/urlbar/UrlbarProviderRemoteTabs.jsm
+++ b/browser/components/urlbar/UrlbarProviderRemoteTabs.jsm
@@ -9,60 +9,65 @@
  */
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderRemoteTabs"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-XPCOMUtils.defineLazyModuleGetters(this, {
+
+const { UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
   SyncedTabs: "resource://services-sync/SyncedTabs.jsm",
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
   UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 let _cache = null;
 
 // By default, we add remote tabs that have been used more recently than this
 // time ago. Any remaining remote tabs are added in queue if no other results
 // are found.
 const RECENT_REMOTE_TAB_THRESHOLD_MS = 72 * 60 * 60 * 1000; // 72 hours.
 
-XPCOMUtils.defineLazyGetter(this, "weaveXPCService", function() {
+XPCOMUtils.defineLazyGetter(lazy, "weaveXPCService", function() {
   try {
     return Cc["@mozilla.org/weave/service;1"].getService(
       Ci.nsISupports
     ).wrappedJSObject;
   } catch (ex) {
     // The app didn't build Sync.
   }
   return null;
 });
 
 XPCOMUtils.defineLazyPreferenceGetter(
-  this,
+  lazy,
   "showRemoteIconsPref",
   "services.sync.syncedTabs.showRemoteIcons",
   true
 );
 
 XPCOMUtils.defineLazyPreferenceGetter(
-  this,
+  lazy,
   "showRemoteTabsPref",
   "services.sync.syncedTabs.showRemoteTabs",
   true
 );
 
 XPCOMUtils.defineLazyPreferenceGetter(
-  this,
+  lazy,
   "syncUsernamePref",
   "services.sync.username"
 );
 
 // from MDN...
 function escapeRegExp(string) {
   return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
 }
@@ -95,23 +100,23 @@ class ProviderRemoteTabs extends UrlbarP
    * Whether this provider should be invoked for the given context.
    * If this method returns false, the providers manager won't start a query
    * with this provider, to save on resources.
    * @param {UrlbarQueryContext} queryContext The query context object
    * @returns {boolean} Whether this provider should be invoked for the search.
    */
   isActive(queryContext) {
     return (
-      syncUsernamePref &&
-      showRemoteTabsPref &&
-      UrlbarPrefs.get("suggest.remotetab") &&
+      lazy.syncUsernamePref &&
+      lazy.showRemoteTabsPref &&
+      lazy.UrlbarPrefs.get("suggest.remotetab") &&
       queryContext.sources.includes(UrlbarUtils.RESULT_SOURCE.TABS) &&
-      weaveXPCService &&
-      weaveXPCService.ready &&
-      weaveXPCService.enabled
+      lazy.weaveXPCService &&
+      lazy.weaveXPCService.ready &&
+      lazy.weaveXPCService.enabled
     );
   }
 
   /**
    * Starts querying.
    * @param {UrlbarQueryContext} queryContext The query context object
    * @param {function} addCallback Callback invoked by the provider to add a new
    *        result. A UrlbarResult should be passed to it.
@@ -129,40 +134,40 @@ class ProviderRemoteTabs extends UrlbarP
       return;
     }
 
     let resultsAdded = 0;
     let staleTabs = [];
     for (let { tab, client } of tabsData) {
       if (
         !searchString ||
-        searchString == UrlbarTokenizer.RESTRICT.OPENPAGE ||
+        searchString == lazy.UrlbarTokenizer.RESTRICT.OPENPAGE ||
         re.test(tab.url) ||
         (tab.title && re.test(tab.title))
       ) {
-        if (showRemoteIconsPref) {
+        if (lazy.showRemoteIconsPref) {
           if (!tab.icon) {
             // It's rare that Sync supplies the icon for the page. If it does, it is a
             // string URL.
             tab.icon = UrlbarUtils.getIconForUrl(tab.url);
           } else {
-            tab.icon = PlacesUtils.favicons.getFaviconLinkForIcon(
+            tab.icon = lazy.PlacesUtils.favicons.getFaviconLinkForIcon(
               Services.io.newURI(tab.icon)
             ).spec;
           }
         }
 
-        let result = new UrlbarResult(
+        let result = new lazy.UrlbarResult(
           UrlbarUtils.RESULT_TYPE.REMOTE_TAB,
           UrlbarUtils.RESULT_SOURCE.TABS,
-          ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
+          ...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
             url: [tab.url, UrlbarUtils.HIGHLIGHT.TYPED],
             title: [tab.title, UrlbarUtils.HIGHLIGHT.TYPED],
             device: client.name,
-            icon: showRemoteIconsPref ? tab.icon : "",
+            icon: lazy.showRemoteIconsPref ? tab.icon : "",
             lastUsed: (tab.lastUsed || 0) * 1000,
           })
         );
 
         // We want to return the most relevant remote tabs and thus the most
         // recent ones. While SyncedTabs.jsm returns tabs that are sorted by
         // most recent client, then most recent tab, we can do better. For
         // example, the most recent client might have one recent tab and then
@@ -200,19 +205,19 @@ class ProviderRemoteTabs extends UrlbarP
    */
   async buildItems() {
     // This is sorted by most recent client, most recent tab.
     let tabsData = [];
     // If Sync isn't initialized (either due to lag at startup or due to no user
     // being signed in), don't reach in to Weave.Service as that may initialize
     // Sync unnecessarily - we'll get an observer notification later when it
     // becomes ready and has synced a list of tabs.
-    if (weaveXPCService.ready) {
-      let clients = await SyncedTabs.getTabClients();
-      SyncedTabs.sortTabClientsByLastUsed(clients);
+    if (lazy.weaveXPCService.ready) {
+      let clients = await lazy.SyncedTabs.getTabClients();
+      lazy.SyncedTabs.sortTabClientsByLastUsed(clients);
       for (let client of clients) {
         for (let tab of client.tabs) {
           tabsData.push({ tab, client });
         }
       }
     }
     return tabsData;
   }
--- a/browser/components/urlbar/UrlbarProviderSearchSuggestions.jsm
+++ b/browser/components/urlbar/UrlbarProviderSearchSuggestions.jsm
@@ -9,39 +9,43 @@
  */
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderSearchSuggestions"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-XPCOMUtils.defineLazyModuleGetters(this, {
+
+const { SkippableTimer, UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   SearchSuggestionController:
     "resource://gre/modules/SearchSuggestionController.jsm",
-  SkippableTimer: "resource:///modules/UrlbarUtils.jsm",
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
   UrlbarSearchUtils: "resource:///modules/UrlbarSearchUtils.jsm",
   UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 /**
  * Returns whether the passed in string looks like a url.
  * @param {string} str
  * @param {boolean} [ignoreAlphanumericHosts]
  * @returns {boolean}
  *   True if the query looks like a URL.
  */
 function looksLikeUrl(str, ignoreAlphanumericHosts = false) {
   // Single word including special chars.
   return (
-    !UrlbarTokenizer.REGEXP_SPACES.test(str) &&
+    !lazy.UrlbarTokenizer.REGEXP_SPACES.test(str) &&
     (["/", "@", ":", "["].some(c => str.includes(c)) ||
       (ignoreAlphanumericHosts
         ? /^([\[\]A-Z0-9-]+\.){3,}[^.]+$/i.test(str)
         : str.includes(".")))
   );
 }
 
 /**
@@ -95,19 +99,19 @@ class ProviderSearchSuggestions extends 
       return false;
     }
 
     if (!this._allowSuggestions(queryContext)) {
       return false;
     }
 
     let wantsLocalSuggestions =
-      UrlbarPrefs.get("maxHistoricalSearchSuggestions") &&
+      lazy.UrlbarPrefs.get("maxHistoricalSearchSuggestions") &&
       (queryContext.trimmedSearchString ||
-        UrlbarPrefs.get("update2.emptySearchBehavior") != 0);
+        lazy.UrlbarPrefs.get("update2.emptySearchBehavior") != 0);
 
     return wantsLocalSuggestions || this._allowRemoteSuggestions(queryContext);
   }
 
   /**
    * Returns whether the user typed a token alias or restriction token, or is in
    * search mode. We use this value to override the pref to disable search
    * suggestions in the Urlbar.
@@ -116,17 +120,17 @@ class ProviderSearchSuggestions extends 
    *   restriction token.
    */
   _isTokenOrRestrictionPresent(queryContext) {
     return (
       queryContext.searchString.startsWith("@") ||
       (queryContext.restrictSource &&
         queryContext.restrictSource == UrlbarUtils.RESULT_SOURCE.SEARCH) ||
       queryContext.tokens.some(
-        t => t.type == UrlbarTokenizer.TYPE.RESTRICT_SEARCH
+        t => t.type == lazy.UrlbarTokenizer.TYPE.RESTRICT_SEARCH
       ) ||
       (queryContext.searchMode &&
         queryContext.sources.includes(UrlbarUtils.RESULT_SOURCE.SEARCH))
     );
   }
 
   /**
    * Returns whether suggestions in general are allowed for a given query
@@ -136,21 +140,21 @@ class ProviderSearchSuggestions extends 
    * @param {object} queryContext The query context object
    * @returns {boolean} True if suggestions in general are allowed and false if
    *   not.
    */
   _allowSuggestions(queryContext) {
     if (
       // If the user typed a restriction token or token alias, we ignore the
       // pref to disable suggestions in the Urlbar.
-      (!UrlbarPrefs.get("suggest.searches") &&
+      (!lazy.UrlbarPrefs.get("suggest.searches") &&
         !this._isTokenOrRestrictionPresent(queryContext)) ||
-      !UrlbarPrefs.get("browser.search.suggest.enabled") ||
+      !lazy.UrlbarPrefs.get("browser.search.suggest.enabled") ||
       (queryContext.isPrivate &&
-        !UrlbarPrefs.get("browser.search.suggest.enabled.private"))
+        !lazy.UrlbarPrefs.get("browser.search.suggest.enabled.private"))
     ) {
       return false;
     }
     return true;
   }
 
   /**
    * Returns whether remote suggestions are allowed for a given query context.
@@ -224,41 +228,42 @@ class ProviderSearchSuggestions extends 
       ? aliasEngine.query
       : UrlbarUtils.substringAt(
           queryContext.searchString,
           queryContext.tokens[0]?.value || ""
         ).trim();
 
     let leadingRestrictionToken = null;
     if (
-      UrlbarTokenizer.isRestrictionToken(queryContext.tokens[0]) &&
+      lazy.UrlbarTokenizer.isRestrictionToken(queryContext.tokens[0]) &&
       (queryContext.tokens.length > 1 ||
-        queryContext.tokens[0].type == UrlbarTokenizer.TYPE.RESTRICT_SEARCH)
+        queryContext.tokens[0].type ==
+          lazy.UrlbarTokenizer.TYPE.RESTRICT_SEARCH)
     ) {
       leadingRestrictionToken = queryContext.tokens[0].value;
     }
 
     // Strip a leading search restriction char, because we prepend it to text
     // when the search shortcut is used and it's not user typed. Don't strip
     // other restriction chars, so that it's possible to search for things
     // including one of those (e.g. "c#").
-    if (leadingRestrictionToken === UrlbarTokenizer.RESTRICT.SEARCH) {
+    if (leadingRestrictionToken === lazy.UrlbarTokenizer.RESTRICT.SEARCH) {
       query = UrlbarUtils.substringAfter(query, leadingRestrictionToken).trim();
     }
 
     // Find our search engine. It may have already been set with an alias.
     let engine;
     if (aliasEngine) {
       engine = aliasEngine.engine;
     } else if (queryContext.searchMode?.engineName) {
       engine = Services.search.getEngineByName(
         queryContext.searchMode.engineName
       );
     } else {
-      engine = UrlbarSearchUtils.getDefaultEngine(queryContext.isPrivate);
+      engine = lazy.UrlbarSearchUtils.getDefaultEngine(queryContext.isPrivate);
     }
 
     if (!engine) {
       return;
     }
 
     let alias = (aliasEngine && aliasEngine.alias) || "";
     let results = await this._fetchSearchSuggestions(
@@ -297,17 +302,17 @@ class ProviderSearchSuggestions extends 
     }
   }
 
   async _fetchSearchSuggestions(queryContext, engine, searchString, alias) {
     if (!engine) {
       return null;
     }
 
-    this._suggestionsController = new SearchSuggestionController();
+    this._suggestionsController = new lazy.SearchSuggestionController();
     this._suggestionsController.formHistoryParam = queryContext.formHistoryName;
 
     // If there's a form history entry that equals the search string, the search
     // suggestions controller will include it, and we'll make a result for it.
     // If the heuristic result ends up being a search result, the muxer will
     // discard the form history result since it dupes the heuristic, and the
     // final list of results would be left with `count` - 1 form history results
     // instead of `count`.  Therefore we request `count` + 1 entries.  The muxer
@@ -340,29 +345,29 @@ class ProviderSearchSuggestions extends 
 
     let results = [];
 
     // maxHistoricalSearchSuggestions used to determine the initial number of
     // form history results, with the special case where zero means to never
     // show form history at all.  With the introduction of flexed result
     // groups, we now use it only as a boolean: Zero means don't show form
     // history at all (as before), non-zero means show it.
-    if (UrlbarPrefs.get("maxHistoricalSearchSuggestions")) {
+    if (lazy.UrlbarPrefs.get("maxHistoricalSearchSuggestions")) {
       for (let entry of fetchData.local) {
         results.push(makeFormHistoryResult(queryContext, engine, entry));
       }
     }
 
     // If we don't return many results, then keep track of the query. If the
     // user just adds on to the query, we won't fetch more suggestions if the
     // query is very long since we are unlikely to get any.
     if (
       allowRemote &&
       !fetchData.remote.length &&
-      searchString.length > UrlbarPrefs.get("maxCharsForSearchSuggestions")
+      searchString.length > lazy.UrlbarPrefs.get("maxCharsForSearchSuggestions")
     ) {
       this._lastLowResultsSearchSuggestion = searchString;
     }
 
     // If we have only tail suggestions, we only show them if we have no other
     // results. We need to wait for other results to arrive to avoid flickering.
     // We will wait for this timer unless we have suggestions that don't have a
     // tail.
@@ -383,40 +388,46 @@ class ProviderSearchSuggestions extends 
         );
         continue;
       }
 
       let tail = entry.tail;
       let tailPrefix = entry.matchPrefix;
 
       // Skip tail suggestions if the pref is disabled.
-      if (tail && !UrlbarPrefs.get("richSuggestions.tail")) {
+      if (tail && !lazy.UrlbarPrefs.get("richSuggestions.tail")) {
         continue;
       }
 
       if (!tail) {
         await tailTimer.fire().catch(ex => this.logger.error(ex));
       }
 
       try {
         results.push(
-          new UrlbarResult(
+          new lazy.UrlbarResult(
             UrlbarUtils.RESULT_TYPE.SEARCH,
             UrlbarUtils.RESULT_SOURCE.SEARCH,
-            ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
-              engine: [engine.name, UrlbarUtils.HIGHLIGHT.TYPED],
-              suggestion: [entry.value, UrlbarUtils.HIGHLIGHT.SUGGESTED],
-              lowerCaseSuggestion: entry.value.toLocaleLowerCase(),
-              tailPrefix,
-              tail: [tail, UrlbarUtils.HIGHLIGHT.SUGGESTED],
-              tailOffsetIndex: tail ? entry.tailOffsetIndex : undefined,
-              keyword: [alias ? alias : undefined, UrlbarUtils.HIGHLIGHT.TYPED],
-              query: [searchString.trim(), UrlbarUtils.HIGHLIGHT.NONE],
-              icon: !entry.value ? engine.iconURI?.spec : undefined,
-            })
+            ...lazy.UrlbarResult.payloadAndSimpleHighlights(
+              queryContext.tokens,
+              {
+                engine: [engine.name, UrlbarUtils.HIGHLIGHT.TYPED],
+                suggestion: [entry.value, UrlbarUtils.HIGHLIGHT.SUGGESTED],
+                lowerCaseSuggestion: entry.value.toLocaleLowerCase(),
+                tailPrefix,
+                tail: [tail, UrlbarUtils.HIGHLIGHT.SUGGESTED],
+                tailOffsetIndex: tail ? entry.tailOffsetIndex : undefined,
+                keyword: [
+                  alias ? alias : undefined,
+                  UrlbarUtils.HIGHLIGHT.TYPED,
+                ],
+                query: [searchString.trim(), UrlbarUtils.HIGHLIGHT.NONE],
+                icon: !entry.value ? engine.iconURI?.spec : undefined,
+              }
+            )
           )
         );
       } catch (err) {
         this.logger.error(err);
         continue;
       }
     }
 
@@ -450,39 +461,41 @@ class ProviderSearchSuggestions extends 
 
     let query = UrlbarUtils.substringAfter(
       queryContext.searchString,
       possibleAlias
     );
 
     // Match an alias only when it has a space after it.  If there's no trailing
     // space, then continue to treat it as part of the search string.
-    if (!UrlbarTokenizer.REGEXP_SPACES_START.test(query)) {
+    if (!lazy.UrlbarTokenizer.REGEXP_SPACES_START.test(query)) {
       return null;
     }
 
     // Check if the user entered an engine alias directly.
-    let engineMatch = await UrlbarSearchUtils.engineForAlias(possibleAlias);
+    let engineMatch = await lazy.UrlbarSearchUtils.engineForAlias(
+      possibleAlias
+    );
     if (engineMatch) {
       return {
         engine: engineMatch,
         alias: possibleAlias,
         query: query.trim(),
       };
     }
 
     return null;
   }
 }
 
 function makeFormHistoryResult(queryContext, engine, entry) {
-  return new UrlbarResult(
+  return new lazy.UrlbarResult(
     UrlbarUtils.RESULT_TYPE.SEARCH,
     UrlbarUtils.RESULT_SOURCE.HISTORY,
-    ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
+    ...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
       engine: engine.name,
       suggestion: [entry.value, UrlbarUtils.HIGHLIGHT.SUGGESTED],
       lowerCaseSuggestion: entry.value.toLocaleLowerCase(),
     })
   );
 }
 
 var UrlbarProviderSearchSuggestions = new ProviderSearchSuggestions();
--- a/browser/components/urlbar/UrlbarProviderSearchTips.jsm
+++ b/browser/components/urlbar/UrlbarProviderSearchTips.jsm
@@ -11,38 +11,42 @@
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderSearchTips"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
-XPCOMUtils.defineLazyModuleGetters(this, {
+const { UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   AppMenuNotifications: "resource://gre/modules/AppMenuNotifications.jsm",
   DefaultBrowserCheck: "resource:///modules/BrowserGlue.jsm",
   BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
   ProfileAge: "resource://gre/modules/ProfileAge.jsm",
   setTimeout: "resource://gre/modules/Timer.jsm",
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarProviderTopSites: "resource:///modules/UrlbarProviderTopSites.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
-XPCOMUtils.defineLazyGetter(this, "updateManager", () => {
+XPCOMUtils.defineLazyGetter(lazy, "updateManager", () => {
   return (
     Cc["@mozilla.org/updates/update-manager;1"] &&
     Cc["@mozilla.org/updates/update-manager;1"].getService(Ci.nsIUpdateManager)
   );
 });
 
 XPCOMUtils.defineLazyPreferenceGetter(
-  this,
+  lazy,
   "cfrFeaturesUserPref",
   "browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features",
   true
 );
 
 // The possible tips to show.  These names (except NONE) are used in the names
 // of keys in the `urlbar.tips` keyed scalar telemetry (see telemetry.rst).
 // Don't modify them unless you've considered that.  If you do modify them or
@@ -92,17 +96,20 @@ const LAST_UPDATE_THRESHOLD_MS = 24 * 60
 class ProviderSearchTips extends UrlbarProvider {
   constructor() {
     super();
 
     // Whether we should disable tips for the current browser session, for
     // example because a tip was already shown.
     this.disableTipsForCurrentSession = true;
     for (let tip of Object.values(TIPS)) {
-      if (tip && UrlbarPrefs.get(`tipShownCount.${tip}`) < MAX_SHOWN_COUNT) {
+      if (
+        tip &&
+        lazy.UrlbarPrefs.get(`tipShownCount.${tip}`) < MAX_SHOWN_COUNT
+      ) {
         this.disableTipsForCurrentSession = false;
         break;
       }
     }
 
     // Whether and what kind of tip we've shown in the current engagement.
     this.showedTipTypeInCurrentEngagement = TIPS.NONE;
 
@@ -114,17 +121,17 @@ class ProviderSearchTips extends UrlbarP
    * Enum of the types of search tips.
    */
   get TIP_TYPE() {
     return TIPS;
   }
 
   get PRIORITY() {
     // Search tips are prioritized over the Places and top sites providers.
-    return UrlbarProviderTopSites.PRIORITY + 1;
+    return lazy.UrlbarProviderTopSites.PRIORITY + 1;
   }
 
   /**
    * Unique name for the provider, used by the context to filter on providers.
    * Not using a unique name will cause the newest registration to win.
    */
   get name() {
     return "UrlbarProviderSearchTips";
@@ -140,17 +147,17 @@ class ProviderSearchTips extends UrlbarP
   /**
    * Whether this provider should be invoked for the given context.
    * If this method returns false, the providers manager won't start a query
    * with this provider, to save on resources.
    * @param {UrlbarQueryContext} queryContext The query context object
    * @returns {boolean} Whether this provider should be invoked for the search.
    */
   isActive(queryContext) {
-    return this.currentTip && cfrFeaturesUserPref;
+    return this.currentTip && lazy.cfrFeaturesUserPref;
   }
 
   /**
    * Gets the provider's priority.
    * @param {UrlbarQueryContext} queryContext The query context object
    * @returns {number} The provider's priority for the given query.
    */
   getPriority(queryContext) {
@@ -169,17 +176,17 @@ class ProviderSearchTips extends UrlbarP
     let instance = this.queryInstance;
 
     let tip = this.currentTip;
     this.showedTipTypeInCurrentEngagement = this.currentTip;
     this.currentTip = TIPS.NONE;
 
     let defaultEngine = await Services.search.getDefault();
 
-    let result = new UrlbarResult(
+    let result = new lazy.UrlbarResult(
       UrlbarUtils.RESULT_TYPE.TIP,
       UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
       {
         type: tip,
         buttonTextData: { id: "urlbar-search-tips-confirm" },
         icon: defaultEngine.iconURI?.spec,
       }
     );
@@ -215,17 +222,17 @@ class ProviderSearchTips extends UrlbarP
   }
 
   /**
    * Called when the tip is selected.
    * @param {UrlbarResult} result
    *   The result that was picked.
    */
   pickResult(result) {
-    let window = BrowserWindowTracker.getTopWindow();
+    let window = lazy.BrowserWindowTracker.getTopWindow();
     window.gURLBar.value = "";
     window.gURLBar.setPageProxyState("invalid");
     window.gURLBar.removeAttribute("suppress-focus-border");
     window.gURLBar.focus();
   }
 
   /**
    * Called when the user starts and ends an engagement with the urlbar.  For
@@ -248,17 +255,17 @@ class ProviderSearchTips extends UrlbarP
     if (
       this.showedTipTypeInCurrentEngagement != TIPS.NONE &&
       state == "engagement"
     ) {
       // The user either clicked the tip's "Okay, Got It" button, or they
       // engaged with the urlbar while the tip was showing. We treat both as the
       // user's acknowledgment of the tip, and we don't show tips again in any
       // session. Set the shown count to the max.
-      UrlbarPrefs.set(
+      lazy.UrlbarPrefs.set(
         `tipShownCount.${this.showedTipTypeInCurrentEngagement}`,
         MAX_SHOWN_COUNT
       );
     }
     this.showedTipTypeInCurrentEngagement = TIPS.NONE;
   }
 
   /**
@@ -311,19 +318,19 @@ class ProviderSearchTips extends UrlbarP
     // the input, the view won't close in that case. We need to close it
     // manually.
     if (this.showedTipTypeInCurrentEngagement != TIPS.NONE) {
       window.gURLBar.view.close();
     }
 
     // Check if we are supposed to show a tip for the current session.
     if (
-      !cfrFeaturesUserPref ||
+      !lazy.cfrFeaturesUserPref ||
       (this.disableTipsForCurrentSession &&
-        !UrlbarPrefs.get("searchTips.test.ignoreShowLimits"))
+        !lazy.UrlbarPrefs.get("searchTips.test.ignoreShowLimits"))
     ) {
       return;
     }
 
     this._maybeShowTipForUrl(uri.spec).catch(ex => this.logger.error(ex));
   }
 
   /**
@@ -347,38 +354,40 @@ class ProviderSearchTips extends UrlbarP
       tip = TIPS.ONBOARD;
     } else if (isSearchHomepage) {
       tip = TIPS.REDIRECT;
     } else {
       // No tip.
       return;
     }
 
-    let ignoreShowLimits = UrlbarPrefs.get("searchTips.test.ignoreShowLimits");
+    let ignoreShowLimits = lazy.UrlbarPrefs.get(
+      "searchTips.test.ignoreShowLimits"
+    );
 
     // If we've shown this type of tip the maximum number of times over all
     // sessions, don't show it again.
-    let shownCount = UrlbarPrefs.get(`tipShownCount.${tip}`);
+    let shownCount = lazy.UrlbarPrefs.get(`tipShownCount.${tip}`);
     if (shownCount >= MAX_SHOWN_COUNT && !ignoreShowLimits) {
       return;
     }
 
     // Don't show a tip if the browser has been updated recently.
     let date = await lastBrowserUpdateDate();
     if (Date.now() - date <= LAST_UPDATE_THRESHOLD_MS && !ignoreShowLimits) {
       return;
     }
 
     // Start a search.
-    setTimeout(async () => {
+    lazy.setTimeout(async () => {
       if (this._maybeShowTipForUrlInstance != instance) {
         return;
       }
 
-      let window = BrowserWindowTracker.getTopWindow();
+      let window = lazy.BrowserWindowTracker.getTopWindow();
       // We don't want to interrupt a user's typed query with a Search Tip.
       // See bugs 1613662 and 1619547.
       if (
         window.gURLBar.getAttribute("pageproxystate") == "invalid" &&
         window.gURLBar.value != ""
       ) {
         return;
       }
@@ -391,41 +400,41 @@ class ProviderSearchTips extends UrlbarP
       ) {
         return;
       }
 
       // At this point, we're showing a tip.
       this.disableTipsForCurrentSession = true;
 
       // Store the new shown count.
-      UrlbarPrefs.set(`tipShownCount.${tip}`, shownCount + 1);
+      lazy.UrlbarPrefs.set(`tipShownCount.${tip}`, shownCount + 1);
 
       this.currentTip = tip;
       window.gURLBar.search("", { focus: tip == TIPS.ONBOARD });
     }, SHOW_TIP_DELAY_MS);
   }
 }
 
 async function isBrowserShowingNotification() {
-  let window = BrowserWindowTracker.getTopWindow();
+  let window = lazy.BrowserWindowTracker.getTopWindow();
 
   // urlbar view and notification box (info bar)
   if (
     window.gURLBar.view.isOpen ||
     window.gNotificationBox.currentNotification ||
     window.gBrowser.getNotificationBox().currentNotification
   ) {
     return true;
   }
 
   // app menu notification doorhanger
   if (
-    AppMenuNotifications.activeNotification &&
-    !AppMenuNotifications.activeNotification.dismissed &&
-    !AppMenuNotifications.activeNotification.options.badgeOnly
+    lazy.AppMenuNotifications.activeNotification &&
+    !lazy.AppMenuNotifications.activeNotification.dismissed &&
+    !lazy.AppMenuNotifications.activeNotification.options.badgeOnly
   ) {
     return true;
   }
 
   // tracking protection and identity box doorhangers
   if (
     [
       "tracking-protection-icon-container",
@@ -460,17 +469,17 @@ async function isBrowserShowingNotificat
   // can be shown at startup
   if (window.gDialogBox.isOpen) {
     return true;
   }
 
   // On startup, the default browser check normally opens after the Search Tip.
   // As a result, we can't check for the prompt's presence, but we can check if
   // it plans on opening.
-  const willPrompt = await DefaultBrowserCheck.willCheckDefaultBrowser(
+  const willPrompt = await lazy.DefaultBrowserCheck.willCheckDefaultBrowser(
     /* isStartupCheck */ false
   );
   if (willPrompt) {
     return true;
   }
 
   return false;
 }
@@ -511,18 +520,18 @@ async function isDefaultEngineHomepage(u
 
   return homepageMatches.domainPath.test(urlStr);
 }
 
 async function lastBrowserUpdateDate() {
   // Get the newest update in the update history. This isn't perfect
   // because these dates are when updates are applied, not when the
   // user restarts with the update. See bug 1595328.
-  if (updateManager && updateManager.getUpdateCount()) {
-    let update = updateManager.getUpdateAt(0);
+  if (lazy.updateManager && lazy.updateManager.getUpdateCount()) {
+    let update = lazy.updateManager.getUpdateAt(0);
     return update.installDate;
   }
   // Fall back to the profile age.
-  let age = await ProfileAge();
+  let age = await lazy.ProfileAge();
   return (await age.firstUse) || age.created;
 }
 
 var UrlbarProviderSearchTips = new ProviderSearchTips();
--- a/browser/components/urlbar/UrlbarProviderTabToSearch.jsm
+++ b/browser/components/urlbar/UrlbarProviderTabToSearch.jsm
@@ -10,25 +10,30 @@
  */
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderTabToSearch"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-XPCOMUtils.defineLazyModuleGetters(this, {
+
+const { UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   UrlbarView: "resource:///modules/UrlbarView.jsm",
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarProviderAutofill: "resource:///modules/UrlbarProviderAutofill.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
   UrlbarSearchUtils: "resource:///modules/UrlbarSearchUtils.jsm",
   UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 const DYNAMIC_RESULT_TYPE = "onboardTabToSearch";
 const VIEW_TEMPLATE = {
   attributes: {
     role: "group",
     selectable: "true",
   },
@@ -88,18 +93,18 @@ const VIEW_TEMPLATE = {
   ],
 };
 
 /**
  * Initializes this provider's dynamic result. To be called after the creation
  *  of the provider singleton.
  */
 function initializeDynamicResult() {
-  UrlbarResult.addDynamicResultType(DYNAMIC_RESULT_TYPE);
-  UrlbarView.addDynamicViewTemplate(DYNAMIC_RESULT_TYPE, VIEW_TEMPLATE);
+  lazy.UrlbarResult.addDynamicResultType(DYNAMIC_RESULT_TYPE);
+  lazy.UrlbarView.addDynamicViewTemplate(DYNAMIC_RESULT_TYPE, VIEW_TEMPLATE);
 }
 
 /**
  * Class used to create the provider.
  */
 class ProviderTabToSearch extends UrlbarProvider {
   constructor() {
     super();
@@ -132,17 +137,17 @@ class ProviderTabToSearch extends Urlbar
    * @param {UrlbarQueryContext} queryContext The query context object
    * @returns {boolean} Whether this provider should be invoked for the search.
    */
   async isActive(queryContext) {
     return (
       queryContext.searchString &&
       queryContext.tokens.length == 1 &&
       !queryContext.searchMode &&
-      UrlbarPrefs.get("suggest.engines")
+      lazy.UrlbarPrefs.get("suggest.engines")
     );
   }
 
   /**
    * Gets the provider's priority.
    * @param {UrlbarQueryContext} queryContext The query context object
    * @returns {number} The provider's priority for the given query.
    */
@@ -227,22 +232,22 @@ class ProviderTabToSearch extends Urlbar
     // Also do not increment the counter if the result was interacted with less
     // than 5 minutes ago. This is a guard against the user running up the
     // counter by interacting with the same result repeatedly.
     if (
       result.payload.dynamicType &&
       (!this.onboardingInteractionAtTime ||
         this.onboardingInteractionAtTime < Date.now() - 1000 * 60 * 5)
     ) {
-      let interactionsLeft = UrlbarPrefs.get(
+      let interactionsLeft = lazy.UrlbarPrefs.get(
         "tabToSearch.onboard.interactionsLeft"
       );
 
       if (interactionsLeft > 0) {
-        UrlbarPrefs.set(
+        lazy.UrlbarPrefs.set(
           "tabToSearch.onboard.interactionsLeft",
           --interactionsLeft
         );
       }
 
       this.onboardingInteractionAtTime = Date.now();
     }
   }
@@ -267,27 +272,27 @@ class ProviderTabToSearch extends Urlbar
   onEngagement(isPrivate, state, queryContext, details) {
     if (!this.enginesShown.regular.size && !this.enginesShown.onboarding.size) {
       return;
     }
 
     try {
       // urlbar.tabtosearch.* is prerelease-only/opt-in for now. See bug 1686330.
       for (let engine of this.enginesShown.regular) {
-        let scalarKey = UrlbarSearchUtils.getSearchModeScalarKey({
+        let scalarKey = lazy.UrlbarSearchUtils.getSearchModeScalarKey({
           engineName: engine,
         });
         Services.telemetry.keyedScalarAdd(
           "urlbar.tabtosearch.impressions",
           scalarKey,
           1
         );
       }
       for (let engine of this.enginesShown.onboarding) {
-        let scalarKey = UrlbarSearchUtils.getSearchModeScalarKey({
+        let scalarKey = lazy.UrlbarSearchUtils.getSearchModeScalarKey({
           engineName: engine,
         });
         Services.telemetry.keyedScalarAdd(
           "urlbar.tabtosearch.impressions_onboarding",
           scalarKey,
           1
         );
       }
@@ -347,39 +352,42 @@ class ProviderTabToSearch extends Urlbar
       queryContext.searchString,
       {
         stripWww: true,
         trimSlash: true,
       }
     );
     // Skip any string that cannot be an origin.
     if (
-      !UrlbarTokenizer.looksLikeOrigin(searchStr, {
+      !lazy.UrlbarTokenizer.looksLikeOrigin(searchStr, {
         ignoreKnownDomains: true,
         noIp: true,
       })
     ) {
       return;
     }
 
     // Also remove the public suffix, if present, to allow for partial matches.
     if (searchStr.includes(".")) {
       searchStr = UrlbarUtils.stripPublicSuffixFromHost(searchStr);
     }
 
     // Add all matching engines.
-    let engines = await UrlbarSearchUtils.enginesForDomainPrefix(searchStr, {
-      matchAllDomainLevels: true,
-      onlyEnabled: true,
-    });
+    let engines = await lazy.UrlbarSearchUtils.enginesForDomainPrefix(
+      searchStr,
+      {
+        matchAllDomainLevels: true,
+        onlyEnabled: true,
+      }
+    );
     if (!engines.length) {
       return;
     }
 
-    const onboardingInteractionsLeft = UrlbarPrefs.get(
+    const onboardingInteractionsLeft = lazy.UrlbarPrefs.get(
       "tabToSearch.onboard.interactionsLeft"
     );
 
     // If the engine host begins with the search string, autofill may happen
     // for it, and the Muxer will retain the result only if there's a matching
     // autofill heuristic result.
     // Otherwise, we may have a partial match, where the search string is at
     // the boundary of a host part, for example "wiki" in "en.wikipedia.org".
@@ -419,17 +427,17 @@ class ProviderTabToSearch extends Urlbar
       } catch (ex) {
         // Invalid url or no searchForm.
       }
       if (searchFormHost?.includes("." + searchStr)) {
         partialMatchEnginesByHost.set(searchFormHost, engine);
       }
     }
     if (partialMatchEnginesByHost.size) {
-      let host = await UrlbarProviderAutofill.getTopHostOverThreshold(
+      let host = await lazy.UrlbarProviderAutofill.getTopHostOverThreshold(
         queryContext,
         Array.from(partialMatchEnginesByHost.keys())
       );
       if (host) {
         let engine = partialMatchEnginesByHost.get(host);
         if (onboardingInteractionsLeft > 0) {
           addCallback(this, makeOnboardingResult(engine, true));
         } else {
@@ -440,17 +448,17 @@ class ProviderTabToSearch extends Urlbar
   }
 }
 
 function makeOnboardingResult(engine, satisfiesAutofillThreshold = false) {
   let [url] = UrlbarUtils.stripPrefixAndTrim(engine.getResultDomain(), {
     stripWww: true,
   });
   url = url.substr(0, url.length - engine.searchUrlPublicSuffix.length);
-  let result = new UrlbarResult(
+  let result = new lazy.UrlbarResult(
     UrlbarUtils.RESULT_TYPE.DYNAMIC,
     UrlbarUtils.RESULT_SOURCE.SEARCH,
     {
       engine: engine.name,
       url,
       providesSearchMode: true,
       icon: UrlbarUtils.ICON.SEARCH_GLASS,
       dynamicType: DYNAMIC_RESULT_TYPE,
@@ -462,20 +470,20 @@ function makeOnboardingResult(engine, sa
   return result;
 }
 
 function makeResult(context, engine, satisfiesAutofillThreshold = false) {
   let [url] = UrlbarUtils.stripPrefixAndTrim(engine.getResultDomain(), {
     stripWww: true,
   });
   url = url.substr(0, url.length - engine.searchUrlPublicSuffix.length);
-  let result = new UrlbarResult(
+  let result = new lazy.UrlbarResult(
     UrlbarUtils.RESULT_TYPE.SEARCH,
     UrlbarUtils.RESULT_SOURCE.SEARCH,
-    ...UrlbarResult.payloadAndSimpleHighlights(context.tokens, {
+    ...lazy.UrlbarResult.payloadAndSimpleHighlights(context.tokens, {
       engine: engine.name,
       isGeneralPurposeEngine: engine.isGeneralPurposeEngine,
       url,
       providesSearchMode: true,
       icon: UrlbarUtils.ICON.SEARCH_GLASS,
       query: "",
       satisfiesAutofillThreshold,
     })
--- a/browser/components/urlbar/UrlbarProviderTokenAliasEngines.jsm
+++ b/browser/components/urlbar/UrlbarProviderTokenAliasEngines.jsm
@@ -8,23 +8,28 @@
  * This module exports a provider that offers token alias engines.
  */
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderTokenAliasEngines"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
-XPCOMUtils.defineLazyModuleGetters(this, {
+
+const { UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
   UrlbarSearchUtils: "resource:///modules/UrlbarSearchUtils.jsm",
   UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
 /**
  * Class used to create the provider.
  */
 class ProviderTokenAliasEngines extends UrlbarProvider {
   constructor() {
     super();
@@ -76,32 +81,32 @@ class ProviderTokenAliasEngines extends 
       return false;
     }
 
     // Do not show token alias results in search mode.
     if (queryContext.searchMode) {
       return false;
     }
 
-    this._engines = await UrlbarSearchUtils.tokenAliasEngines();
+    this._engines = await lazy.UrlbarSearchUtils.tokenAliasEngines();
     if (!this._engines.length) {
       return false;
     }
 
     // Check the query was not canceled while this executed.
     if (instance != this.queryInstance) {
       return false;
     }
 
     if (queryContext.trimmedSearchString == "@") {
       return true;
     }
 
     // If the user is typing a potential engine name, autofill it.
-    if (UrlbarPrefs.get("autoFill") && queryContext.allowAutofill) {
+    if (lazy.UrlbarPrefs.get("autoFill") && queryContext.allowAutofill) {
       let result = this._getAutofillResult(queryContext);
       if (result) {
         this._autofillData = { result, instance };
         return true;
       }
     }
 
     return false;
@@ -125,20 +130,20 @@ class ProviderTokenAliasEngines extends 
       addCallback(this, this._autofillData.result);
     }
 
     for (let { engine, tokenAliases } of this._engines) {
       if (
         tokenAliases[0].startsWith(queryContext.trimmedSearchString) &&
         engine.name != this._autofillData?.result.payload.engine
       ) {
-        let result = new UrlbarResult(
+        let result = new lazy.UrlbarResult(
           UrlbarUtils.RESULT_TYPE.SEARCH,
           UrlbarUtils.RESULT_SOURCE.SEARCH,
-          ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
+          ...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
             engine: [engine.name, UrlbarUtils.HIGHLIGHT.TYPED],
             keyword: [tokenAliases[0], UrlbarUtils.HIGHLIGHT.TYPED],
             query: ["", UrlbarUtils.HIGHLIGHT.TYPED],
             icon: engine.iconURI?.spec,
             providesSearchMode: true,
           })
         );
         addCallback(this, result);
@@ -175,39 +180,42 @@ class ProviderTokenAliasEngines extends 
       for (let alias of tokenAliases) {
         if (alias.startsWith(lowerCaseSearchString)) {
           // We found the engine.
 
           // Stop adding an autofill result once the user has typed the full
           // alias followed by a space. We enter search mode at that point.
           if (
             lowerCaseSearchString.startsWith(alias) &&
-            UrlbarTokenizer.REGEXP_SPACES_START.test(
+            lazy.UrlbarTokenizer.REGEXP_SPACES_START.test(
               lowerCaseSearchString.substring(alias.length)
             )
           ) {
             return null;
           }
 
           // Add an autofill result.  Append a space so the user can hit enter
           // or the right arrow key and immediately start typing their query.
           let aliasPreservingUserCase =
             queryContext.searchString +
             alias.substr(queryContext.searchString.length);
           let value = aliasPreservingUserCase + " ";
-          let result = new UrlbarResult(
+          let result = new lazy.UrlbarResult(
             UrlbarUtils.RESULT_TYPE.SEARCH,
             UrlbarUtils.RESULT_SOURCE.SEARCH,
-            ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
-              engine: [engine.name, UrlbarUtils.HIGHLIGHT.TYPED],
-              keyword: [aliasPreservingUserCase, UrlbarUtils.HIGHLIGHT.TYPED],
-              query: ["", UrlbarUtils.HIGHLIGHT.TYPED],
-              icon: engine.iconURI?.spec,
-              providesSearchMode: true,
-            })
+            ...lazy.UrlbarResult.payloadAndSimpleHighlights(
+              queryContext.tokens,
+              {
+                engine: [engine.name, UrlbarUtils.HIGHLIGHT.TYPED],
+                keyword: [aliasPreservingUserCase, UrlbarUtils.HIGHLIGHT.TYPED],
+                query: ["", UrlbarUtils.HIGHLIGHT.TYPED],
+                icon: engine.iconURI?.spec,
+                providesSearchMode: true,
+              }
+            )
           );
 
           // We set suggestedIndex = 0 instead of the heuristic because we
           // don't want this result to be automatically selected. That way,
           // users can press Tab to select the result, building on their
           // muscle memory from tab-to-search.
           result.suggestedIndex = 0;
 
--- a/browser/components/urlbar/UrlbarProviderTopSites.jsm
+++ b/browser/components/urlbar/UrlbarProviderTopSites.jsm
@@ -10,28 +10,32 @@
 
 var EXPORTED_SYMBOLS = ["UrlbarProviderTopSites"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
-XPCOMUtils.defineLazyModuleGetters(this, {
+const { UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   AboutNewTab: "resource:///modules/AboutNewTab.jsm",
   CONTEXTUAL_SERVICES_PING_TYPES:
     "resource:///modules/PartnerLinkAttribution.jsm",
   PartnerLinkAttribution: "resource:///modules/PartnerLinkAttribution.jsm",
   PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarProviderOpenTabs: "resource:///modules/UrlbarProviderOpenTabs.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
   UrlbarSearchUtils: "resource:///modules/UrlbarSearchUtils.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
   TOP_SITES_MAX_SITES_PER_ROW: "resource://activity-stream/common/Reducers.jsm",
   TOP_SITES_DEFAULT_ROWS: "resource://activity-stream/common/Reducers.jsm",
 });
 
 // The scalar category of TopSites impression for Contextual Services
 const SCALAR_CATEGORY_TOPSITES = "contextual.services.topsites.impression";
 
 // These prefs must be true for the provider to return results. They are assumed
@@ -119,46 +123,46 @@ class ProviderTopSites extends UrlbarPro
     // configure the default empty search results. See bug 1623666.
     let enabled = TOP_SITES_ENABLED_PREFS.every(p =>
       Services.prefs.getBoolPref(p, false)
     );
     if (!enabled) {
       return;
     }
 
-    let sites = AboutNewTab.getTopSites();
+    let sites = lazy.AboutNewTab.getTopSites();
 
     let instance = this.queryInstance;
 
     // Filter out empty values. Site is empty when there's a gap between tiles
     // on about:newtab.
     sites = sites.filter(site => site);
 
-    if (!UrlbarPrefs.get("sponsoredTopSites")) {
+    if (!lazy.UrlbarPrefs.get("sponsoredTopSites")) {
       sites = sites.filter(site => !site.sponsored_position);
     }
 
     // This is done here, rather than in the global scope, because
     // TOP_SITES_DEFAULT_ROWS causes the import of Reducers.jsm, and we want to
     // do that only when actually querying for Top Sites.
     if (this.topSitesRows === undefined) {
       XPCOMUtils.defineLazyPreferenceGetter(
         this,
         "topSitesRows",
         "browser.newtabpage.activity-stream.topSitesRows",
-        TOP_SITES_DEFAULT_ROWS
+        lazy.TOP_SITES_DEFAULT_ROWS
       );
     }
 
     // We usually respect maxRichResults, though we never show a number of Top
     // Sites greater than what is visible in the New Tab Page, because the
     // additional ones couldn't be managed from the page.
     let numTopSites = Math.min(
-      UrlbarPrefs.get("maxRichResults"),
-      TOP_SITES_MAX_SITES_PER_ROW * this.topSitesRows
+      lazy.UrlbarPrefs.get("maxRichResults"),
+      lazy.TOP_SITES_MAX_SITES_PER_ROW * this.topSitesRows
     );
     sites = sites.slice(0, numTopSites);
 
     let sponsoredSites = [];
     let index = 1;
     sites = sites.map(link => {
       let site = {
         type: link.searchTopSite ? "search" : "url",
@@ -209,90 +213,93 @@ class ProviderTopSites extends UrlbarPro
           };
           if (site.isSponsored) {
             payload = {
               ...payload,
               sponsoredTileId: site.sponsoredTileId,
               sponsoredClickUrl: site.sponsoredClickUrl,
             };
           }
-          let result = new UrlbarResult(
+          let result = new lazy.UrlbarResult(
             UrlbarUtils.RESULT_TYPE.URL,
             UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
-            ...UrlbarResult.payloadAndSimpleHighlights(
+            ...lazy.UrlbarResult.payloadAndSimpleHighlights(
               queryContext.tokens,
               payload
             )
           );
 
           let tabs;
-          if (UrlbarPrefs.get("suggest.openpage")) {
-            tabs = UrlbarProviderOpenTabs.getOpenTabs(
+          if (lazy.UrlbarPrefs.get("suggest.openpage")) {
+            tabs = lazy.UrlbarProviderOpenTabs.getOpenTabs(
               queryContext.userContextId || 0,
               queryContext.isPrivate
             );
           }
 
           if (tabs && tabs.includes(site.url.replace(/#.*$/, ""))) {
             result.type = UrlbarUtils.RESULT_TYPE.TAB_SWITCH;
             result.source = UrlbarUtils.RESULT_SOURCE.TABS;
-          } else if (UrlbarPrefs.get("suggest.bookmark")) {
-            let bookmark = await PlacesUtils.bookmarks.fetch({
+          } else if (lazy.UrlbarPrefs.get("suggest.bookmark")) {
+            let bookmark = await lazy.PlacesUtils.bookmarks.fetch({
               url: new URL(result.payload.url),
             });
             if (bookmark) {
               result.source = UrlbarUtils.RESULT_SOURCE.BOOKMARKS;
             }
           }
 
           // Our query has been cancelled.
           if (instance != this.queryInstance) {
             break;
           }
 
           addCallback(this, result);
           break;
         }
         case "search": {
-          let engine = await UrlbarSearchUtils.engineForAlias(site.title);
+          let engine = await lazy.UrlbarSearchUtils.engineForAlias(site.title);
 
           if (!engine && site.url) {
             // Look up the engine by its domain.
             let host;
             try {
               host = new URL(site.url).hostname;
             } catch (err) {}
             if (host) {
               engine = (
-                await UrlbarSearchUtils.enginesForDomainPrefix(host)
+                await lazy.UrlbarSearchUtils.enginesForDomainPrefix(host)
               )[0];
             }
           }
 
           if (!engine) {
             // No engine found. We skip this Top Site.
             break;
           }
 
           if (instance != this.queryInstance) {
             break;
           }
 
-          let result = new UrlbarResult(
+          let result = new lazy.UrlbarResult(
             UrlbarUtils.RESULT_TYPE.SEARCH,
             UrlbarUtils.RESULT_SOURCE.SEARCH,
-            ...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
-              title: site.title,
-              keyword: site.title,
-              providesSearchMode: true,
-              engine: engine.name,
-              query: "",
-              icon: site.favicon,
-              isPinned: site.isPinned,
-            })
+            ...lazy.UrlbarResult.payloadAndSimpleHighlights(
+              queryContext.tokens,
+              {
+                title: site.title,
+                keyword: site.title,
+                providesSearchMode: true,
+                engine: engine.name,
+                query: "",
+                icon: site.favicon,
+                isPinned: site.isPinned,
+              }
+            )
           );
           addCallback(this, result);
           break;
         }
         default:
           this.logger.error(`Unknown Top Site type: ${site.type}`);
           break;
       }
@@ -320,25 +327,25 @@ class ProviderTopSites extends UrlbarPro
       ["engagement", "abandonment"].includes(state)
     ) {
       for (let site of this.sponsoredSites) {
         Services.telemetry.keyedScalarAdd(
           SCALAR_CATEGORY_TOPSITES,
           `urlbar_${site.position}`,
           1
         );
-        PartnerLinkAttribution.sendContextualServicesPing(
+        lazy.PartnerLinkAttribution.sendContextualServicesPing(
           {
             source: "urlbar",
             tile_id: site.sponsoredTileId || -1,
             position: site.position,
             reporting_url: site.sponsoredImpressionUrl,
             advertiser: site.title.toLocaleLowerCase(),
           },
-          CONTEXTUAL_SERVICES_PING_TYPES.TOPSITES_IMPRESSION
+          lazy.CONTEXTUAL_SERVICES_PING_TYPES.TOPSITES_IMPRESSION
         );
       }
     }
 
     this.sponsoredSites = null;
   }
 
   /**
--- a/browser/components/urlbar/UrlbarProviderUnitConversion.jsm
+++ b/browser/components/urlbar/UrlbarProviderUnitConversion.jsm
@@ -8,29 +8,40 @@
  * Provide unit converter.
  */
 
 const EXPORTED_SYMBOLS = ["UrlbarProviderUnitConversion"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
-XPCOMUtils.defineLazyModuleGetters(this, {
-  UnitConverterSimple: "resource:///modules/UnitConverterSimple.jsm",
-  UnitConverterTemperature: "resource:///modules/UnitConverterTemperature.jsm",
-  UnitConverterTimezone: "resource:///modules/UnitConverterTimezone.jsm",
+
+const { UnitConverterSimple } = ChromeUtils.import(
+  "resource:///modules/UnitConverterSimple.jsm"
+);
+const { UnitConverterTemperature } = ChromeUtils.import(
+  "resource:///modules/UnitConverterTemperature.jsm"
+);
+const { UnitConverterTimezone } = ChromeUtils.import(
+  "resource:///modules/UnitConverterTimezone.jsm"
+);
+const { UrlbarProvider, UrlbarUtils } = ChromeUtils.import(
+  "resource:///modules/UrlbarUtils.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
-  UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarResult: "resource:///modules/UrlbarResult.jsm",
-  UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
   UrlbarView: "resource:///modules/UrlbarView.jsm",
 });
 
 XPCOMUtils.defineLazyServiceGetter(
-  this,
+  lazy,
   "ClipboardHelper",
   "@mozilla.org/widget/clipboardhelper;1",
   "nsIClipboardHelper"
 );
 
 const CONVERTERS = [
   new UnitConverterSimple(),
   new UnitConverterTemperature(),
@@ -70,18 +81,18 @@ const VIEW_TEMPLATE = {
 };
 
 /**
  * Provide a feature that converts given units.
  */
 class ProviderUnitConversion extends UrlbarProvider {
   constructor() {
     super();
-    UrlbarResult.addDynamicResultType(DYNAMIC_RESULT_TYPE);
-    UrlbarView.addDynamicViewTemplate(DYNAMIC_RESULT_TYPE, VIEW_TEMPLATE);
+    lazy.UrlbarResult.addDynamicResultType(DYNAMIC_RESULT_TYPE);
+    lazy.UrlbarView.addDynamicViewTemplate(DYNAMIC_RESULT_TYPE, VIEW_TEMPLATE);
   }
 
   /**
    * Returns the name of this provider.
    * @returns {string} the name of this provider.
    */
   get name() {
     return "UnitConversion";
@@ -101,17 +112,17 @@ class ProviderUnitConversion extends Url
    * provider, to save on resources.
    *
    * @param {UrlbarQueryContext} queryContext
    *   The query context object.
    * @returns {boolean}
    *   Whether this provider should be invoked for the search.
    */
   isActive({ searchString }) {
-    if (!UrlbarPrefs.get("unitConversion.enabled")) {
+    if (!lazy.UrlbarPrefs.get("unitConversion.enabled")) {
       return false;
     }
 
     for (const converter of CONVERTERS) {
       const result = converter.convert(searchString);
       if (result) {
         this._activeResult = result;
         return true;
@@ -149,31 +160,33 @@ class ProviderUnitConversion extends Url
    * each extension provider's results.  It fires the resultsRequested event.
    *
    * @param {UrlbarQueryContext} queryContext
    *   The query context object.
    * @param {function} addCallback
    *   The callback invoked by this method to add each result.
    */
   startQuery(queryContext, addCallback) {
-    const result = new UrlbarResult(
+    const result = new lazy.UrlbarResult(
       UrlbarUtils.RESULT_TYPE.DYNAMIC,
       UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
       {
         dynamicType: DYNAMIC_RESULT_TYPE,
         output: this._activeResult,
         input: queryContext.searchString,
       }
     );
-    result.suggestedIndex = UrlbarPrefs.get("unitConversion.suggestedIndex");
+    result.suggestedIndex = lazy.UrlbarPrefs.get(
+      "unitConversion.suggestedIndex"
+    );
 
     addCallback(this, result);
   }
 
   pickResult(result, element) {
     const { textContent } = element.querySelector(
       ".urlbarView-dynamic-unitConversion-output"
     );
-    ClipboardHelper.copyString(textContent);
+    lazy.ClipboardHelper.copyString(textContent);
   }
 }
 
 const UrlbarProviderUnitConversion = new ProviderUnitConversion();
--- a/browser/components/urlbar/UrlbarProvidersManager.jsm
+++ b/browser/components/urlbar/UrlbarProvidersManager.jsm
@@ -9,30 +9,31 @@
  * the connection between such providers and a UrlbarController.
  */
 
 var EXPORTED_SYMBOLS = ["UrlbarProvidersManager"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
-XPCOMUtils.defineLazyModuleGetters(this, {
+const lazy = {};
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   ObjectUtils: "resource://gre/modules/ObjectUtils.jsm",
   PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
   SkippableTimer: "resource:///modules/UrlbarUtils.jsm",
   UrlbarMuxer: "resource:///modules/UrlbarUtils.jsm",
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
   UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
   UrlbarSearchUtils: "resource:///modules/UrlbarSearchUtils.jsm",
   UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.jsm",
   UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
 });
 
-XPCOMUtils.defineLazyGetter(this, "logger", () =>
-  UrlbarUtils.getLogger({ prefix: "ProvidersManager" })
+XPCOMUtils.defineLazyGetter(lazy, "logger", () =>
+  lazy.UrlbarUtils.getLogger({ prefix: "ProvidersManager" })
 );
 
 // List of available local providers, each is implemented in its own jsm module
 // and will track different queries internally by queryContext.
 var localProviderModules = {
   UrlbarProviderAboutPages: "resource:///modules/UrlbarProviderAboutPages.jsm",
   UrlbarProviderAliasEngines:
     "resource:///modules/UrlbarProviderAliasEngines.jsm",
@@ -112,43 +113,45 @@ class ProvidersManager {
     }
   }
 
   /**
    * Registers a provider object with the manager.
    * @param {object} provider
    */
   registerProvider(provider) {
-    if (!provider || !(provider instanceof UrlbarProvider)) {
+    if (!provider || !(provider instanceof lazy.UrlbarProvider)) {
       throw new Error(`Trying to register an invalid provider`);
     }
-    if (!Object.values(UrlbarUtils.PROVIDER_TYPE).includes(provider.type)) {
+    if (
+      !Object.values(lazy.UrlbarUtils.PROVIDER_TYPE).includes(provider.type)
+    ) {
       throw new Error(`Unknown provider type ${provider.type}`);
     }
-    logger.info(`Registering provider ${provider.name}`);
+    lazy.logger.info(`Registering provider ${provider.name}`);
     let index = -1;
-    if (provider.type == UrlbarUtils.PROVIDER_TYPE.HEURISTIC) {
+    if (provider.type == lazy.UrlbarUtils.PROVIDER_TYPE.HEURISTIC) {
       // Keep heuristic providers in order at the front of the array.  Find the
       // first non-heuristic provider and insert the new provider there.
       index = this.providers.findIndex(
-        p => p.type != UrlbarUtils.PROVIDER_TYPE.HEURISTIC
+        p => p.type != lazy.UrlbarUtils.PROVIDER_TYPE.HEURISTIC
       );
     }
     if (index < 0) {
       index = this.providers.length;
     }
     this.providers.splice(index, 0, provider);
   }
 
   /**
    * Unregisters a previously registered provider object.
    * @param {object} provider
    */
   unregisterProvider(provider) {
-    logger.info(`Unregistering provider ${provider.name}`);
+    lazy.logger.info(`Unregistering provider ${provider.name}`);
     let index = this.providers.findIndex(p => p.name == provider.name);
     if (index != -1) {
       this.providers.splice(index, 1);
     }
   }
 
   /**
    * Returns the provider with the given name.
@@ -159,95 +162,95 @@ class ProvidersManager {
     return this.providers.find(p => p.name == name);
   }
 
   /**
    * Registers a muxer object with the manager.
    * @param {object} muxer a UrlbarMuxer object
    */
   registerMuxer(muxer) {
-    if (!muxer || !(muxer instanceof UrlbarMuxer)) {
+    if (!muxer || !(muxer instanceof lazy.UrlbarMuxer)) {
       throw new Error(`Trying to register an invalid muxer`);
     }
-    logger.info(`Registering muxer ${muxer.name}`);
+    lazy.logger.info(`Registering muxer ${muxer.name}`);
     this.muxers.set(muxer.name, muxer);
   }
 
   /**
    * Unregisters a previously registered muxer object.
    * @param {object} muxer a UrlbarMuxer object or name.
    */
   unregisterMuxer(muxer) {
     let muxerName = typeof muxer == "string" ? muxer : muxer.name;
-    logger.info(`Unregistering muxer ${muxerName}`);
+    lazy.logger.info(`Unregistering muxer ${muxerName}`);
     this.muxers.delete(muxerName);
   }
 
   /**
    * Starts querying.
    * @param {object} queryContext The query context object
    * @param {object} [controller] a UrlbarController instance
    */
   async startQuery(queryContext, controller = null) {
-    logger.info(`Query start ${queryContext.searchString}`);
+    lazy.logger.info(`Query start ${queryContext.searchString}`);
 
     // Define the muxer to use.
     let muxerName = queryContext.muxer || DEFAULT_MUXER;
-    logger.info(`Using muxer ${muxerName}`);
+    lazy.logger.info(`Using muxer ${muxerName}`);
     let muxer = this.muxers.get(muxerName);
     if (!muxer) {
       throw new Error(`Muxer with name ${muxerName} not found`);
     }
 
     // If the queryContext specifies a list of providers to use, filter on it,
     // otherwise just pass the full list of providers.
     let providers = queryContext.providers
       ? this.providers.filter(p => queryContext.providers.includes(p.name))
       : this.providers;
 
     // Apply tokenization.
-    UrlbarTokenizer.tokenize(queryContext);
+    lazy.UrlbarTokenizer.tokenize(queryContext);
 
     // If there's a single source, we are in restriction mode.
     if (queryContext.sources && queryContext.sources.length == 1) {
       queryContext.restrictSource = queryContext.sources[0];
     }
     // Providers can use queryContext.sources to decide whether they want to be
     // invoked or not.
     // The sources may be defined in the context, then the whole search string
     // can be used for searching. Otherwise sources are extracted from prefs and
     // restriction tokens, then restriction tokens must be filtered out of the
     // search string.
     let restrictToken = updateSourcesIfEmpty(queryContext);
     if (restrictToken) {
       queryContext.restrictToken = restrictToken;
       // If the restriction token has an equivalent source, then set it as
       // restrictSource.
-      if (UrlbarTokenizer.SEARCH_MODE_RESTRICT.has(restrictToken.value)) {
+      if (lazy.UrlbarTokenizer.SEARCH_MODE_RESTRICT.has(restrictToken.value)) {
         queryContext.restrictSource = queryContext.sources[0];
       }
     }
-    logger.debug(`Context sources ${queryContext.sources}`);
+    lazy.logger.debug(`Context sources ${queryContext.sources}`);
 
     let query = new Query(queryContext, controller, muxer, providers);
     this.queries.set(queryContext, query);
 
     // The muxer and many providers depend on the search service and our search
     // utils.  Make sure they're initialized now (via UrlbarSearchUtils) so that
     // all query-related urlbar modules don't need to do it.
-    await UrlbarSearchUtils.init();
+    await lazy.UrlbarSearchUtils.init();
     if (query.canceled) {
       return;
     }
 
     // Update the behavior of extension providers.
     let updateBehaviorPromises = [];
     for (let provider of this.providers) {
       if (
-        provider.type == UrlbarUtils.PROVIDER_TYPE.EXTENSION &&
+        provider.type == lazy.UrlbarUtils.PROVIDER_TYPE.EXTENSION &&
         provider.name != "Omnibox"
       ) {
         updateBehaviorPromises.push(
           provider.tryMethod("updateBehavior", queryContext)
         );
       }
     }
     if (updateBehaviorPromises.length) {
@@ -260,25 +263,25 @@ class ProvidersManager {
     await query.start();
   }
 
   /**
    * Cancels a running query.
    * @param {object} queryContext
    */
   cancelQuery(queryContext) {
-    logger.info(`Query cancel "${queryContext.searchString}"`);
+    lazy.logger.info(`Query cancel "${queryContext.searchString}"`);
     let query = this.queries.get(queryContext);
     if (!query) {
       throw new Error("Couldn't find a matching query for the given context");
     }
     query.cancel();
     if (!this.interruptLevel) {
       try {
-        let db = PlacesUtils.promiseLargeCacheDBConnection();
+        let db = lazy.PlacesUtils.promiseLargeCacheDBConnection();
         db.interrupt();
       } catch (ex) {}
     }
     this.queries.delete(queryContext);
   }
 
   /**
    * A provider can use this util when it needs to run a SQL query that can't
@@ -402,17 +405,17 @@ class Query {
                 }
                 activeProviders.push(provider);
                 if (provider.deferUserSelection) {
                   this.context.deferUserSelectionProviders.add(provider.name);
                 }
               }
             }
           })
-          .catch(ex => logger.error(ex))
+          .catch(ex => lazy.logger.error(ex))
       );
     }
 
     // We have to wait for all isActive calls to finish because we want to query
     // only the highest priority active providers as determined by the priority
     // logic above.
     await Promise.all(activePromises);
 
@@ -431,39 +434,39 @@ class Query {
       });
       if (!addedResult) {
         this.context.deferUserSelectionProviders.delete(provider.name);
       }
     };
 
     let queryPromises = [];
     for (let provider of activeProviders) {
-      if (provider.type == UrlbarUtils.PROVIDER_TYPE.HEURISTIC) {
+      if (provider.type == lazy.UrlbarUtils.PROVIDER_TYPE.HEURISTIC) {
         this.context.pendingHeuristicProviders.add(provider.name);
         queryPromises.push(startQuery(provider));
         continue;
       }
       if (!this._sleepTimer) {
         // Tracks the delay timer. We will fire (in this specific case, cancel
         // would do the same, since the callback is empty) the timer when the
         // search is canceled, unblocking start().
-        this._sleepTimer = new SkippableTimer({
+        this._sleepTimer = new lazy.SkippableTimer({
           name: "Query provider timer",
-          time: UrlbarPrefs.get("delay"),
+          time: lazy.UrlbarPrefs.get("delay"),
           logger: provider.logger,
         });
       }
       queryPromises.push(
         this._sleepTimer.promise.then(() =>
           this.canceled ? undefined : startQuery(provider)
         )
       );
     }
 
-    logger.info(`Queried ${queryPromises.length} providers`);
+    lazy.logger.info(`Queried ${queryPromises.length} providers`);
     await Promise.all(queryPromises);
 
     // All the providers are done returning results, so we can stop chunking.
     if (!this.canceled) {
       if (this._heuristicProviderTimer) {
         await this._heuristicProviderTimer.fire();
       }
       if (this._chunkTimer) {
@@ -489,33 +492,33 @@ class Query {
       provider.logger.info(
         `Canceling query for "${this.context.searchString}"`
       );
       // Mark the instance as no more valid, see start() for details.
       provider.queryInstance = null;
       provider.tryMethod("cancelQuery", this.context);
     }
     if (this._heuristicProviderTimer) {
-      this._heuristicProviderTimer.cancel().catch(ex => logger.error(ex));
+      this._heuristicProviderTimer.cancel().catch(ex => lazy.logger.error(ex));
     }
     if (this._chunkTimer) {
-      this._chunkTimer.cancel().catch(ex => logger.error(ex));
+      this._chunkTimer.cancel().catch(ex => lazy.logger.error(ex));
     }
     if (this._sleepTimer) {
-      this._sleepTimer.fire().catch(ex => logger.error(ex));
+      this._sleepTimer.fire().catch(ex => lazy.logger.error(ex));
     }
   }
 
   /**
    * Adds a result returned from a provider to the results set.
    * @param {object} provider
    * @param {object} result
    */
   add(provider, result) {
-    if (!(provider instanceof UrlbarProvider)) {
+    if (!(provider instanceof lazy.UrlbarProvider)) {
       throw new Error("Invalid provider passed to the add callback");
     }
 
     // When this set is empty, we can display heuristic results early. We remove
     // the provider from the list without checking result.heuristic since
     // heuristic providers don't necessarily have to return heuristic results.
     // We expect a provider with type HEURISTIC will return its heuristic
     // result(s) first.
@@ -540,31 +543,31 @@ class Query {
     }
 
     // Check if the result source should be filtered out. Pay attention to the
     // heuristic result though, that is supposed to be added regardless.
     if (
       !this.acceptableSources.includes(result.source) &&
       !result.heuristic &&
       // Treat form history as searches for the purpose of acceptableSources.
-      (result.type != UrlbarUtils.RESULT_TYPE.SEARCH ||
-        result.source != UrlbarUtils.RESULT_SOURCE.HISTORY ||
-        !this.acceptableSources.includes(UrlbarUtils.RESULT_SOURCE.SEARCH))
+      (result.type != lazy.UrlbarUtils.RESULT_TYPE.SEARCH ||
+        result.source != lazy.UrlbarUtils.RESULT_SOURCE.HISTORY ||
+        !this.acceptableSources.includes(lazy.UrlbarUtils.RESULT_SOURCE.SEARCH))
     ) {
       return;
     }
 
     // Filter out javascript results for safety. The provider is supposed to do
     // it, but we don't want to risk leaking these out.
     if (
-      result.type != UrlbarUtils.RESULT_TYPE.KEYWORD &&
+      result.type != lazy.UrlbarUtils.RESULT_TYPE.KEYWORD &&
       result.payload.url &&
       result.payload.url.startsWith("javascript:") &&
       !this.context.searchString.startsWith("javascript:") &&
-      UrlbarPrefs.get("filter.javascript")
+      lazy.UrlbarPrefs.get("filter.javascript")
     ) {
       return;
     }
 
     result.providerName = provider.name;
     result.providerType = provider.type;
     this.context.results.push(result);
 
@@ -574,69 +577,69 @@ class Query {
   _notifyResultsFromProvider(provider) {
     // We create two chunking timers: one for heuristic results, and one for
     // other results. We expect heuristic providers to return their heuristic
     // results before other results/providers in most cases. When all heuristic
     // providers have returned some results, we fire the heuristic timer early.
     // If the timer fires first, we stop waiting on the remaining heuristic
     // providers.
     // Both timers are used to reduce UI flicker.
-    if (provider.type == UrlbarUtils.PROVIDER_TYPE.HEURISTIC) {
+    if (provider.type == lazy.UrlbarUtils.PROVIDER_TYPE.HEURISTIC) {
       if (!this._heuristicProviderTimer) {
-        this._heuristicProviderTimer = new SkippableTimer({
+        this._heuristicProviderTimer = new lazy.SkippableTimer({
           name: "Heuristic provider timer",
           callback: () => this._notifyResults(),
           time: CHUNK_RESULTS_DELAY_MS,
           logger: provider.logger,
         });
       }
     } else if (!this._chunkTimer) {
-      this._chunkTimer = new SkippableTimer({
+      this._chunkTimer = new lazy.SkippableTimer({
         name: "Query chunk timer",
         callback: () => this._notifyResults(),
         time: CHUNK_RESULTS_DELAY_MS,
         logger: provider.logger,
       });
     }
     // If all active heuristic providers have returned results, we can skip the
     // heuristic results timer and start showing results immediately.
     if (
       this._heuristicProviderTimer &&
       !this.context.pendingHeuristicProviders.size
     ) {
-      this._heuristicProviderTimer.fire().catch(ex => logger.error(ex));
+      this._heuristicProviderTimer.fire().catch(ex => lazy.logger.error(ex));
     }
   }
 
   _notifyResults() {
     this.muxer.sort(this.context);
 
     if (this._heuristicProviderTimer) {
-      this._heuristicProviderTimer.cancel().catch(ex => logger.error(ex));
+      this._heuristicProviderTimer.cancel().catch(ex => lazy.logger.error(ex));
       this._heuristicProviderTimer = null;
     }
 
     if (this._chunkTimer) {
-      this._chunkTimer.cancel().catch(ex => logger.error(ex));
+      this._chunkTimer.cancel().catch(ex => lazy.logger.error(ex));
       this._chunkTimer = null;
     }
 
     // Before the muxer.sort call above, this.context.results should never be
     // empty since this method is called when results are added.  But the muxer
     // may have excluded one or more results from the final sorted list.  For
     // example, it excludes the "Search in a Private Window" result if it's the
     // only result that's been added so far.  We don't want to notify consumers
     // if there are no results since they generally expect at least one result
     // when notified, so bail, but only after nulling out the chunk timer above
     // so that it will be restarted the next time results are added.
     if (!this.context.results.length) {
       return;
     }
 
-    this.context.firstResultChanged = !ObjectUtils.deepEqual(
+    this.context.firstResultChanged = !lazy.ObjectUtils.deepEqual(
       this.context.firstResult,
       this.context.results[0]
     );
     this.context.firstResult = this.context.results[0];
 
     if (this.controller) {
       this.controller.receiveResults(this.context);
     }
@@ -652,86 +655,86 @@ class Query {
 function updateSourcesIfEmpty(context) {
   if (context.sources && context.sources.length) {
     return false;
   }
   let acceptedSources = [];
   // There can be only one restrict token per query.
   let restrictToken = context.tokens.find(t =>
     [
-      UrlbarTokenizer.TYPE.RESTRICT_HISTORY,
-      UrlbarTokenizer.TYPE.RESTRICT_BOOKMARK,
-      UrlbarTokenizer.TYPE.RESTRICT_TAG,
-      UrlbarTokenizer.TYPE.RESTRICT_OPENPAGE,
-      UrlbarTokenizer.TYPE.RESTRICT_SEARCH,
-      UrlbarTokenizer.TYPE.RESTRICT_TITLE,
-      UrlbarTokenizer.TYPE.RESTRICT_URL,
-      UrlbarTokenizer.TYPE.RESTRICT_ACTION,
+      lazy.UrlbarTokenizer.TYPE.RESTRICT_HISTORY,
+      lazy.UrlbarTokenizer.TYPE.RESTRICT_BOOKMARK,
+      lazy.UrlbarTokenizer.TYPE.RESTRICT_TAG,
+      lazy.UrlbarTokenizer.TYPE.RESTRICT_OPENPAGE,
+      lazy.UrlbarTokenizer.TYPE.RESTRICT_SEARCH,
+      lazy.UrlbarTokenizer.TYPE.RESTRICT_TITLE,
+      lazy.UrlbarTokenizer.TYPE.RESTRICT_URL,
+      lazy.UrlbarTokenizer.TYPE.RESTRICT_ACTION,
     ].includes(t.type)
   );
 
   // RESTRICT_TITLE and RESTRICT_URL do not affect query sources.
   let restrictTokenType =
     restrictToken &&
-    restrictToken.type != UrlbarTokenizer.TYPE.RESTRICT_TITLE &&
-    restrictToken.type != UrlbarTokenizer.TYPE.RESTRICT_URL
+    restrictToken.type != lazy.UrlbarTokenizer.TYPE.RESTRICT_TITLE &&
+    restrictToken.type != lazy.UrlbarTokenizer.TYPE.RESTRICT_URL
       ? restrictToken.type
       : undefined;
 
-  for (let source of Object.values(UrlbarUtils.RESULT_SOURCE)) {
+  for (let source of Object.values(lazy.UrlbarUtils.RESULT_SOURCE)) {
     // Skip sources that the context doesn't care about.
     if (context.sources && !context.sources.includes(source)) {
       continue;
     }
     // Check prefs and restriction tokens.
     switch (source) {
-      case UrlbarUtils.RESULT_SOURCE.BOOKMARKS:
+      case lazy.UrlbarUtils.RESULT_SOURCE.BOOKMARKS:
         if (
-          restrictTokenType === UrlbarTokenizer.TYPE.RESTRICT_BOOKMARK ||
-          restrictTokenType === UrlbarTokenizer.TYPE.RESTRICT_TAG ||
-          (!restrictTokenType && UrlbarPrefs.get("suggest.bookmark"))
+          restrictTokenType === lazy.UrlbarTokenizer.TYPE.RESTRICT_BOOKMARK ||
+          restrictTokenType === lazy.UrlbarTokenizer.TYPE.RESTRICT_TAG ||
+          (!restrictTokenType && lazy.UrlbarPrefs.get("suggest.bookmark"))
         ) {
           acceptedSources.push(source);
         }
         break;
-      case UrlbarUtils.RESULT_SOURCE.HISTORY:
+      case lazy.UrlbarUtils.RESULT_SOURCE.HISTORY:
         if (
-          restrictTokenType === UrlbarTokenizer.TYPE.RESTRICT_HISTORY ||
-          (!restrictTokenType && UrlbarPrefs.get("suggest.history"))
+          restrictTokenType === lazy.UrlbarTokenizer.TYPE.RESTRICT_HISTORY ||
+          (!restrictTokenType && lazy.UrlbarPrefs.get("suggest.history"))
         ) {
           acceptedSources.push(source);
         }
         break;
-      case UrlbarUtils.RESULT_SOURCE.SEARCH:
+      case lazy.UrlbarUtils.RESULT_SOURCE.SEARCH:
         if (
-          restrictTokenType === UrlbarTokenizer.TYPE.RESTRICT_SEARCH ||
+          restrictTokenType === lazy.UrlbarTokenizer.TYPE.RESTRICT_SEARCH ||
           !restrictTokenType
         ) {
           // We didn't check browser.urlbar.suggest.searches here, because it
           // just controls search suggestions. If a search suggestion arrives
           // here, we lost already, because we broke user's privacy by hitting
           // the network. Thus, it's better to leave things go through and
           // notice the bug, rather than hiding it with a filter.
           acceptedSources.push(source);
         }
         break;
-      case UrlbarUtils.RESULT_SOURCE.TABS:
+      case lazy.UrlbarUtils.RESULT_SOURCE.TABS:
         if (
-          restrictTokenType === UrlbarTokenizer.TYPE.RESTRICT_OPENPAGE ||
-          (!restrictTokenType && UrlbarPrefs.get("suggest.openpage"))
+          restrictTokenType === lazy.UrlbarTokenizer.TYPE.RESTRICT_OPENPAGE ||
+          (!restrictTokenType && lazy.UrlbarPrefs.get("suggest.openpage"))
         ) {
           acceptedSources.push(source);
         }
         break;
-      case UrlbarUtils.RESULT_SOURCE.OTHER_NETWORK:
+      case lazy.UrlbarUtils.RESULT_SOURCE.OTHER_NETWORK:
         if (!context.isPrivate && !restrictTokenType) {
           acceptedSources.push(source);
         }
         break;
-      case UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL:
+      case lazy.UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL:
       default:
         if (!restrictTokenType) {
           acceptedSources.push(source);
         }
         break;
     }
   }
   context.sources = acceptedSources;
--- a/browser/components/urlbar/UrlbarQuickSuggest.jsm
+++ b/browser/components/urlbar/UrlbarQuickSuggest.jsm
@@ -6,31 +6,36 @@
 
 const EXPORTED_SYMBOLS = ["ONBOARDING_CHOICE", "UrlbarQuickSuggest"];
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
-XPCOMUtils.defineLazyModuleGetters(this, {
+const { EventEmitter } = ChromeUtils.import(
+  "resource://gre/modules/EventEmitter.jsm"
+);
+
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
-  EventEmitter: "resource://gre/modules/EventEmitter.jsm",
   NimbusFeatures: "resource://nimbus/ExperimentAPI.jsm",
   QUICK_SUGGEST_SOURCE: "resource:///modules/UrlbarProviderQuickSuggest.jsm",
   RemoteSettings: "resource://services-settings/remote-settings.js",
   TaskQueue: "resource:///modules/UrlbarUtils.jsm",
   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
   UrlbarProviderQuickSuggest:
     "resource:///modules/UrlbarProviderQuickSuggest.jsm",
 });
 
 const log = console.createInstance({
   prefix: "QuickSuggest",
-  maxLogLevel: UrlbarPrefs.get("quicksuggest.log") ? "All" : "Warn",
+  maxLogLevel: lazy.UrlbarPrefs.get("quicksuggest.log") ? "All" : "Warn",
 });
 
 const RS_COLLECTION = "quicksuggest";
 
 // Categories that should show "Firefox Suggest" instead of "Sponsored"
 const NONSPONSORED_IAB_CATEGORIES = new Set(["5 - Education"]);
 
 const FEATURE_AVAILABLE = "quickSuggestEnabled";
@@ -66,18 +71,18 @@ const DEFAULT_SUGGESTION_SCORE = 0.2;
 const ADD_RESULTS_CHUNK_SIZE = 1000;
 
 /**
  * Fetches the suggestions data from RemoteSettings and builds the structures
  * to provide suggestions for UrlbarProviderQuickSuggest.
  */
 class QuickSuggest extends EventEmitter {
   init() {
-    UrlbarPrefs.addObserver(this);
-    NimbusFeatures.urlbar.onUpdate(() => this._queueSettingsSetup());
+    lazy.UrlbarPrefs.addObserver(this);
+    lazy.NimbusFeatures.urlbar.onUpdate(() => this._queueSettingsSetup());
 
     this._settingsTaskQueue.queue(() => {
       return new Promise(resolve => {
         Services.tm.idleDispatchToMainThread(() => {
           this._queueSettingsSetup();
           resolve();
         });
       });
@@ -166,17 +171,17 @@ class QuickSuggest extends EventEmitter 
       block_id: result.id,
       advertiser: result.advertiser,
       iab_category: result.iab_category,
       is_sponsored: !NONSPONSORED_IAB_CATEGORIES.has(result.iab_category),
       score:
         typeof result.score == "number"
           ? result.score
           : DEFAULT_SUGGESTION_SCORE,
-      source: QUICK_SUGGEST_SOURCE.REMOTE_SETTINGS,
+      source: lazy.QUICK_SUGGEST_SOURCE.REMOTE_SETTINGS,
       icon: icons.shift(),
       position: result.position,
       _test_is_best_match: result._test_is_best_match,
     }));
   }
 
   /**
    * Records the Nimbus exposure event if it hasn't already been recorded during
@@ -185,17 +190,17 @@ class QuickSuggest extends EventEmitter 
    */
   ensureExposureEventRecorded() {
     // `recordExposureEvent()` makes sure only one event is recorded per app
     // session even if it's called many times, but since it may be expensive, we
     // also keep `_recordedExposureEvent`.
     if (!this._recordedExposureEvent) {
       this._recordedExposureEvent = true;
       Services.tm.idleDispatchToMainThread(() =>
-        NimbusFeatures.urlbar.recordExposureEvent({ once: true })
+        lazy.NimbusFeatures.urlbar.recordExposureEvent({ once: true })
       );
     }
   }
 
   /**
    * Gets the full keyword (i.e., suggestion) for a result and query.  The data
    * doesn't include full keywords, so we make our own based on the result's
    * keyword phrases and a particular query.  We use two heuristics:
@@ -260,95 +265,95 @@ class QuickSuggest extends EventEmitter 
    *
    * @returns {boolean}
    *   True if the dialog was shown and false if not.
    */
   async maybeShowOnboardingDialog() {
     // The call to this method races scenario initialization on startup, and the
     // Nimbus variables we rely on below depend on the scenario, so wait for it
     // to be initialized.
-    await UrlbarPrefs.firefoxSuggestScenarioStartupPromise;
+    await lazy.UrlbarPrefs.firefoxSuggestScenarioStartupPromise;
 
     // If the feature is disabled, the user has already seen the dialog, or the
     // user has already opted in, don't show the onboarding.
     if (
-      !UrlbarPrefs.get(FEATURE_AVAILABLE) ||
-      UrlbarPrefs.get(SEEN_DIALOG_PREF) ||
-      UrlbarPrefs.get("quicksuggest.dataCollection.enabled")
+      !lazy.UrlbarPrefs.get(FEATURE_AVAILABLE) ||
+      lazy.UrlbarPrefs.get(SEEN_DIALOG_PREF) ||
+      lazy.UrlbarPrefs.get("quicksuggest.dataCollection.enabled")
     ) {
       return false;
     }
 
     // Wait a number of restarts before showing the dialog.
-    let restartsSeen = UrlbarPrefs.get(RESTARTS_PREF);
+    let restartsSeen = lazy.UrlbarPrefs.get(RESTARTS_PREF);
     if (
       restartsSeen <
-      UrlbarPrefs.get("quickSuggestShowOnboardingDialogAfterNRestarts")
+      lazy.UrlbarPrefs.get("quickSuggestShowOnboardingDialogAfterNRestarts")
     ) {
-      UrlbarPrefs.set(RESTARTS_PREF, restartsSeen + 1);
+      lazy.UrlbarPrefs.set(RESTARTS_PREF, restartsSeen + 1);
       return false;
     }
 
-    let win = BrowserWindowTracker.getTopWindow();
+    let win = lazy.BrowserWindowTracker.getTopWindow();
 
     // Don't show the dialog on top of about:welcome for new users.
     if (win.gBrowser?.currentURI?.spec == "about:welcome") {
       return false;
     }
 
-    if (UrlbarPrefs.get("experimentType") === "modal") {
+    if (lazy.UrlbarPrefs.get("experimentType") === "modal") {
       this.ensureExposureEventRecorded();
     }
 
-    if (!UrlbarPrefs.get("quickSuggestShouldShowOnboardingDialog")) {
+    if (!lazy.UrlbarPrefs.get("quickSuggestShouldShowOnboardingDialog")) {
       return false;
     }
 
     let variationType;
     try {
       // An error happens if the pref is not in user prefs.
-      variationType = UrlbarPrefs.get(DIALOG_VARIATION_PREF).toLowerCase();
+      variationType = lazy.UrlbarPrefs.get(DIALOG_VARIATION_PREF).toLowerCase();
     } catch (e) {}
 
     let params = { choice: undefined, variationType, visitedMain: false };
     await win.gDialogBox.open(ONBOARDING_URI, params);
 
-    UrlbarPrefs.set(SEEN_DIALOG_PREF, true);
-    UrlbarPrefs.set(
+    lazy.UrlbarPrefs.set(SEEN_DIALOG_PREF, true);
+