Recursing through parent pages - Will this be a performance problem?

Vote:
 

I have a requirement to display Alerts on a website. Alerts should be defined at a parent page level, and cascade down to all child pages. Alerts may be defined on the homepage, on a landing page, or on an individual detail page. Only one alert should be displayed at a time.

I've come up with a solution that is working, but I fear I may have introduced a performance problem. My approach is a bit naive, but here's what I've done:

  1. Every page (including the homepage) has Content Area for "Alert Content"
  2. The "Alert Content" Content Area accepts an Alert Block
  3. In my Layout, I've created an HTML helper to Render Alerts.  The HTML helper (displayed below), recurses through the page hierarchy until it comes across a page with an Alert Content Area that has items inside of it- this instance is rendered.

Here's the rough pseudocode of my logic:

        public static MvcHtmlString RenderAlerts<TModel>(this HtmlHelper<TModel> helper)
        {
            var contentRouteHelper = ServiceLocator.Current.GetInstance<IContentRouteHelper>();
            var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();

            if (contentRouteHelper != null && contentRouteHelper.Content != null)
            {
                var page = contentRouteHelper.Content as IContent; // get the current page

                // loop through pages until we break out or until the page object is null
                while (page != null)
                {
                    // cast the page object to an instance of BasePage, which has the content area
                    if (page is BasePage basePage) 
                    {
                        if (basePage.AlertContent != null && basePage.AlertContent.Items != null && basePage.AlertContent.Items.Any())
                        {
                            return helper.DisplayFor(x => basePage.AlertContent); // render the Content Area
                        }
                    }

                    if (page.ParentLink == null || page.ParentLink == EPiServer.Core.PageReference.RootPage || page.ParentLink == EPiServer.Core.PageReference.SelfReference)
                        break;

                    page = contentRepository.Get<IContent>(page.ParentLink);
                }
            }

            return null;
        }

So I guess the real heart of my question is: is there a more efficient way to recurse through the page ancestry looking for the first instance of a page which has a non-empty content area?  Are calls into the ContentRepository cached?  Am I thinking about this problem in the wrong way?

#263549
Sep 22, 2021 20:21
Vote:
 

ContentRepository is cached and you probably don't have to worry. All things adds up in the end though, so if you do a lot of recursion, you might want to cache the result. You can cache the object with depedencies to all ancestors, or just a the global cache key for when any content changes.

#263550
Sep 22, 2021 22:24
Dylan McCurry - Sep 23, 2021 1:24
Thanks! Knowing that the ContentRepository is cached makes me feel a lot better.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.