diff --git a/typo3/sysext/core/Classes/Resource/ResourceCompressor.php b/typo3/sysext/core/Classes/Resource/ResourceCompressor.php
index 093adea2b83088d71191de1df7593b4feec63cc6..c24d4f5f9a3eb9049ba2c1ac4d79e7b180d03155 100644
--- a/typo3/sysext/core/Classes/Resource/ResourceCompressor.php
+++ b/typo3/sysext/core/Classes/Resource/ResourceCompressor.php
@@ -169,6 +169,8 @@ class ResourceCompressor
      */
     public function concatenateJsFiles(array $jsFiles)
     {
+        $concatenatedJsFileIsAsync = false;
+        $allFilesToConcatenateAreAsync = true;
         $filesToInclude = [];
         foreach ($jsFiles as $key => $fileOptions) {
             // invalid section found or no concatenation allowed, so continue
@@ -184,6 +186,11 @@ class ResourceCompressor
             } else {
                 $filesToInclude[$fileOptions['section']][] = $filenameFromMainDir;
             }
+            if (!empty($fileOptions['async']) && (bool)$fileOptions['async']) {
+                $concatenatedJsFileIsAsync = true;
+            } else {
+                $allFilesToConcatenateAreAsync = false;
+            }
             // remove the file from the incoming file array
             unset($jsFiles[$key]);
         }
@@ -197,7 +204,8 @@ class ResourceCompressor
                     'compress' => true,
                     'excludeFromConcatenation' => true,
                     'forceOnTop' => false,
-                    'allWrap' => ''
+                    'allWrap' => '',
+                    'async' => $concatenatedJsFileIsAsync && $allFilesToConcatenateAreAsync,
                 ];
                 // place the merged javascript on top of the JS files
                 $jsFiles = array_merge([$targetFile => $concatenatedOptions], $jsFiles);
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-83476-LoadMergedJSFilesAsynchronous.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-83476-LoadMergedJSFilesAsynchronous.rst
new file mode 100644
index 0000000000000000000000000000000000000000..da24a12e1cd8c740f360df598393d28bf705923b
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/master/Feature-83476-LoadMergedJSFilesAsynchronous.rst
@@ -0,0 +1,30 @@
+.. include:: ../../Includes.txt
+
+===================================================
+Feature: #83476 - Load merged JS files asynchronous
+===================================================
+
+See :issue:`83476`
+
+Description
+===========
+
+The async attribute is now assigned to the script tag of the concatenated JS files if all files have the async attribute enabled in TypoScript.
+
+Example:
+--------
+
+.. code-block:: typoscript
+
+   config.concatenateJs = 1
+
+   page = PAGE
+   page.includeJSFooter {
+       test = fileadmin/user_upload/test.js
+       test.async = 1
+
+       test2 = fileadmin/user_upload/test2.js
+       test2.async = 1
+   }
+
+.. index:: Frontend, TypoScript, ext:core
diff --git a/typo3/sysext/core/Tests/Unit/Resource/ResourceCompressorTest.php b/typo3/sysext/core/Tests/Unit/Resource/ResourceCompressorTest.php
index 97f12a3661dac74b7d455d76b615a1c4f30129d7..4c873a1be4fd2825c7342b84cad45c219e5907c5 100644
--- a/typo3/sysext/core/Tests/Unit/Resource/ResourceCompressorTest.php
+++ b/typo3/sysext/core/Tests/Unit/Resource/ResourceCompressorTest.php
@@ -287,7 +287,7 @@ class ResourceCompressorTest extends BaseTestCase
     /**
      * @test
      */
-    public function concatenatedJsFileIsFlaggedToNotConcatenateAgain(): void
+    public function concatenateJsFileIsFlaggedToNotConcatenateAgain(): void
     {
         $fileName = 'fooFile.js';
         $concatenatedFileName = 'merged_' . $fileName;
@@ -309,6 +309,133 @@ class ResourceCompressorTest extends BaseTestCase
         $this->assertTrue($result[$concatenatedFileName]['excludeFromConcatenation']);
     }
 
+    /**
+     * @return array
+     */
+    public function concatenateJsFileAsyncDataProvider(): array
+    {
+        return [
+            'all files have no async' => [
+                [
+                    [
+                        'file' => 'file1.js',
+                        'excludeFromConcatenation' => false,
+                        'section' => 'top',
+                    ],
+                    [
+                        'file' => 'file2.js',
+                        'excludeFromConcatenation' => false,
+                        'section' => 'top',
+                    ],
+                ],
+                false
+            ],
+            'all files have async false' => [
+                [
+                    [
+                        'file' => 'file1.js',
+                        'excludeFromConcatenation' => false,
+                        'section' => 'top',
+                        'async' => false,
+                    ],
+                    [
+                        'file' => 'file2.js',
+                        'excludeFromConcatenation' => false,
+                        'section' => 'top',
+                        'async' => false,
+                    ],
+                ],
+                false
+            ],
+            'all files have async true' => [
+                [
+                    [
+                        'file' => 'file1.js',
+                        'excludeFromConcatenation' => false,
+                        'section' => 'top',
+                        'async' => true,
+                    ],
+                    [
+                        'file' => 'file2.js',
+                        'excludeFromConcatenation' => false,
+                        'section' => 'top',
+                        'async' => true,
+                    ],
+                ],
+                true
+            ],
+            'one file async true and one file async false' => [
+                [
+                    [
+                        'file' => 'file1.js',
+                        'excludeFromConcatenation' => false,
+                        'section' => 'top',
+                        'async' => true,
+                    ],
+                    [
+                        'file' => 'file2.js',
+                        'excludeFromConcatenation' => false,
+                        'section' => 'top',
+                        'async' => false,
+                    ],
+                ],
+                false
+            ],
+            'one file async true and one file async false but is excluded form concatenation' => [
+                [
+                    [
+                        'file' => 'file1.js',
+                        'excludeFromConcatenation' => false,
+                        'section' => 'top',
+                        'async' => true,
+                    ],
+                    [
+                        'file' => 'file2.js',
+                        'excludeFromConcatenation' => true,
+                        'section' => 'top',
+                        'async' => false,
+                    ],
+                ],
+                true
+            ],
+            'one file async false and one file async true but is excluded form concatenation' => [
+                [
+                    [
+                        'file' => 'file1.js',
+                        'excludeFromConcatenation' => false,
+                        'section' => 'top',
+                        'async' => false,
+                    ],
+                    [
+                        'file' => 'file2.js',
+                        'excludeFromConcatenation' => true,
+                        'section' => 'top',
+                        'async' => true,
+                    ],
+                ],
+                false
+            ],
+        ];
+    }
+
+    /**
+     * @test
+     * @dataProvider concatenateJsFileAsyncDataProvider
+     * @param string $input
+     * @param bool $expected
+     */
+    public function concatenateJsFileAddsAsyncPropertyIfAllFilesAreAsync(array $input, bool $expected): void
+    {
+        $concatenatedFileName = 'merged_foo.js';
+        $this->subject->expects($this->once())
+            ->method('createMergedJsFile')
+            ->will($this->returnValue($concatenatedFileName));
+
+        $result = $this->subject->concatenateJsFiles($input);
+
+        $this->assertSame($expected, $result[$concatenatedFileName]['async']);
+    }
+
     /**
      * @return array
      */