0

I'm setting up an extremely basic PHP/jQuery/Ajax contact form; and while it is working, the response is extremely slow (5+ seconds for the success message to show) and I'm wondering what I might be doing wrong.

Here is all the relevant code:

Markup:

<form id="contact-form" name="contact-form" action="php/form-process.php" method="post" role="form">
    <input type="text" name="name" id="name" placeholder="Name" required>
    <input type="email" name="email" id="email" placeholder="Email" required>
    <textarea id="message" name="message" rows="5" placeholder="Your message" required></textarea>
    <button type="submit" id="form-submit" class="contact-button">Submit</button>
    <div id="msg-submit" class="hidden">Message sumbitted!</div>
</form>

PHP:

<?php
$name = $_POST["name"];
$email = $_POST["email"];
$message = $_POST["message"];

$EmailTo = "test@test.com";
$Subject = "New Contact Form Message";

// prepare email body text
$Body .= "Name: ";
$Body .= $name;
$Body .= "\n";

$Body .= "Email: ";
$Body .= $email;
$Body .= "\n";

$Body .= "Message: ";
$Body .= $message;
$Body .= "\n";

// send email
$success = mail($EmailTo, $Subject, $Body, "From:".$email);

// redirect to success page
if ($success){
   echo "success";
}else{
    echo "invalid";
}

?>

jQuery:

$('#contact-form').submit(function(event){
        event.preventDefault();
        submitForm(); 
    });

    function submitForm(){
        var $this = $('#contact-form');
        $.ajax({
            type: $this.attr('method'),
            url: $this.attr('action'),
            data: $this.serialize(),
            success : function(text){
                if (text == "success"){
                    formSuccess();
                }
            }
        });
    }
    function formSuccess(){
        $("#msg-submit").removeClass("hidden");
    }

I'm leaving out all form validation functionality to stick to the absolute basics. I'm not sure if it's the server causing the slow response, but ideally, I'd like the success message to show as soon as the user clicks submit. Thanks for any assistance here.

nickpish
  • 839
  • 4
  • 24
  • 43

3 Answers3

1

Did you try to comment out
$success = mail($EmailTo, $Subject, $Body, "From:".$email); ?

I might be wrong, but, sending email might take a few seconds
i suggest you to send email using other ajax request.


Because PHP is not async language, at least by default.

  1. First PHP script: receive datas from JS, and respond with 200(success)
    jQuery will trigger 'success' event before sending Email.
    this will not block or bother you and other users.

  2. Second PHP script: just to send Email, without modal and etc.


   $.ajax({
        //here, you could send some infos to  use with DB, check if
       //datas, e-mail is valid with filter_var($email, FILTER_VALIDATE_EMAIL), etc..
        type: $this.attr('method'),
        url: $this.attr('action'),
        data: $this.serialize(), 
        success : function(text){
            if (text == "success"){
                formSuccess();
            }
        }
    });
   function formSuccess(){
       $("#msg-submit").removeClass("hidden");
       $.ajax({
        //here, you could send some infos to build and send Email
        //It's right, because the first ajax did succeed right ?
        type: $this.attr('method'),
        url: $this.attr('action'),
        data: $this.serialize(), 
        success : function(text){
            //yey :D
        }
   }
yukioxD
  • 81
  • 5
  • why do you recommend sending email using another request? How does that speed up the success/failure result? – BeetleJuice Aug 03 '16 at 20:14
  • Because PHP is not async language, at least by default. First PHP script just `receive datas from JS, and respond with 200(success)`, so jQuery will trigger 'success' event before dispatchEmail. this will not block or bother you and other users. ...And Second PHP script, just to send Email, without modal and etc. – yukioxD Aug 03 '16 at 20:22
  • Another AJAX request would make it non-transactional. One could succeed, the other could fail for whatever reason. And yes, PHP doesn't use different threads but it's exactly how it's supposed to be done. You can hack in some threading into PHP using `fork()`. I've done that in the past - it's not amazing, but if you really need more processes, it can work. – VLAZ Aug 03 '16 at 20:24
  • You're right, i've worked with `fork`, `Thread` before....I just though that it's more complex than 2 $.ajax. – yukioxD Aug 03 '16 at 20:34
  • @yukioxD thanks for the response-- that approach makes sense as far as dividing the response from the actual sending of the email. Could you provide a bit of direction as far as the jQuery/Ajax involved for an additional request? – nickpish Aug 03 '16 at 20:37
  • @nickpish I wouldn't do that. yukoxD, you misunderstood my question (1st comment under your post). I understand why the site will be more responsive. What I meant by my comment is: when you look at the point of this form, `success` should mean that the message was sent successfully. In fact, that's what the OP's original code guarantees. By breaking things up into two requests, you can have a situation where the user gets `success`, but the message is never sent. – BeetleJuice Aug 03 '16 at 20:42
  • updated my res again, I hope this help you :D .... but, as you see, my option is not the perfect one. I hope you understand what is happening on JS and PHP Code....... thought I believe that, if you check your inputs and outputs it's should work. – yukioxD Aug 03 '16 at 20:52
1

I'm going to assume you're assuming PHPMailer, but correct me if I'm wrong. If not, consider using that to implement this next part.

Your PHP script is waiting for the email to be sent. That's not how it should be done. You need to send it using a mail server. See this superb answer on how to do that using PHPMailer.

Community
  • 1
  • 1
Nick Bull
  • 9,518
  • 6
  • 36
  • 58
  • I'm not actually using PHPMailer, I believe it's just the default PHP mail function-- I will check out the link you've provided, thank you. – nickpish Aug 03 '16 at 20:15
  • more specifically, are you suggesting using an email queue as described in the answer you referenced? – nickpish Aug 03 '16 at 20:22
  • @nickpish Yes I am, or any way to send the messages outside of that script. – Nick Bull Aug 03 '16 at 20:28
  • just circling back here: I implemented PHPMailer as suggested, and it's working like a charm! I'm using SMTP and the the response time went down from over 6s with `mail()` to just over 1s with SMTP and PHPMailer. Thank you! – nickpish Aug 04 '16 at 05:56
1

@nickpish

you have php, jquery and ajax. the issue with the bottleneck can either be the front-end or the backend. you need a powerful tool in order to debug the issue. if you have an error in your jquery there is no way to figure that out. in addition, if you have a backend issue, that can cause your jquery to take more time in responding back to your front-end ui. if you look at the image below

enter image description here

you need to use something like firefox, (right click anywhere on your ui and select [Inspect Element Q] click on the net panel and choose XHR. in the console window you'll see if there are any errors; furthermore, you'll notice your back-end php file and it'll give you a response time.

if the back-end script is too slow, you can go into your back-end file. you have a mail function, maybe it's the server that's taking too long. you may need to switch out your smtp to something faster or leave it as is. if you choose to stay with your current smtp that may take time, you should think of putting a progress window meanwhile.

unixmiah
  • 3,081
  • 1
  • 12
  • 26
  • thanks for the response, @unixmiah. I just checked using dev tools, and I'm not seeing any errors at all, just a `POST` `XHR` "OK" response at 6089ms, which I guess explains the wait. – nickpish Aug 03 '16 at 20:33