Slow Performance on a Dense Interface

Certified Lead Developer

We are seeing performance issues and would appreciate any input on how to speed things up.

We currently have an interface that consists of a two column layout.

In the first column, we have 4 card layouts. Within each of these card layouts, we have ~15 rich text items and ~10 rich text images/icons. 

When a user clicks on a card in the left column, we populate the second column with certain associated records, also shown in a list of card layouts (this side has 5-10). Each of these card layouts has ~10 rich text items and ~15 rich text images/icons.

 

We have no with() variables anywhere and we are not querying the database beyond the initial load. Yet, just clicking on a single card can take up to 5 seconds. It doesn't matter what we click, any action on the page takes 3-5 seconds (even when clicking on completely isolated components). It seems like Appian is re-rendering every component on every click. 

 

 

We have already read through https://docs.appian.com/suite/help/18.4/SAIL_Performance.html but were not able to find any actionable takeaways from it.

Looking at the performance view, Appian is telling us the page is loading in 1.3 second (not accurate when compared to end user testing). 

 

The only option I can see is reducing the number of components on the page. When doing so, we have received pushback since it no longer matches the client's initial design. Are there any other ways to speed up performance here? 

 

Top 5 parts of performance view:

Function
Count
Total Time (ms)
Percent
Minimum Time (ms)
Maximum Time (ms)

a!richTextItem

154

524

38.40%

< 1

61

a!richtextimage

60

332

24.34%

5

11

a!sidebysidelayout

41

191

13.99%

2

12

a!richtextdisplayfield

101

44

3.22%

< 1

2

a!richtexticon

61

36

2.66%

< 1

2

  Discussion posts and replies are publicly visible

  • Hi Joubin! Is all of the data for both left and right columns being queried on page load? Perhaps you could consider querying required data only for the left columns on page load and then making queries for the right column data as needed (on click of the card in the left column, for example).
  • 0
    Certified Lead Developer
    in reply to glennw
    Hello!

    We are querying the data only once on page load - there are further complexities that I didn't explain that led to us loading all the data at once.

    At the same time, our queries are the fastest part of our system and there really isn't a lot of data (it's all sample data for now). It's simple interactions with the page that are taking long amounts of time.
  • Hi Joubin,

    in general, performance issue would be in scenarios when multiple Query entities are called in with() or if there is a iterative loop on DB transactions or if there is a web service call for every tab out.
    But according to your problem statement, these scenarios do not apply.
    It would be feasible to analyse the issue in depth if its possible to share the code or at least sample code.

    Thanks,
    Farnaz
  • Hi, on what browser are you testing this? For me it looks more like a client side performance issue? Internet Explorer is known to be slow with complex UI. Virtual desktops will also not help.
  • 0
    Certified Lead Developer
    in reply to Stefan Helzle
    We are using the latest version of Chrome, as recommended by Appian. There is no virtual desktop either. We are able to replicate this on at least 4 different computers, so I'm leaning away from client-side issue for now.
  • 0
    Certified Lead Developer
    in reply to Farnaz

    Hi Farnaz,

    That is correct, those scenarios do not apply. I've mocked up the entire interface here using sample code to give a sense of the issue.

    You will need to change the local!documentConstant to point to a constant on your environment that is pointing to an uploaded image.

     

    To see the issue, try clicking on any of the links on the page (the buttons, the Edit button on the left hand cards, or the expand caret on the right hand cards). These links do a single variable save (or nothing at all!) in their saveInto, but it still takes about 4 seconds for the page to load.

     

    Performance view will claim it's taking 1.8-2 seconds, but using the page, you will see otherwise. 

     

    load(
      local!documentConstant: cons!TEST_SAMPLE_ICON,
      local!buttonValue1,
      local!checkboxValue1,
      local!checkboxValue2,
      local!isExpand: false,
      {
        a!richTextDisplayField(
          value: a!richTextItem(
            text: "Informational Text",
            style: "EMPHASIS"
          )
        ),
        a!columnsLayout(
          columns: {
            a!forEach(
              items: enumerate(5),
              expression: a!columnLayout(
                a!cardLayout(
                  style: "INFO",
                  contents: {
                    a!richTextDisplayField(
                      value: {
                        a!richTextIcon(
                          icon: "star",
                          color: "ACCENT"
                        ),
                        a!richTextItem(
                          text: " Title" & char(10),
                          style: "STRONG",
                          size: "MEDIUM"
                        ),
                        a!richTextItem(
                          text: "Subtitle"
                        )
                      }
                    )
                  }
                )
              )
            )
          }
        ),
        a!richTextDisplayField(
          value: a!richTextHeader(
            text: "Page Header:" & char(10),
            size: "LARGE"
          )
        ),
        a!buttonArrayLayout(
          buttons: {
            a!buttonWidget(
              label: "BUTTON 1",
              value: "BUTTON 1",
              saveInto: local!buttonValue1,
              style: if(
                local!buttonValue1 = "BUTTON 1",
                "PRIMARY",
                {}
              )
            ),
            a!buttonWidget(
              label: "BUTTON 2",
              value: "BUTTON 2",
              saveInto: local!buttonValue1,
              style: if(
                local!buttonValue1 = "BUTTON 2",
                "PRIMARY",
                {}
              )
            ),
          }
        ),
        a!richTextDisplayField(
          value: a!richTextHeader(
            text: "Sub Header:" & char(10)
          )
        ),
        a!checkboxField(
          choiceLabels: {"one"},
          choiceValues: {"one"},
          value: local!checkboxValue1,
          saveInto: local!checkboxValue1
        ),
        a!checkboxField(
          choiceLabels: {"two"},
          choiceValues: {"two"},
          value: local!checkboxValue2,
          saveInto: local!checkboxValue2
        ),
        a!columnsLayout(
          columns: {
            a!columnLayout(
              contents: a!forEach(
                items: enumerate(4)+1,
                expression: a!cardLayout(
                  marginBelow: "STANDARD",
                  contents: {
                    a!sideBySideLayout(
                      items: {
                        a!sideBySideItem(
                          width: "1X",
                          item: a!richTextDisplayField(
                            value: {
                              a!richTextImage(
                                image: a!documentImage(
                                  document: local!documentConstant,
                                  caption: "Caption " & fv!item
                                )
                              ),
                              a!richTextItem(
                                text: " TITLE OF CARD " & fv!item
                              )
                            }
                          )
                        ),
                        a!sideBySideItem(
                          width: "MINIMIZE",
                          item: a!richTextDisplayField(
                            value: a!richTextIcon(
                              icon: "repeat"
                            )
                          )
                        )
                      }
                    ),
                    a!sideBySideLayout(
                      items: {
                        a!forEach(
                          items: enumerate(5)+1,
                          expression: a!sideBySideItem(
                            item: a!richTextDisplayField(
                              value: {
                                a!richTextItem(
                                  text: "# " & fv!item & char(10),
                                  style: "STRONG"
                                ),
                                a!richTextItem(
                                  text: "Text " & fv!item & char(10),
                                  style: "EMPHASIS"
                                )
                              }
                            )
                          )
                        ),
                        a!sideBySideItem(
                          width: "MINIMIZE",
                          item: a!richTextDisplayField(
                            value: {
                              a!forEach(
                                items: enumerate(6),
                                expression: a!richTextImage(
                                  image: a!documentImage(
                                    document: local!documentConstant
                                  )
                                )
                              )
                            }
                          )
                        )
                      }
                    ),
                    a!sideBySideLayout(
                      items: a!forEach(
                        items: enumerate(5)+1,
                        expression: a!sideBySideItem(
                          item: a!richTextDisplayField(
                            value: {
                              a!richTextItem(
                                text: "# " & fv!item & char(10),
                                style: "STRONG"
                              ),
                              a!richTextItem(
                                text: "Text " & fv!item & char(10),
                                style: "EMPHASIS"
                              )
                            }
                          )
                        )
                      )
                    ),
                    a!richTextDisplayField(
                      value: {
                        a!richTextIcon(
                          icon: "edit"
                        ),
                        a!richTextItem(
                          text: " Edit",
                          link: a!dynamicLink(
                            
                          ),
                          linkStyle: "STANDALONE"
                        )
                      } 
                    )
                  }
                )
              )
            ),
            a!columnLayout(
              contents: a!forEach(
                items: enumerate(10)+1,
                expression: a!cardLayout(
                  marginBelow: "STANDARD",
                  contents: {
                    a!sideBySideLayout(
                      items: {
                        a!sideBySideItem(
                          width: "1X",
                          item: a!richTextDisplayField(
                            value: {
                              a!richTextImage(
                                image: a!documentImage(
                                  document: local!documentConstant,
                                  caption: "Caption " & fv!item
                                )
                              ),
                              a!richTextItem(
                                text: " TITLE OF RIGHT HAND CARD " & fv!item
                              )
                            }
                          )
                        ),
                        a!sideBySideItem(
                          width: "MINIMIZE",
                          item: a!richTextDisplayField(
                            value: {
                              a!richTextIcon(
                                icon: "repeat"
                              ),
                              a!richTextItem(
                                text: " Action 1"
                              ),
                              a!richTextItem(
                                text: "  "
                              ),
                              a!richTextIcon(
                                icon: "random"
                              ),
                              a!richTextItem(
                                text: " Action 2"
                              )
                            }
                          )
                        )
                      }
                    ),
                    a!sideBySideLayout(
                      items: {
                        a!forEach(
                          items: enumerate(5)+1,
                          expression: a!sideBySideItem(
                            item: a!richTextDisplayField(
                              value: {
                                a!richTextItem(
                                  text: "# " & fv!item & char(10),
                                  style: "STRONG"
                                ),
                                a!richTextItem(
                                  text: "Text " & fv!item & char(10),
                                  style: "EMPHASIS"
                                )
                              }
                            )
                          )
                        ),
                        a!sideBySideItem(
                          width: "MINIMIZE",
                          item: a!richTextDisplayField(
                            value: {
                              a!forEach(
                                items: enumerate(6),
                                expression: a!richTextImage(
                                  image: a!documentImage(
                                    document: local!documentConstant
                                  )
                                )
                              )
                            }
                          )
                        )
                      }
                    ),
                    a!sectionLayout(divider: "BELOW"),
                    a!sideBySideLayout(
                      items: {
                        a!sideBySideItem(
                          width: "AUTO",
                          item: a!richTextDisplayField(
                            value: {
                              a!richTextIcon(
                                icon: "recycle"
                              ),
                              a!richTextItem(
                                text: " Action 3"
                              ),
                              a!richTextItem(
                                text: "  "
                              ),
                              a!richTextIcon(
                                icon: "remove"
                              ),
                              a!richTextItem(
                                text: " Action 4"
                              )
                            }
                          )
                        ),
                        a!sideBySideItem(
                          width: "MINIMIZE",
                          item: a!richTextDisplayField(
                            value: {
                              a!richTextIcon(
                                icon: "caret-down",
                                link: a!dynamicLink(
                                  value: not(local!isExpand),
                                  saveInto: local!isExpand
                                ),
                                linkStyle: "STANDALONE"
                              )
                            }
                          )
                        )
                      }
                    ),
                    if(
                      local!isExpand,
                      a!richTextDisplayField(
                        value: a!richTextItem(
                          text: "EXPAND IS TRUE",
                          size: "MEDIUM"
                        )
                      ),
                      {}
                    )
                  }
                )
              )          
            )
          }
        )
      }
    )