Episerver.Forms and the solving of a performance issue
Update: This issue is probably solved in EPiServer.Forms 4.29.0, released May 11 2020, bug number: AFORM-2450.
Forms are a key element of many websites to collect information and interact with visitors. Some examples of such forms are Contact us, Sign up for our newsletter and Apply for a job.
The block-based approach Episerver.Forms makes assembling a new form a familiar experience for Episerver-editors. Complex forms require a large number of blocks, and thus a large amount of clicking, typing and publishing. Even though the experience is familiar, creating a form is not necessarily a five-minute task.
A small form with two-three text-inputs, a few radio buttons and a submit button are quick to set up and works flawless. Real life use cases are not always quick and flawless. When a customer created a quite large form, with five text fields, 70 groups of radio buttons and a total of 35 headings, the page containing the form took 25 seconds to load. Not so quick and flawless anymore.
Removing about half of the form elements improved the loading time, but 15 seconds are still a bit on the slow side. After some investigating, large amounts of coffee, and some trial and error, the block type «Rich text (with placeholder)» caught our attention. The block was used to add headings and elaborate text to the form, and the placeholder part were not used at all. It turned out that the code for rendering the placeholders are run even if no placeholders are used, and the initial loading of the form resulted in OVER SEVEN HUNDRED calls to the database. Removing all blocks of type «Rich text (with placeholder)» made the form load instantly.
Our solution to the problem was creating a new block type «Rich text (without placeholder)» equal to the existing block, but without all the time-consuming placeholder nonsense.
The new block type, inheriting the slow one.
using System;
...
...
namespace Alloy.Models.Blocks
{
[ContentType(DisplayName = "Rich text (without placeholder)",
GroupName = "BasicElements")]
public class FastParagraphBlock: ParagraphTextElementBlock
{
[CultureSpecific]
[Display(GroupName = "Information")]
public override XhtmlString ParagraphText { get; set; }
}
}
For the view, we made a copy of the slow blocks view, omiting all the code related to placeholders. The view is found in this location: \Views\ElementBlocks\ParagraphTextElementBlock.ascx
Inside this zip-file: \modules\_protected\EPiServer.Forms\EPiServer.Forms.zip
And after removing the placeholder code, it could look like this:
<%@ Import Namespace="System.Web.Mvc" %>
<%@ Import Namespace="EPiServer.Forms.Helpers.Internal" %>
<%@ Import Namespace="EPiServer.Forms.Implementation.Elements" %>
<%@ Control Language="C#" Inherits="ViewUserControl" %>
<% var formElement = Model.FormElement; %>
<% using(Html.BeginElement(Model,
new {
@class="FormParagraphText Form__Element--NonData",
@data_f_element_nondata="" }))
{ %>
<div name="<%: formElement.ElementName %>" id="<%: formElement.Guid %>" <%: Html.Raw(Model.AttributesString) %>>
<%: Html.Raw(Model.ParagraphText) %>
</div>
<% } %>
The modified view was saved with a filename matching the blocktype, in this location:
\Views\ElementBlocks\ParagraphTextElementBlock.ascx
The loading time was reduced from 25 seconds to 256 milliseconds!
So, if you are tempted to use the block type «Rich text (with placeholder)», be careful if your form consists of more than a handful of blocks/fields.