CodeIgniter Efficiency of loading multiple times versus loop
I am trying to solve a possible performance scaling issue. Is there a more obvious performance advantage for these two scenarios:
Scenario 1:
Make multiple calls to load the view and transfer 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 view and transfer 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');
}
Show table
...
<table>
<thead>Header Info...</thead>
<tbody>
<?php foreach ($results as $key): ?>
<tr>echo row information as needed</tr>
<?php endforeach; ?>
</tbody>
<table>
...
I use scenario 1 because it helps maintain a modular application and maintains the MVC format while keeping the logic outlines in the controller. But tell me the result of the SQL call is 1000 records or even more, is there a clear performance difference between the two scenarios? Am I trying to make my application too modular? I am trying to rework as much code as possible and as a result my methods will load at least 8 views.
source to share
Ok I broke down and wrote a small script to inflate the table for these testing purposes. Here are the results of my little test. To make the tests equivalent, I only change the view I am showing.
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 11004 results and this 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 does this mean
For someone who just wants to know the answer and not read this entire post:
While separating 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 used the loop only to splash out single information as needed. This test shows that it is more efficient to make the fewest calls.
source to share
imho the controller renders the appropriate assets - in the correct view. for example, if you get no results, the course of action for the "no results" condition should happen in the controller. (versus checking if your view has $ results)
Logic for - how do we show results? - happens in the view. The controller passes $ results, the view is then responsible for displaying those results. With scenario # 1, you have to log into your controller, make changes to the page design.
And when $ results is too big ... then use pagination.
source to share