diff --git a/Build/Sources/TypeScript/core/document-service.ts b/Build/Sources/TypeScript/core/document-service.ts
index 7f07b17623ebdfd0e1351ac7645e5f6f03c02cf2..3d346a212d26dfe2942fd352067782e77357a90f 100644
--- a/Build/Sources/TypeScript/core/document-service.ts
+++ b/Build/Sources/TypeScript/core/document-service.ts
@@ -16,42 +16,18 @@
  * @exports @typo3/core/document-service
  */
 class DocumentService {
-  private readonly windowRef: Window;
-  private readonly documentRef: Document;
+  private promise: Promise<Document> = null;
 
-  /**
-   * @param {Window} windowRef
-   * @param {Document} documentRef
-   */
-  constructor(windowRef: Window = window, documentRef: Document = document) {
-    this.windowRef = windowRef;
-    this.documentRef = documentRef;
+  public ready(): Promise<Document> {
+    return this.promise ?? (this.promise = this.createPromise());
   }
 
-  ready(): Promise<Document> {
-    return new Promise<Document>((resolve: (document: Document) => void, reject: (document: Document) => void) => {
-      if (this.documentRef.readyState === 'complete') {
-        resolve(this.documentRef);
-      } else {
-        // timeout & reject after 30 seconds
-        const timer = setTimeout((): void => {
-          clearListeners();
-          reject(this.documentRef);
-        }, 30000);
-        const clearListeners = (): void => {
-          this.windowRef.removeEventListener('load', delegate);
-          this.documentRef.removeEventListener('DOMContentLoaded', delegate);
-        };
-        const delegate = (): void => {
-          clearListeners();
-          clearTimeout(timer);
-          resolve(this.documentRef);
-        };
-        this.windowRef.addEventListener('load', delegate);
-        this.documentRef.addEventListener('DOMContentLoaded', delegate);
-      }
-
-    });
+  private async createPromise(): Promise<Document> {
+    if (document.readyState !== 'loading') {
+      return document;
+    }
+    await new Promise<void>(resolve => document.addEventListener('DOMContentLoaded', () => resolve(), { once: true }));
+    return document;
   }
 }
 
diff --git a/typo3/sysext/core/Resources/Public/JavaScript/document-service.js b/typo3/sysext/core/Resources/Public/JavaScript/document-service.js
index 7264f00c773c0b7a8a5ad909b82bd59872032a6d..743ead5d53b406f8006e7d9810c5fd14514b20e8 100644
--- a/typo3/sysext/core/Resources/Public/JavaScript/document-service.js
+++ b/typo3/sysext/core/Resources/Public/JavaScript/document-service.js
@@ -10,4 +10,4 @@
  *
  * The TYPO3 project - inspiring people to share!
  */
-class DocumentService{constructor(e=window,t=document){this.windowRef=e,this.documentRef=t}ready(){return new Promise(((e,t)=>{if("complete"===this.documentRef.readyState)e(this.documentRef);else{const n=setTimeout((()=>{o(),t(this.documentRef)}),3e4),o=()=>{this.windowRef.removeEventListener("load",d),this.documentRef.removeEventListener("DOMContentLoaded",d)},d=()=>{o(),clearTimeout(n),e(this.documentRef)};this.windowRef.addEventListener("load",d),this.documentRef.addEventListener("DOMContentLoaded",d)}}))}}const documentService=new DocumentService;export default documentService;
\ No newline at end of file
+class DocumentService{constructor(){this.promise=null}ready(){return this.promise??(this.promise=this.createPromise())}async createPromise(){return"loading"!==document.readyState||await new Promise((e=>document.addEventListener("DOMContentLoaded",(()=>e()),{once:!0}))),document}}const documentService=new DocumentService;export default documentService;
\ No newline at end of file