diff --git a/typo3/sysext/core/Classes/Utility/RootlineUtility.php b/typo3/sysext/core/Classes/Utility/RootlineUtility.php
index a98d88d8e8afc462d678c219ccb7030ab23dc3b9..55079ba05e4744c57e738dd9958fb4094455e329 100644
--- a/typo3/sysext/core/Classes/Utility/RootlineUtility.php
+++ b/typo3/sysext/core/Classes/Utility/RootlineUtility.php
@@ -108,6 +108,11 @@ class RootlineUtility {
 	 */
 	protected $pageContext;
 
+	/**
+	 * @var string
+	 */
+	protected $cacheIdentifier;
+
 	/**
 	 * @var array
 	 */
@@ -162,6 +167,8 @@ class RootlineUtility {
 		self::$rootlineFields = array_merge(self::$rootlineFields, \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['addRootLineFields'], TRUE));
 		self::$rootlineFields = array_unique(self::$rootlineFields);
 		$this->databaseConnection = $GLOBALS['TYPO3_DB'];
+
+		$this->cacheIdentifier = $this->getCacheIdentifier();
 	}
 
 	/**
@@ -186,16 +193,31 @@ class RootlineUtility {
 	 * @return array
 	 */
 	public function get() {
-		$cacheIdentifier = $this->getCacheIdentifier();
-		if (!isset(self::$localCache[$cacheIdentifier])) {
-			$entry = self::$cache->get($cacheIdentifier);
+		if (!isset(static::$localCache[$this->cacheIdentifier])) {
+			$entry = static::$cache->get($this->cacheIdentifier);
 			if (!$entry) {
 				$this->generateRootlineCache();
 			} else {
-				self::$localCache[$cacheIdentifier] = $entry;
+				static::$localCache[$this->cacheIdentifier] = $entry;
+				$depth = count($entry);
+				// Populate the root-lines for parent pages as well
+				// since they are part of the current root-line
+				while ($depth > 1) {
+					--$depth;
+					$parentCacheIdentifier = $this->getCacheIdentifier($entry[$depth - 1]['uid']);
+					// Abort if the root-line of the parent page is
+					// already in the local cache data
+					if (isset(static::$localCache[$parentCacheIdentifier])) {
+						break;
+					}
+					// Behaves similar to array_shift(), but preserves
+					// the array keys - which contain the page ids here
+					$entry = array_slice($entry, 1, NULL, TRUE);
+					static::$localCache[$parentCacheIdentifier] = $entry;
+				}
 			}
 		}
-		return self::$localCache[$cacheIdentifier];
+		return static::$localCache[$this->cacheIdentifier];
 	}
 
 	/**
@@ -206,7 +228,8 @@ class RootlineUtility {
 	 * @return array
 	 */
 	protected function getRecordArray($uid) {
-		if (!isset(self::$pageRecordCache[$this->getCacheIdentifier($uid)])) {
+		$currentCacheIdentifier = $this->getCacheIdentifier($uid);
+		if (!isset(self::$pageRecordCache[$currentCacheIdentifier])) {
 			$row = $this->databaseConnection->exec_SELECTgetSingleRow(implode(',', self::$rootlineFields), 'pages', 'uid = ' . intval($uid) . ' AND pages.deleted = 0 AND pages.doktype <> ' . \TYPO3\CMS\Frontend\Page\PageRepository::DOKTYPE_RECYCLER);
 			if (empty($row)) {
 				throw new \RuntimeException('Could not fetch page data for uid ' . $uid . '.', 1343589451);
@@ -218,13 +241,13 @@ class RootlineUtility {
 					$row = $this->pageContext->getPageOverlay($row, $this->languageUid);
 				}
 				$row = $this->enrichWithRelationFields(isset($row['_PAGES_OVERLAY_UID']) ? $row['_PAGES_OVERLAY_UID'] : $uid, $row);
-				self::$pageRecordCache[$this->getCacheIdentifier($uid)] = $row;
+				self::$pageRecordCache[$currentCacheIdentifier] = $row;
 			}
 		}
-		if (!is_array(self::$pageRecordCache[$this->getCacheIdentifier($uid)])) {
+		if (!is_array(self::$pageRecordCache[$currentCacheIdentifier])) {
 			throw new \RuntimeException('Broken rootline. Could not resolve page with uid ' . $uid . '.', 1343464101);
 		}
-		return self::$pageRecordCache[$this->getCacheIdentifier($uid)];
+		return self::$pageRecordCache[$currentCacheIdentifier];
 	}
 
 	/**
@@ -334,8 +357,8 @@ class RootlineUtility {
 		}
 		array_push($rootline, $page);
 		krsort($rootline);
-		self::$cache->set($this->getCacheIdentifier(), $rootline, $cacheTags);
-		self::$localCache[$this->getCacheIdentifier()] = $rootline;
+		static::$cache->set($this->cacheIdentifier, $rootline, $cacheTags);
+		static::$localCache[$this->cacheIdentifier] = $rootline;
 	}
 
 	/**
diff --git a/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php b/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
index 258f462d7f8b2078332b8417bef2401fbee84f5a..15d0f177e6aa19d583d0f4b5b68f23794cdf38f6 100644
--- a/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
+++ b/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
@@ -741,6 +741,13 @@ class TypoScriptFrontendController {
 	 */
 	protected $cacheHash;
 
+	/**
+	 * Runtime cache of domains per processed page ids.
+	 *
+	 * @var array
+	 */
+	protected $domainDataCache = array();
+
 	/**
 	 * Class constructor
 	 * Takes a number of GET/POST input variable as arguments and stores them internally.
@@ -4920,19 +4927,25 @@ if (version == "n3") {
 	 * @return mixed Return domain data or NULL
 	*/
 	public function getDomainDataForPid($targetPid) {
-		$result = NULL;
-
-		$sysDomainData = $this->getSysDomainCache();
-		$rootline = $this->sys_page->getRootLine($targetPid);
-		// walk the rootline downwards from the target page to the root, until a domain record is found
-		foreach ($rootline as $pageInRootline) {
-			$pidInRootline = $pageInRootline['uid'];
-			if (isset($sysDomainData[$pidInRootline])) {
-				$result = $sysDomainData[$pidInRootline];
-				break;
+		// Using array_key_exists() here, nice $result can be NULL
+		// (happens, if there's no domain records defined)
+		if (!array_key_exists($targetPid, $this->domainDataCache)) {
+			$result = NULL;
+			$sysDomainData = $this->getSysDomainCache();
+			$rootline = $this->sys_page->getRootLine($targetPid);
+			// walk the rootline downwards from the target page
+			// to the root page, until a domain record is found
+			foreach ($rootline as $pageInRootline) {
+				$pidInRootline = $pageInRootline['uid'];
+				if (isset($sysDomainData[$pidInRootline])) {
+					$result = $sysDomainData[$pidInRootline];
+					break;
+				}
 			}
+			$this->domainDataCache[$targetPid] = $result;
 		}
-		return $result;
+
+		return $this->domainDataCache[$targetPid];
 	}
 
 	/**