Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CodeIgniter Performance load view multiple times vs loop in view

I'm trying to solve possible scaling performance issue. Is there a more clear performance benefit to these two scenarios:

Scenario 1:

Make several calls to load a view and pass a small amount of data each time

Controller

public function index()
{
    $this->load->view('header');
    $this->load->view('table_head');
    $results = $this->db->select('*')->from('table')->get()->result_array();
    foreach ($results as $key)
    {
        $this->load->view('table_row', $key);
    }
    $this->load->view('table_foot');
    $this->load->view('footer');
}

View table_head

<table>
    <thead>
        <tr>
            <th>...</th>
            <th>...</th>
            ...
        </tr>
    </thead>
    <tbody>

View table_row

        <tr>
            <td><?php echo $var_a; ?></td>
            <td><?php echo $var_b; ?></td>
            ...
        </tr>

View Table_foot

    </tbody>
    <tfoot>
        <tr>
            <td>...</td>
            <td>...</td>
            ...
        </tr>
    </tfoot>
</table>

Scenario 2:

Make 1 call to load a view and pass a large amount of data

Controller

public function index()
{
    $this->load->view('header');
    $this->data['results'] = $this->db->select('*')->from('table')->get()->result_array();
    $this->load->view('table', $this->data);
    $this->load->view('footer');
}

View table

...
<table>
    <thead>Header Info...</thead>
    <tbody>
        <?php foreach ($results as $key): ?>
            <tr>echo row information as needed</tr>
        <?php endforeach; ?>
    </tbody>
<table>
...

I've been using scenario 1 because it is helping to keep my application modular and keep the MVC format by keeping logic loops in the controller. But say the result from the SQL call is 1000 entries, or even more, is there a clear performance difference between the two scenarios? Am I attempting to make my application too modular? I do try to recycle as much of my code as I can, and as a result more of my methods will load at minimum 8 views.

like image 428
adambullmer Avatar asked Oct 16 '25 17:10

adambullmer


1 Answers

Well, I broke down and wrote a small script to inflate my table for these testing purposes. Here are the results of my small test. To keep the tests equivalent, I only change which view I am displaying.

Scenario 1

Controller:

public function results()
{
    $this->load->view('headers/header', $this->default_lib->viewdata());
    $this->load->view('body_bits/bodyopen');
    $this->title['title'] = 'Testing Tesults';
    $this->title['link'] = 'tests';
    $this->title['link_text'] = 'Back to Tests';
    $this->load->view('body_bits/page_title', $this->title);
    $this->load->view('tests/results_open');

    $results = $this->db->select('*')->
        from('test_results')->
        where('software', 'nwralpha')->
        order_by('time', 'ASC')->
        //limit('10')->
        get()->result_array();
    foreach ($results as $key)
    {
        $this->data['name'] = ucwords($this->ion_auth->user($key['user_id'])->row()->username);
        $this->data['time_taken'] = $key['time'];
        $this->data['test_taken'] = $key['test_type'];
        $this->data['common'] = ($key['common_codes'] == 1) ? 'Common Code List' : 'Full Code List';
        $this->data['date'] = $key['date'];

        $this->load->view('tests/results', $this->data);
    }

    $this->load->view('tests/results_close');
    $this->load->view('body_bits/bodyclose');
    $this->load->view('footers/footer');
}

View

<tr>
    <td><?php echo $name; ?></td>
    <td><?php echo $time_taken; ?></td>
    <td><?php echo $test_taken; ?></td>
    <td><?php echo $common; ?></td>
    <td><?php echo $date; ?></td>
</tr>

Scenario 2

Controller:

public function results()
{
    $this->load->view('headers/header', $this->default_lib->viewdata());
    $this->load->view('body_bits/bodyopen');
    $this->title['title'] = 'Testing Tesults';
    $this->title['link'] = 'tests';
    $this->title['link_text'] = 'Back to Tests';
    $this->load->view('body_bits/page_title', $this->title);
    $this->load->view('tests/results_open');

    $results = $this->db->select('*')->
        from('test_results')->
        where('software', 'nwralpha')->
        order_by('time', 'ASC')->
        //limit('10')->
        get()->result_array();

    $this->data['results'] = $results;
    $this->load->view('tests/resultsloop', $this->data);

    $this->load->view('tests/results_close');
    $this->load->view('body_bits/bodyclose');
    $this->load->view('footers/footer');
}

View

<?php foreach ($results as $key): ?>
<tr>
    <td><?php echo ucwords($this->ion_auth->user($key['user_id'])->row()->username); ?></td>
    <td><?php echo $key['time']; ?></td>
    <td><?php echo $key['test_type']; ?></td>
    <td><?php echo $key['common_codes']; ?></td>
    <td><?php echo $key['date']; ?></td>
</tr>
<?php endforeach; ?>

Results

I tested both examples with 1004 results and with 11004 results and here is what I found using CodeIgniter's built in Profiler

1004 Results

Scenario 1 Average Load Time: 1.94462 Seconds
Scenario 2 Average Load Time: 1.1723 Seconds

11004 Results

Scenario 1 Average Load Time: 19.78867 Seconds
Scenario 2 Average Load Time: 11.81502 Seconds

What This Means

For anyone else who just wants to know the answer and not read this whole post:
While Separation of logic and HTML is the point of MVC frameworks, There are acceptable cases where you can use logic to determine how to display information. In this case, I only used a loop to keep spitting out uniform information as needed. This test shows that it is more efficient to make the least amount of view calls.

like image 153
adambullmer Avatar answered Oct 19 '25 08:10

adambullmer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!