5 practices to avoid when doing Sitefinity development

5 practices to avoid when doing Sitefinity development

Posted on March 14, 2012 0 Comments

The content you're reading is getting on in years
This post is on the older side and its content may be out of date.
Be sure to visit our blogs homepage for our latest news, updates and information.

As many of you know, the extensibility of the Sitefinity product is one of our top concerns. We try to expose everything and make it easily accessible through the Sitefinity API. And by everything, I don’t mean just content, but the whole architecture. We try to provide hooks and events you can subscribe to and plug your custom code into the Sitefinity pipeline. One rule we try to follow is to provide many options for you to do the same thing, and let you decide what is best. Although this makes development easier, sometimes it leads to problems if developers do not fully understand what they are doing. This blog post is going to list 5 practices you should avoid and provide alternatives for them.

Calling ToList() on IQueryable objects

All Sitefinity content is exposed through the provider pattern. When working with collections of items, Sitefinity returns IQueryable objects everywhere. The benefit is that you can use deferred execution for database calls and shift data processing to the database server using LINQ, instead of consuming web server memory and processing power.

Many .NET developers are used to working with IList objects, because of their convenience. This is why, sometimes it’s easy to just convert an IQueryable to IList by calling the ToList() method.

var news = App.WorkWith().NewsItems().Get().ToList();

 

Although you gain a lot in convenience, you lose all advantages of IQueryable and deferred execution. Never call ToList() on results you got from the Sitefinity API unless you absolutely need to, and know what you are doing. Read Use LINQ deferred execution in the documentation for more information.

Eagerly loading data

Sitefinity is designed to expose the data in the CMS without making assumptions about how you would use it. It’s your job as a developer to understand the usage of this data and only request what you need. Sometimes this is easy to neglect. By default, Sitefinity returns collections that contain all items of a certain type. The scenarios in which you would need all items up front are very rare. Try to use paging and filtering whenever possible to limit the amount of data transferred from the database. If you are only going to display 10 items, don’t request all of them.

App.WorkWith().NewsItems().Get().Skip(40).Take(20);

 

Read more about paging and filtering in the Sitefinity documentation.

Implementing custom navigation without the sitemap

Sitefinity comes with a navigation widget by default, which you can use for a lot of scenarios. For one reason or another, a lot of developers decide to implement custom navigation. Maybe they want better control on what is displayed, or want to style the navigation in a way the navigation widget doesn’t support. In these cases, you can expose the site page hierarchy and bind to it.

There are many ways you can do this, and one that comes to mind is to use the Pages API. Don’t go for this first option. The reason it’s a bad idea to use the Page API for navigation is that it only exposes data and doesn’t scale. Navigation is one of those things that are rendered everywhere on your site and calling the API on each request is not exactly a performance best practice. What you can do instead is to bind to the Sitefinity SiteMap provider. This gives you a lot better performance by utilizing caching and lazy loading – it only calls for data when needed. You can get an instance like this:

var provider = SiteMapBase.GetSiteMapProvider("FrontendSiteMap");

 

Once you have the provider, you can bind using the standard ASP.NET way.

Not caching jQuery selector results

A lot of the development in Sitefinity is done in JavaScript. This includes custom widget designers, customizing the backend and binding to services asynchronously. With JavaScript comes jQuery, which is turning into the defacto library used in almost every client development project. You can easily use jQuery in Sitefinity, but do it with caution. While jQuery makes it a lot easier to select DOM elements and bind even handlers, it comes with a certain overhead you should take into account. Selecting an element always traverses the DOM tree, and when doing it multiple times you should take care to cache the results of a selection.

$(li.highlighted).click( function () {
    $(li.highlighted).removeClass("highlighted");
    $(li.highlighted).addClass("otherClass");
});

 

You can save some processing by caching the result of the above selector into a variable.

var highlightedItems = $(li.highlighted);
highlightedItems.click( function () {
    highlightedItems.removeClass("highlighted");
    highlightedItems.addClass("otherClass");
});

 

For more on this, read the client performance documentation.

Allowing memory leaks in client script controls

When you develop custom widgets for Sitefinity and extend them with client capabilities, you are almost always writing client script controls. Script controls are the bridge between an ASP.NET server control and JavaScript and make it extremely easy to change client behavior depending on server-side control properties. MS Ajax exposes two methods for each client component that serve as the analogue for constructors and destructors in object oriented programming – initialize() and dispose() respectively. While this is clear to most developers at the beginning, they don’t always remember to dispose everything they use in client script. Two very good candidates for disposal are delegates and event handlers. You should always make sure to unsubscribe from events and delete the delegates you create in your client components.

// to delete a delegate created in the same component
if (this._formSavedDelegate) {
    delete this._formSavedDelegate;
}
  
// to remove an event handler that was added in the same component
$removeHandler(someLink, 'click', this._handleSomeLinkClickDelegate);

 

More info on disposing client objects is available in the documentation.

These 5 practices are what we’ve most commonly seen in reviewing customer code. You should also follow general development best practices and apply them in your sites. If you have other ideas on what Sitefinity developers should avoid and what they can do better, let us know.

progress-logo

The Progress Team

View all posts from The Progress Team on the Progress blog. Connect with us about all things application development and deployment, data integration and digital business.

Comments

Comments are disabled in preview mode.
Topics

Sitefinity Training and Certification Now Available.

Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.

Learn More
Latest Stories
in Your Inbox

Subscribe to get all the news, info and tutorials you need to build better business apps and sites

Loading animation