Delayed loading of cases in case list

Hi Everyone,

So I have a form whose case list is filtered through numerous records before it is displayed. The filter works perfectly but the issue is that it takes ages to populate the cases for selection in the Mobile App (time varies from device to device -- Fastest can be about 3 minutes to load the list), while it seems to be working smoothly in the emulator in CommCareHQ, populating under 10 seconds.

I'd like to believe it is because of two things;

  1. High number of records filtered through to populate only 4 records (For now, they are about 100 records to filter through per user - Which honestly isn't that much because the syncing is swift.)
  2. 'Complex' filtering expression?
    Expression: (Module_Number = instance('casedb')/casedb/case[@case_type = 'c_staff' and s_staff_id = instance('commcaresession')/session/user/data/s_id]/Current_Module) and (FV_AA_Visited = 'No') and (Module_Name = instance('casedb')/casedb/case[@case_type = 'c_staff' and s_staff_id = instance('commcaresession')/session/user/data/s_id]/Current_Module_Name)

I had wanted to push this form to production but the delays in loading the case lists is what is holding me back. Does anyone have any idea what could be the issue here?

Many thanks!

This is a good question - hopefully someone else will chime in with more ideas, but the first thing I'd try is splitting up those filters. Instead of

[@case_type = 'c_staff' and s_staff_id = instance('commcaresession')/session/user/data/s_id]

you can use two filters:

[@case_type = 'c_staff'][s_staff_id = instance('commcaresession')/session/user/data/s_id]

You might also try reordering them so (FV_AA_Visited = 'No') comes first. That portion is simpler than the other two, and I'd expect it to evaluate faster. Also, is it necessary to filter both against module name and module number? If they are expected to always coincide, you may be able to drop one of them.

Lastly, I'd also look at your overall case load per user. You might be able to adjust the way cases are managed so that each user receives a smaller number of cases, say by closing old cases or changing the way cases are shared between users.

1 Like

Thank you, @Ethan_Soergel, this has improved the response of the app!

I have always used the square brackets in XPath expressions to 'merge' filters, but for some reason, when I tried doing it in the case list filters, it produced errors, so I opted to use 'and' within the expression. Not sure what I was doing wrong back then, but it has worked today. I also rearranged the filters as advised.

As for the module name and module number, I definitely could use only one of the two in an ideal case, but decided to add both just in case and since I am in the testing phase :slight_smile:. And sometimes, the module names are repeated over months so it would match to multiple nodes if I used that alone.

When it comes to the case load, at the moment, there aren't so many cases per user (Probably 80 new cases every month), but I will likely implement closing of each case that has been worked on, since these are random samples and the aren't repeated -- But this is more of a prospect for now.

I appreciate your swift support on this!

1 Like

I would also do this tiny thing that in my experience has a significant impact:

make your filters have an easier job by cascading the number of returned rows by each filter. and also start with filtering with indexed fields "things that start with an @"
so, status = open, case type = c_staff, then whichever filter returns the most rows, goes first. from left to right. so probably module name, then visited = no, then staff id

1 Like