Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Investigate performance of action forms in 2.13 #3837

Closed
abbyad opened this issue Aug 29, 2017 · 25 comments
Closed

Investigate performance of action forms in 2.13 #3837

abbyad opened this issue Aug 29, 2017 · 25 comments
Labels
Priority: 2 - Medium Normal priority Type: Performance Make something faster

Comments

@abbyad
Copy link
Contributor

abbyad commented Aug 29, 2017

With 2.13.0-beta.10 it is taking ~5-12 seconds to load Action forms on standard.app (eg the Delivery form). It seems to take longer from the contact profile vs from the history tab. This could perhaps be related to inputs being populated, which contains a db-object.

We need to investigate this further to characterize the performance and determine if 2.13 can be released as such.

@garethbowen
Copy link
Contributor

garethbowen commented Aug 30, 2017

I've managed to eek out some small gains in the contact summary service but putting breakpoints in the code it looks like the bottleneck is Enketo rendering.

@abbyad Is there a 2.12 instance with the same forms we can use for comparison?

@alxndrsn Any ideas? Do you think it could be related to binding the contact summary into the form?

You can test 2.13.0 here: https://standard.app.medicmobile.org/medic/_design/medic/_rewrite/#/contacts/02a2c7eba7e4f4a92aa04ff5c2072419/report/delivery

garethbowen added a commit that referenced this issue Aug 30, 2017
Don't compile it every time the contact summary is requested.
Invalidation is handled by the page being refreshed on configuration
change.

#3837
@alxndrsn
Copy link
Contributor

screen shot 2017-08-30 at 10 58 45

garethbowen added a commit that referenced this issue Aug 30, 2017
Don't compile it every time the contact summary is requested.
Invalidation is handled by the page being refreshed on configuration
change.

#3837
@garethbowen
Copy link
Contributor

I've merged my caching improvements to master and we can backport if it'd help but I think there's something else going on that I haven't been able to detect yet...

@abbyad
Copy link
Contributor Author

abbyad commented Aug 30, 2017

I will create and post links to forms today with minor variants that seem to have some effect on performance so that they can be profiled.

@abbyad
Copy link
Contributor Author

abbyad commented Aug 30, 2017

Here are some variants of the delivery form, which I then tested on 2.13.0-beta.10 on standard.app.

@alxndrsn offered to do some detailed profiling of the forms, but in the meantime here are some stopwatch results:

Form Opened from History tab Opened from Person's profile
issue-3837-0-no-change 1.5s 6s
issue-3837-1-no-translations 1s 3.5s
issue-3837-2-no-secondary-instance 1s 3.5s
issue-3837-3-no-db-object 1s 3s

Opening the forms from the History tab does not run contact-summary, nor pass any info to the form, which is helpful for quick check before proper profiling is done tomorrow.

From this quick analysis it looks like removing unused <translations> has the biggest benefits, although not terribly practical for Standard projects. That said, it probably means this isn't anything new in 2.13 so may not be a blocker, but we can wait until the proper profiling before making that call.

@sglangevin
Copy link

Just a note that I did some quick testing on a Tecno Y4, v2.13.0-beta.10, container v0.3.6 and I don't see a noticeable difference between the contacts tab and history tab. I also don't think the performance has degraded significantly, but it is definitely slower to open forms than it was in the past. I also noticed that contact-summary seems to run when you open a form from the Tasks tab. Is that necessary to populate certain fields?

@alxndrsn
Copy link
Contributor

On remote server

The first five network requests when loading the linked contact are impressively slow:

screen shot 2017-08-31 at 17 20 25

@alxndrsn
Copy link
Contributor

Loading the actual form

screen shot 2017-08-31 at 17 27 31

N.B. this is with an all-access/fully-online user

Queries

  • why isn't the favicon cached?
  • does the user object really (need to) get loaded twice simultaneously?

@alxndrsn
Copy link
Contributor

Profile of loading the delivery form on standard.app

screen shot 2017-08-31 at 17 57 29

=>

screen shot 2017-08-31 at 17 58 55

=>

.trigger()

screen shot 2017-08-31 at 17 59 41

screen shot 2017-08-31 at 18 00 15

This looks like it's part of jQuery.

setVal()

screen shot 2017-08-31 at 18 00 43

This looks like it's part of enketo.

evaluate()

screen shot 2017-08-31 at 18 02 35

This is part of our XPath evaluator.

@abbyad
Copy link
Contributor Author

abbyad commented Aug 31, 2017

As requested by @alxndrsn, here is a version without the output fields in the labels: issue-3837-4-no-outputs.zip

This can also be seen in action on standard.app

garethbowen added a commit that referenced this issue Aug 31, 2017
Don't compile it every time the contact summary is requested.
Invalidation is handled by the page being refreshed on configuration
change.

#3837
@alxndrsn
Copy link
Contributor

alxndrsn commented Sep 1, 2017

Loading this form calls jsEvaluate() 2,500 times. This implies 2.5k xpath expressions are evaluated...

@alxndrsn
Copy link
Contributor

alxndrsn commented Sep 1, 2017

From a page refresh:

Form jsEvaluate() count Time to load on server
0 - No Change 2452 15s
1 - No Translations 856 8s
2 - No Secondary Instance 856 6s
3 - No db-object 170 7s
4 - No outputs 52 3s

Time to load was measured for Toronto Health Centre in Firefox after loading a few forms for the same user, including the form in question. A single timing was taken.

Observations

  1. It seems a strange coincidence that 1 and 2 should have the same call count when the change made is so different, unless the only translated elements are in the secondary instance.
  2. db-object is doing something pathological
  3. A few things we do in our forms seem to severely affect enketo performance
  4. Outputs!?!?

@alxndrsn
Copy link
Contributor

alxndrsn commented Sep 1, 2017

Conclusion

Removing the jr:choice-name() patch improves things significantly:

Form jsEvaluate() count (with patch) jsEvaluate() count (without patch)
0 - No Change 2452 58
1 - No Translations 856 58
2 - No Secondary Instance 856 58
3 - No db-object 170 54
4 - No outputs 52 52

Recommendation

  1. Re-deploy webapp to standard.app with `jr:choice-name() patch removed and test performance [DONE]
  2. find a replacement for our jr:choice-name() and update our forms

References

@alxndrsn
Copy link
Contributor

alxndrsn commented Sep 1, 2017

The final tests above were done on master. I'm going to re-test this on the 2.13.x branch, as the jr:choice-name() patch was slightly different in that release. I expect similar results.

@alxndrsn
Copy link
Contributor

alxndrsn commented Sep 1, 2017

2.13.x branch

Form jsEvaluate() count (with patch) jsEvaluate() count (without patch)
0 - No Change 2566 84

Patch is to provide second-level calculations based on jr:choice-name().

@alxndrsn
Copy link
Contributor

alxndrsn commented Sep 1, 2017

I've manually removed the jr:choice-name() patch on standard.app and see form load times of around 5s for both 0 - No change and 4 - No outputs.

@abbyad
Copy link
Contributor Author

abbyad commented Sep 1, 2017

After discussion with @alxndrsn we will attempt to get around the (over)use of jr:choice-name(), especially as used for g_chw_sms in the forms above. That calc sets the default value for a text field based on prior inputs, and the default value is a template that includes other values such as patient name, ID eg Good news, ${chw_name}! ${patient_name} (${r_patient_id}) has delivered at the health facility.

One strategy is to use itext() instead, as seen in this simplified example:
<bind calculate="jr:itext( '/delivery/group_note/default_chw_sms/anc_only_home_sba_birth:label' )" nodeset="/delivery/group_note/g_chw_sms" type="string"/>

However this gives the following error:
Error loading form Error: ["FormLogicError: Could not evaluate: jr:itext( '/delivery/group_note/default_chw_sms/anc_only_home_sba_birth:label' ), message: Failed to execute 'evaluate' on 'Document': The string 'jr:itext(\"/delivery/group_note/default_chw_sms/anc_only_home_sba_birth:label\")' is not a valid XPath expression."]

The form issue-3837-0-5-no-choice-name.zip can be seen in standard.app

@garethbowen
Copy link
Contributor

@alxndrsn This is marked for "Code review" but I think it should be "Won't fix: Not an issue" because there's no code change. Does that make sense?

@garethbowen garethbowen removed their assignment Sep 3, 2017
@alxndrsn
Copy link
Contributor

alxndrsn commented Sep 4, 2017

I'd quite like someone to check my working 😄

Also I don't think "not an issue" is a very helpful label when this clearly is an issue. Just not one whose solution can be tested or released in the standard way.

@alxndrsn
Copy link
Contributor

alxndrsn commented Sep 5, 2017

@garethbowen did you check this before changing the status?

@garethbowen
Copy link
Contributor

The logic looks fine to me. I put it in AT so the performance could be tested.

@alxndrsn
Copy link
Contributor

alxndrsn commented Sep 6, 2017

I put it in AT so the performance could be tested.

I haven't made any changes to code.

@abbyad
Copy link
Contributor Author

abbyad commented Sep 6, 2017

The performance AT is blocked on #3870

@abbyad abbyad added the Status: Blocked Unable to progress this. label Sep 6, 2017
@abbyad abbyad reopened this Sep 6, 2017
@alxndrsn
Copy link
Contributor

alxndrsn commented Sep 7, 2017

This ticket was to investigate the performance; I was requesting a review of my investigation. Acceptance testing is to e.g. check the conclusions & recommendations I made.

@alxndrsn alxndrsn closed this as completed Sep 7, 2017
@alxndrsn alxndrsn removed the Status: Blocked Unable to progress this. label Sep 7, 2017
@alxndrsn alxndrsn reopened this Sep 7, 2017
@garethbowen
Copy link
Contributor

As discussed in the planning meeting: the investigation is done, and performance improvements can be tested with #3870

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Priority: 2 - Medium Normal priority Type: Performance Make something faster
Projects
None yet
Development

No branches or pull requests

4 participants