patternjavascriptMinor
Slow Performance of AJAX Submitted Webform
Viewed 0 times
ajaxwebformslowperformancesubmitted
Problem
I am creating a poll that website visitors can then vote. I use a hosted CMS (Business Catalyst) so I have to do a lot of this with javascript.
I have the poll working but when I click submit it is taking around 15 to 20 seconds for the poll to submit. I really need to improve this performance but unsure how to do so.
Below is the script I am using. I did not write this but followed some examples for getting it to work. I am using Business Catalyst's Web Apps to create the poll.
Here is how it works. There is a form on a page that looks like this:
The script sees which option the user sees and adds a 1 to the total votes. We then take the information and submit it to the system.
Because we are using web apps, BC required the user to be logged in. Since we do not want to require a user to be logged in to vote, we log in an anonymous user, unless they are already logged in. Take the data, submit the data, logout the anonymous user (we do not log out a logged in user) and reload the page.
Any code in
Here is the code being used.
```
var Engine = {
ui : {
pollSubmit : function(){
if($("#pollAnswers{{itemid}}").size() === 0){return;}
var $form = $("#pollAnswers{{itemid}}"), // ID of Poll
$radioOptions = $form.find("input[type='radio']"),
$webAppItemName = "{{name}}", //{{name}} is a system tag that will render the name of the poll
$formButton = $form.find("button"),
bcField_1 = "CAT_Custom_2",
answer_1 = parseInt({{this.['Answer 1 Votes']}}),
bcField_2 = "CAT_Custom_4",
answer_2 = parseInt({{this.['Answer 2 Votes']}}),
bcField_3 = "CAT_Custom_6",
answer_3 = parseInt({{this.['Answer 3 Votes']}}),
$formSubmitData = "",
preElem;
$radioOptions.
I have the poll working but when I click submit it is taking around 15 to 20 seconds for the poll to submit. I really need to improve this performance but unsure how to do so.
Below is the script I am using. I did not write this but followed some examples for getting it to work. I am using Business Catalyst's Web Apps to create the poll.
Here is how it works. There is a form on a page that looks like this:
Answer 1
Answer 2
Answer 3
Vote
Your vote is submitting, please wait while we tally the votes.
The script sees which option the user sees and adds a 1 to the total votes. We then take the information and submit it to the system.
Because we are using web apps, BC required the user to be logged in. Since we do not want to require a user to be logged in to vote, we log in an anonymous user, unless they are already logged in. Take the data, submit the data, logout the anonymous user (we do not log out a logged in user) and reload the page.
Any code in
{{ }} is rendered on the server. For example {{itemid}} would render 123456, the ID of that web app item.Here is the code being used.
```
var Engine = {
ui : {
pollSubmit : function(){
if($("#pollAnswers{{itemid}}").size() === 0){return;}
var $form = $("#pollAnswers{{itemid}}"), // ID of Poll
$radioOptions = $form.find("input[type='radio']"),
$webAppItemName = "{{name}}", //{{name}} is a system tag that will render the name of the poll
$formButton = $form.find("button"),
bcField_1 = "CAT_Custom_2",
answer_1 = parseInt({{this.['Answer 1 Votes']}}),
bcField_2 = "CAT_Custom_4",
answer_2 = parseInt({{this.['Answer 2 Votes']}}),
bcField_3 = "CAT_Custom_6",
answer_3 = parseInt({{this.['Answer 3 Votes']}}),
$formSubmitData = "",
preElem;
$radioOptions.
Solution
Having the values in
The next issue is
I also noticed that you used a cookie to tell whether someone already voted. The problem here is cookies can be deleted. If I go in private mode, or just delete my browser history, I can just vote again. I better option would be to send to the server a bunch of identifying data, a combination of browser name, version, os name, os version, referrer etc. These data are usually present in the HTTP request header, mostly on the useragent string. Then compute a hash for the combination and store it in the server with the vote. Once the user will try to vote again using the setup, it should produce the same hash, you can disregard the vote. It's not foolproof, but the user would need to go through all the hoops just to change the stuff needed by your hash. This is also how ads track you by the way.
Now its down to your AJAX. The problem is you need to fire them in sequence just because you need to login, cast the vote and logout. A better solution would be to just expose a single public endpoint for anonymous voting. Because logging in/logging out just makes no sense when the account is pretty much public. You just have to tell your server to record the vote as the public user.
{{ }} rendered by the server on your script is a bad idea. What if the server chokes and returns an invalid value? What happens to your script? I suggest that the server creates an object containing all those values, then print that object on the page. This is usually done by creating an object, serializing it to JSON, then print the JSON to the page. Then have your script validate and access that object afterwards.The next issue is
parseInt. You have no checks if the value returned by parseInt is a number at all. You usually use isNaN for that. Also, it's best practice to provide parseInt with a base as second argument. This is so that parseInt would know how to parse the string. Otherwise, it will treat your string as some other value (octal in some implementations instead of decimal).I also noticed that you used a cookie to tell whether someone already voted. The problem here is cookies can be deleted. If I go in private mode, or just delete my browser history, I can just vote again. I better option would be to send to the server a bunch of identifying data, a combination of browser name, version, os name, os version, referrer etc. These data are usually present in the HTTP request header, mostly on the useragent string. Then compute a hash for the combination and store it in the server with the vote. Once the user will try to vote again using the setup, it should produce the same hash, you can disregard the vote. It's not foolproof, but the user would need to go through all the hoops just to change the stuff needed by your hash. This is also how ads track you by the way.
Now its down to your AJAX. The problem is you need to fire them in sequence just because you need to login, cast the vote and logout. A better solution would be to just expose a single public endpoint for anonymous voting. Because logging in/logging out just makes no sense when the account is pretty much public. You just have to tell your server to record the vote as the public user.
Context
StackExchange Code Review Q#109056, answer score: 2
Revisions (0)
No revisions yet.