More in this section

Forums / Developing with Sitefinity / Blog/TagList (Cloud) Performance Problem

Blog/TagList (Cloud) Performance Problem

4 posts, 0 answered
  1. Chris Dodge
    Chris Dodge avatar
    16 posts
    Registered:
    17 Dec 2009
    24 Jun 2010
    Link to this post
    Hello,

    I'm in the middle of load-testing our Sitefinity website.

    I'm seeing some serious performance issues (CPU spikes leading to non-responsiveness) with our Blog section of the website. Our Blog has about 80 posts, so it's pretty small.

    The page that is having some problems has a BlogPosts, CategoriesList, and TagsList controls. There's also a SearchBox control and a bunch of GenericContent on there as well.

    The page on which the Blog is hosted has Caching Enabled with a non-sliding expiration of 1hr (I put it high in order to better isolate the cause).

    Even under non-load (just me clicking through the Blog section [e.g. listing page to detail page], I see CPU spikes which look unusual.

    Do you have any guidelines regarding making Blog performance better?
  2. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    24 Jun 2010
    Link to this post
    Hello Chris Dodge,

    BlogPost  control, should not be a problem, CategoriesTree uses caching, Generic Content control renders just html, SearchBox is simple form. The problem could appear if you have many tags displayed by TagsList which does not use caching. You could also observe the size of the page and all request if there are some scripts or images that cause the issue.

    You could enable page caching for the whole page. Try removing the TagList control and all controls one by one to see whether the performance will be improved. This will help you to narrow down the issue and show you  the problematic control.

    Sincerely yours,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. Chris Dodge
    Chris Dodge avatar
    16 posts
    Registered:
    17 Dec 2009
    24 Jun 2010
    Link to this post
    HI,

    Thanks for the suggestions, I do believe it is being caused by the tag list.

    Although the page settings say that the page is cached, so I'm not understanding why I'm seeing CPU spikes when visiting this page in the interval between the page expiry (1hr)

    Can you explain how page caching is performed? Is there some dependency that the TagList is creating on the page which forces a re-build of the page?

    Thank you,

    Chris
  4. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    24 Jun 2010
    Link to this post
    Hi Chris Dodge,

    You can substitute the control - TagsList with a custom one which gets the count of the content items tagged with each tag from cache. Then you will set the cache expiration to certain number of hours. This control should not count new tags and tagged items until the cache is cleared.

    sample code

    public class CustomTagsList: TagsList
    {
        #region Public properties
     
        [Category("Appearance"), WebEditor("Telerik.Cms.Web.UI.UrlEditorWrapper, Telerik.Cms")]
        public override string LayoutTemplatePath
        {
            get
            {
                object obj = this.ViewState["LayoutTemplatePath"];
                if (obj != null)
                {
                    return (string)obj;
                } return "~/Sitefinity/ControlTemplates/Generic_Content/TagsList.ascx";
            }
            set
            {
                base.LayoutTemplatePath = value;
            }
        }
     
        [Category("Behavior"),Description("Sets cache duration for the control in hours")]
        public double CacheDurationInterval
        {
            get { return this._CacheDuration; }
            set { this._CacheDuration = value; }
        }
     
        #endregion
     
        #region Methods
     
        protected override void InitializeControls(System.Web.UI.Control controlContainer)
        {
            if (this.DefaultDisplayMode == DisplayMode.List)
            {
                this.TagsRepeaterList.DataSource = this.Manager.GetTags(String.Empty, "TagName", false);
                this.TagsRepeaterList.ItemDataBound += this.TagsRepeaterList_ItemDataBound;
                this.TagsRepeaterList.DataBind();
            }
            else
            {
                IList tags = this.Manager.GetTags(String.Empty, "TagName", false);
     
                this.TagsRepeaterCloud.DataSource = tags;
                this.TagsRepeaterCloud.ItemDataBound += this.TagsRepeaterCloud_ItemDataBound;
                this.TagsRepeaterCloud.DataBind();
            }
     
            if (this.ControlTitleControl != null)
                this.ControlTitleControl.Text = this.ControlTitle;
     
            this.TagsRepeaterCloud.Visible = this.DefaultDisplayMode == DisplayMode.Cloud;
            this.TagsRepeaterList.Visible = this.DefaultDisplayMode == DisplayMode.List;
     
            if (this.DisplayCloudLink != null)
            {
                this.DisplayCloudLink.Enabled = this.DefaultDisplayMode == DisplayMode.List;
                this.DisplayCloudLink.CommandName = "DisplayCloud";
                this.DisplayCloudLink.Command += this.Button_Command;
            }
     
            if (this.DisplayListLink != null)
            {
                this.DisplayListLink.Enabled = this.DefaultDisplayMode == DisplayMode.Cloud;
                this.DisplayListLink.CommandName = "DisplayList";
                this.DisplayListLink.Command += this.Button_Command;
            }
        }
     
        private void TagsRepeaterList_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                ITag tag = (ITag)e.Item.DataItem;
                HyperLink tagUrl = (HyperLink)e.Item.FindControl("tagLink");
                tagUrl.Text = tag.TagName;
                tagUrl.NavigateUrl = this.TagKeyType == TagKeyTypes.ID ? this.ResolveUrl(String.Concat(this.TaggedContentUrl, "?", this.TagItemKey, "=", tag.ID.ToString())) : this.ResolveUrl(String.Concat(this.TaggedContentUrl, "?", this.TagItemKey, "=", tag.TagName));
     
                IUrlService svc = UrlServices.GetLanguageService();
                if (svc != null)
                {
                    tagUrl.NavigateUrl = svc.ResolveLanguageUrl(tagUrl.NavigateUrl);
                }
     
                ITextControl taggedContentCount = (ITextControl)e.Item.FindControl("taggedContentCount");
                taggedContentCount.Text = GetCachedTagCount(tag).ToString();
            }
        }
     
        private void TagsRepeaterCloud_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                ITag tag = (ITag)e.Item.DataItem;
                HyperLink tagLink = (HyperLink)e.Item.FindControl("tagLink");
                tagLink.Text = tag.TagName;
                tagLink.NavigateUrl = this.TagKeyType == TagKeyTypes.ID ? this.ResolveUrl(String.Concat(this.TaggedContentUrl, "?", this.TagItemKey, "=", tag.ID.ToString())) : this.ResolveUrl(String.Concat(this.TaggedContentUrl, "?", this.TagItemKey, "=", tag.TagName));
     
                IUrlService svc = UrlServices.GetLanguageService();
                if (svc != null)
                {
                    tagLink.NavigateUrl = svc.ResolveLanguageUrl(tagLink.NavigateUrl);
                }
     
                int contentTagged = GetCachedTagCount(tag);
     
                if (this.MaxContentTagged != 0)
                {
                    double fontSize = 75 + 225 * contentTagged / this.MaxContentTagged;
                    tagLink.Style.Add(HtmlTextWriterStyle.FontSize, fontSize.ToString() + "%");
                }
            }
        }
     
        private void Button_Command(object sender, CommandEventArgs e)
        {
            switch (e.CommandName)
            {
                case "DisplayCloud":
                    this.DefaultDisplayMode = DisplayMode.Cloud;
                    this.ChildControlsCreated = false;
                    break;
                case "DisplayList":
                    this.DefaultDisplayMode = DisplayMode.List;
                    this.ChildControlsCreated = false;
                    break;
            }
        }
     
        private int GetCachedTagCount(ITag tag)
        {
            object contentCount = 0;
            string key = this.GenerateTagCountCacheKey(tag.TagName);
            if (Context != null)
            {
                contentCount = Context.Cache[key];
                if (contentCount == null)
                {
                    contentCount = tag.TaggedContent.Count;
                    Context.Cache.Add(key, contentCount, null, DateTime.Now.AddHours(CacheDurationInterval), Cache.NoSlidingExpiration,
                                      CacheItemPriority.Normal, null);
                }
            }
            return (int)contentCount;
        }
     
        public string GenerateTagCountCacheKey(string tagName)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(this.ProviderName);
            sb.Append(tagName);
            sb.Append(System.Threading.Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName);
            return sb.ToString().GetHashCode().ToString();
        }
         
        
        #endregion
     
        #region Private fields
     
        private double _CacheDuration;
     
        #endregion
     
     
    }


    Kind regards,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Register for webinar
4 posts, 0 answered