Welcome Guest, Not a member yet? Register   Sign In
Email sending is slow
#1

[eluser]skunkbad[/eluser]
I've got a standard contact form, and it posts back to itself. Standard form validation happens. Form validation seems very quick. Once the actual email is being sent, it is taking a long time to show confirmation that it is done. I've tried this on all browsers for Windows XP and on different computers/locations, and they are equally slow. IE6 on Windows 2000 doesn't work. FF on Mac actually seemed pretty fast, but I'm not sure why.

I'd like to speed up the process, or perhaps having it do it in the background so the user experience doesn't lag, but I don't have any ideas. I don't remember this being so slow, but I recently did some work to my website, and that's when I noticed.

Check out what I have here, and let me know what you think:

The controller:
Code:
<?php
class Contact extends Controller {

    public function index()
    {
        $this->load->library('session');
        $session_token = $this->session->flashdata('submit_token');

        //If there was a submission, as opposed to a refresh, or somebody hitting the back button of their browser:
        if (
            $this->input->post('token') &&
            isset($session_token) &&
            $this->input->post('token') == $this->session->flashdata('submit_token')
            ){

            //Load CodeIgniter validation library
            $this->load->library('form_validation');
            $this->form_validation->set_error_delimiters('<li>', '</li>');
            //Set up validation rules
            $this->form_validation->set_rules('realname', 'NAME' , 'trim|required|xss_clean|callback__clean_field_model[formval_callbacks]');
            $this->form_validation->set_rules('email', 'EMAIL ADDRESS' ,'trim|required|xss_clean|callback__basic_email_validation_model[formval_callbacks]');
            $this->form_validation->set_rules('mesg', 'MESSAGE' , 'trim|required|xss_clean|callback__clean_field_model[formval_callbacks]');
            //Run the validation
            $this->load->model('formval_callbacks');
            if ($this->form_validation->run() == FALSE){
                $view_data['fail'] = 1;
                $column_b['fail'] = 1;
                $view_data['error_message_stack'] = validation_errors();
                //repopulate the form since errors occurred
                $fields = array(
                    'realname',
                    'email',
                    'mesg'
                );
                foreach($fields as $field){
                    if(!array_key_exists($field, $this->form_validation->_error_array)){
                        //Repopulate only the fields that passed validation
                        $view_data[$field] = set_value($field);
                    }else{
                        //Set up good field indicator (asterisk) to be green
                        $error_array_keys["$field"] = $field;
                    }
                }
                //A resubmission is going to need another form token
                $token = md5(uniqid(rand(), TRUE));
                $this->session->set_flashdata('submit_token', $token );
                $view_data['token'] = $token;
            }else{
                $view_data['submit'] = 1;
                $column_b['submit'] = 1;
                $confirmation_message =    "<h3>Thank You!</h3>
                                        <p>Thank you for sending me a message.<br />I will get back to you shortly.</p>";
                //Show the thank you message
                $view_data['confirmation_message'] = $confirmation_message;
                // send the email
                $this->load->library('email');
                $this->email->from( set_value('email') , set_value('realname') );
                $this->email->to( '[email protected]' );
                $this->email->subject('BWD Contact Message ' . date("M j, Y"));
                $built_message['realname'] = set_value('realname');
                $built_message['email'] = set_value('email');
                $built_message['mesg'] = nl2br(set_value('mesg'));
                $this->email->message($this->load->view('contact_email', $built_message, TRUE));
                $this->email->send();
            }

        }else{
            //If no form submission, then user here for the first time, and needs a form token
            $token = md5(uniqid(rand(), TRUE));
            $this->session->set_flashdata('submit_token', $token );
            $view_data['token'] = $token;
        }

        // insert page specific data into template
        $data = array(
            'title' => 'Brian\'s Web Design - Contact Brian',
            'robots' => 'index,follow',
            'style_sheet_names' => array(
                                        'css/style.css',
                                        'css/page_specific/contact/screen.css'
            ),
            'media_targets' => array(
                                    'screen',
                                    'screen'
            ),
            'javascripts' => array(
                                    'js/target_blank.js',
                                    'js/contact_write.js',
                                    'js/contact_validate.js'
            ),
            'slogan' => 'I\'m really pretty easy to get ahold of ...',
            'content' => $this->load->view('contact', $view_data, TRUE )
        );

        $this->load->view('template_content', $data );
    }
#2

[eluser]BrianDHall[/eluser]
I have run into my emails being slower than I think it should be, but I don't even use the CI email class.

There are three ways to solve this:

1) The Easy Way Out - ignore the problem or use some sort of javascript interstitial to let the user know you are working and will let them know when you are done.

2) The Cron Que - setup your emails in such a way that a cronjob runs say every minute or so and sends emails for you. This way you can just let the user know you are sending them an email, and then as far as they know it has already been sent.

3) The l337 h@x0r Way - use pipes or exec to spawn a separate process in the server to run asynchronously to your script. So you just fire off the email script (directing output to /dev/null or using pipes with no listener) and let the user know the email is on the way, and a little while from then the email script will finish and the email will actually be sent.

Me, I go for option #1b, ignore the problem completely.
#3

[eluser]skunkbad[/eluser]
I guess I am considering what would happen if I used ob_flush() and/or flush(). If I was to take the block of code that sends the email, and put it after the page load is flushed, the page would theoretically load before the email was sent, right? I should know shortly if this actually works.


... edit ...

Apparently it won't work unless I disable output compression for the contact page. Still working on it ...

... another edit ...

Yes! Got it working with flush(); and by turning off zlib output compression at the top of my controller:

Code:
@ini_set('zlib.output_compression', 0);
#4

[eluser]skunkbad[/eluser]
I just want to let you know of an update to this issue. Yes, flush() seemed to work better than when I wasn't flushing, but the real performance increase, for whatever reason, was when I made the form action a relative link. After doing that, their is no slowness at all. It's odd that when I am just validating the form, the slowness isn't there, compared to when the email is actually sent. I just know things are way faster now!




Theme © iAndrew 2016 - Forum software by © MyBB