diff --git a/src/Umbraco.Web.UI/umbraco/Views/Default.cshtml b/src/Umbraco.Web.UI/umbraco/Views/Default.cshtml
index f8b7eb86cf..677d28d362 100644
--- a/src/Umbraco.Web.UI/umbraco/Views/Default.cshtml
+++ b/src/Umbraco.Web.UI/umbraco/Views/Default.cshtml
@@ -43,6 +43,7 @@
+
Umbraco
diff --git a/src/Umbraco.Web/PublishedContentQuery.cs b/src/Umbraco.Web/PublishedContentQuery.cs
index bfe8fb5260..469d53f749 100644
--- a/src/Umbraco.Web/PublishedContentQuery.cs
+++ b/src/Umbraco.Web/PublishedContentQuery.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Xml.XPath;
@@ -224,14 +225,51 @@ namespace Umbraco.Web
{
var doc = cache.GetById(id);
return doc;
- }
+ }
+
+ private static readonly ConcurrentDictionary _guidToIntLoopkup = new ConcurrentDictionary();
private IPublishedContent TypedDocumentById(Guid id, ContextualPublishedCache cache)
- {
- // todo: in v8, implement in a more efficient way
- var legacyXml = UmbracoConfig.For.UmbracoSettings().Content.UseLegacyXmlSchema;
- var xpath = legacyXml ? "//node [@key=$guid]" : "//* [@key=$guid]";
- var doc = cache.GetSingleByXPath(xpath, new XPathVariable("guid", id.ToString()));
+ {
+ // Check if the loopkup is empty, if so populate it [LK]
+ if (_guidToIntLoopkup.Count == 0)
+ {
+ // TODO: Remove the debug profile logger
+ using (ApplicationContext.Current.ProfilingLogger.DebugDuration("Populate GUID/INT lookup"))
+ {
+ // NOTE, using the `@nodeTypeAlias` attribute in the XPath as this was support in both legacy & new schemas
+ var tmpNodes = cache.GetXPathNavigator().Select("//*[@nodeTypeAlias]");
+ foreach (XPathNavigator tmpNode in tmpNodes)
+ {
+ if (int.TryParse(tmpNode.GetAttribute("id", string.Empty), out int tmpNodeId)
+ && Guid.TryParse(tmpNode.GetAttribute("key", string.Empty), out Guid tmpNodeKey))
+ {
+ _guidToIntLoopkup[tmpNodeKey] = tmpNodeId;
+ }
+ }
+ }
+ }
+
+ IPublishedContent doc;
+
+ // Check if the lookup contains the GUID/INT value
+ if (_guidToIntLoopkup.TryGetValue(id, out int nodeId) == false)
+ {
+ // If not, then we perform an inefficient XPath for the GUID
+
+ // todo: in v8, implement in a more efficient way
+ doc = cache.GetSingleByXPath("//*[@key=$guid]", new XPathVariable("guid", id.ToString()));
+
+ // When we have the node, we add the GUID/INT value to the lookup
+ if (doc != null)
+ _guidToIntLoopkup[id] = doc.Id;
+ }
+ else
+ {
+ // Otherwise we have the node id (INT) and can perform an efficient retrieval
+ doc = cache.GetById(nodeId);
+ }
+
return doc;
}