View previous topic :: View next topic |
Author |
Message |
greenlander Smarty n00b
Joined: 01 Jul 2009 Posts: 3
|
Posted: Wed Jul 01, 2009 2:38 pm Post subject: Includes are terribly slow - what to do? |
|
|
I'm currently in the process of building a site with Smarty. However, some pages are loading really slow. After profiling with xdebug, I found out that on this page 5 seconds is spent on rendering the template. This seems to happen because includes are really slow.
Code: | <tr>
<td><a href="product_details.html?id={$row->getId()}">{$row->getCompany()|htmlentities}</a></td>
{if $resultSet->getHasProductName()}<td><a href="product_details.html?id={$row->getId()}">{$row->getProductName()|htmlentities}</td>{/if}
<td>€ {$row->getPremium()|number_format:2:",":"."}</td>
{foreach from=$extraColumns item="column"}
<td>{include file=$column->getTemplate() detail=$column}</td>
{/foreach}
</tr> |
The foreach loop runs about 300 times, the included templates are never longer than 2 lines and don't contain any loops or logic whatsoever. Removing the include increases the speed drastically (I did not measure it, but pages seem to load under 1 second now).
Caching does improve the load time, but the data on this page is different every time it is loaded, so that won't really have an effect on the user experencie in a production environment.
Integrating the included templates in this one isn't really an option unfortunately, since we would then have to have some very large and complex if's, which makes the code really unmaintainable. Does anybody have an idea how to improve the speed? |
|
Back to top |
|
philoertel Smarty Rookie
Joined: 25 Jun 2009 Posts: 14 Location: Chicago, IL
|
Posted: Wed Jul 01, 2009 3:41 pm Post subject: |
|
|
Sounds like you know exactly what the problem is. Loading 300 templates is going to take a long time. Assume an average 10-20ms seek time (stole that from wikipedia ;), that's 3-6 seconds just for the first byte of each file. Reading the remaining bytes will take a little longer, and page caching and disk prefetching will shorten it a little, so 5s just for I/O sounds reasonable.
You could throw memory at the problem. That'll give your OS more room for the page cache. Might help.
But if you're looking for a serious speed boost you'll need to rethink your solution. You're I/O bound, so get rid of the I/O! Instead of storing 300+ templates on disk and storing their paths in the database, cut out the middleman and store the template code in the database as a varchar.
Optimizing further might not be possible, but I'm suspicious of your 300+ arbitrary styles. Can you restrict that space and represent the templates' differences using a few variables?
good luck! _________________ Phil Oertel
Application Developer
http://www.soliantconsulting.com |
|
Back to top |
|
jLix Smarty Regular
Joined: 01 Apr 2009 Posts: 59 Location: Lowlands, EU
|
Posted: Wed Jul 01, 2009 5:03 pm Post subject: |
|
|
How many different templates do you have to include and can you give some examples of them to get an idea what we're talking about here? _________________ http://jlix.net/extensions/smarty |
|
Back to top |
|
greenlander Smarty n00b
Joined: 01 Jul 2009 Posts: 3
|
Posted: Wed Jul 01, 2009 6:40 pm Post subject: |
|
|
Quote: | Sounds like you know exactly what the problem is. Loading 300 templates is going to take a long time. Assume an average 10-20ms seek time (stole that from wikipedia , that's 3-6 seconds just for the first byte of each file. Reading the remaining bytes will take a little longer, and page caching and disk prefetching will shorten it a little, so 5s just for I/O sounds reasonable. |
I understand that, but when I include 3 small PHP scripts 400 times each, it only takes ~0.1s. So unless I'm missing something, I/O doesn't seem to be the main problem.
jLix wrote: | How many different templates do you have to include and can you give some examples of them to get an idea what we're talking about here? |
The list isn't finalized yet, but the total number of templates will probably be smaller than 10. Basically every template formats a cell in a table. It might simply display them as text or format a number. They might be a bit more complex than that, but I doubt any template will be larger than 7 lines. The simplest one looks like this:
Code: | {assign var="cat" value=$detail->getCategory()}
{$row->getDetailValue($cat->getId(), $detail->getId())|htmlentities} |
We chose this way of loading the templates to achieve maximum flexibility and easier maintenance. Every cell type is described by a class and embedding the template name in the class means that you don't have to edit main templates when you add a cell type. We're using these cells (value+lay-out) on multiple pages, so using subtemplates allows for easier editing of the way these cells are displayed. Also, you can change the template on individual cells, allowing to format some cell in a non-standard way. The last reason is that the formatting of the cells might depend on the domain name (we use the back-end software for different sites), which is handled by the getTemplate() function.
BTW, including 300 templates is a maximum and a pretty rare case. We are however planning on using this approach all over the site, so it is probably worth finding out if a faster approach could be found. We're not expecting, however, to load this specific page in <0.5 seconds |
|
Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Wed Jul 01, 2009 9:06 pm Post subject: |
|
|
The performance is also dependent on the compile_check configuration parameter of Smarty. If this is true (which is default) on every call of {include } Smarty checks if the template source has been modifed and recompilation is required. If the template sources are stable the diabling of compile_check may spped things up a bit.
But I think best performance would be to do the work of your foreach loop in one way or the other in the PHP script and assign that result into a Smarty variable. |
|
Back to top |
|
mohrt Administrator
Joined: 16 Apr 2003 Posts: 7368 Location: Lincoln Nebraska, USA
|
Posted: Thu Jul 02, 2009 2:04 am Post subject: |
|
|
$smarty->compile_check = false;
$smarty->caching = true;
also use a PHP op-code cache such as APC, eAccelerator or XCache |
|
Back to top |
|
greenlander Smarty n00b
Joined: 01 Jul 2009 Posts: 3
|
Posted: Thu Jul 02, 2009 9:25 am Post subject: |
|
|
Quote: | $smarty->compile_check = false; |
This increased the speed to an acceptable level, so we will simply use this in the production environment. Thank you very much! |
|
Back to top |
|
|