1

It is general scenario to create functionality of add and delete row dynamically.

You can refer following link for better understanding of scenario: http://www.infallibletechie.com/2012/06/dynamically-adding-rows-in-apex.html

Basic flow to achieve this is as follows:

  1. Create Wrapper for row
  2. Create list of wrapper
  3. on 'Add' button -> perform server call and add element to wrapper list
  4. Re -render the panel containing table or apex-repeat tag, to view updated data.

But if number of rows are large in number, then it takes significant amount of time to perform above operations & this results is laggy UI experience.

It there any way to optimize this issue or any other way to achieve same efficiently.

1 Answer 1

1

The problem with the design has to do with the bottleneck: the server. This is one reason why we were given Lightning. By eliminating many of the server calls, the performance of Lightning was greatly enhanced. Visualforce has to render the entire page as HTML, then update sections of the page as fragments in JavaScript. Realistically, the best you're going to get for even a simple Visualforce page is somewhere on the order of 100ms, and it can easily take 4-5 seconds or more to render complicated pages.

The only real solution is client-side rendering. Normally, this might mean using something like jQuery, although I strongly advise against it in normal cases. It's not that I don't like jQuery, is that's the browsers are now standardized enough that using jQuery negates some of the performance benefits of using client-side rendering (that is, it's not as fast, even if it's a little easier to write).

Here's a rough translation of the add row feature in Visualforce with no controller at all:

<apex:page showHeader="true" standardStylesheets="true">
    <script>
    var de = x => document.createElement(x), ap = (x, y) => x.appendChild(y);
    function save() {
        // not implemented
    }
    function cancel() {
        // not implemented
    }
    function addRow() {
        var row = de("tr"),
            col1 = de("td"), col2 = de("td"), col3 = de("td"),
            inp1 = de("input"), inp2 = de("input"), inp3 = de("input");
        ap(col1, inp1);
        ap(col2, inp2);
        ap(col3, inp3);
        [col1, col2, col3].forEach(col => ap(row, col));
        ap(document.querySelector('tbody[table]'), row);
        return false;
    }

    </script>
    <apex:form>
        <apex:variable value="[]" var="nothing" />
        <apex:pageBlock>
            <apex:pageBlockButtons>
                <apex:commandButton value="Save" onclick="return save()" />
                <apex:commandButton value="Cancel" onclick="return cancel()" />
            </apex:pageBlockButtons>
            <apex:pageBlockTable html-table="table" value="{!nothing}" var="row">
                <apex:column headerValue="Member Name" />
                <apex:column headerValue="Mobile Number" />
                <apex:column headerValue="eMail Id" />
            </apex:pageBlockTable>
            <br/><apex:commandLink value="Add Row" onclick="return addRow()" />        
        </apex:pageBlock>
    </apex:form>
</apex:page>

Note: obviously, this isn't a full solution, as you also need a way to load the existing data, save, etc, but this demonstrates a client-side implementation. The actual code would probably be something closer to 200 lines of code, so I'm not going to type up the full thing, as that's largely outside the scope of this answer, and it'd probably take me an hour or so to write up the extra logic you'd need.

The actual save and load methods could be implemented with RemoteAction methods. You would need a small (~10-15 lines of code) Apex Code controller, but the only thing you're doing is processing data, not rendering a UI.

Of course, if you're going to go full client-side, you might want to just look in to Lightning Out, where it's trivial to add/remove/save data just like in Visualforce, but without the performance penalty. The only downside to Lightning Components is that you have to learn a new framework on top of what you already know. However, I would say that if you're building client-side solutions in Visualforce in 2018 and beyond, doing so in Lightning is much more sane than using straight JavaScript or jQuery, since you get a Lightning version you can use as well.

The point is, if you want a better UX, you have to write a little more code to take away a lot of the control from Visualforce; the framework is great at minimizing the code you have to write, but there is a trade off for writing less code.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .