nikola Posted March 20, 2013 Share Posted March 20, 2013 I had this structure in template before, but without the functions, and I repetead it manually and it worked fine and fast. Since I've made 3 function to do it automatically, page render slowed down dramatically (for now I have around 400 articles). I'm calling these 4 function 5 times on home page (for 5 different main categories). "kategorije" means "categories" // Article Header function homeHeader($category) { $category = wire('pages')->get("/kategorije/$category/"); foreach($category->children as $subcategory) { $subcategories[] = $subcategory->id; } $array = implode("|",$subcategories); $articles = wire('pages')->find("subcategory=$array, template=article, sort=-date"); echo "<a href='{$category->url}' class='all-categories'>Sve podkategorije</a>"; echo "<form class='category-select' method='get' action='#'>"; echo "<select name='category' class='selectyze' >"; echo "<option>Odaberi podkategoriju</option>"; echo "<optgroup label='Podkategorije'>"; foreach($category->children as $option) { echo "<option value='{$option->url}'>{$option->title}</option>"; } echo "</optgroup>"; echo "</select>"; echo "</form>"; echo "<h2><a href='{$category->url}'>{$category->title}</a> <span>(" . count($articles) . ")</span></h2>"; echo "<div class='clear'></div>"; } // Home Main Article function homeMainArticle($category, $start) { $category = wire('pages')->get("/kategorije/$category/"); foreach($category->children as $subcategory) { $subcategories[] = $subcategory->name; } $array = implode("|",$subcategories); $articles = wire('pages')->find("subcategory=$array, template=article, start=$start, limit=1, sort=-date"); foreach($articles as $article) { if(count($article->images) > 0) { $image = $article->images->first(); echo "<img class='align-left' src='" . $image->getThumb('bigthumb') . "' alt='{$image->description}' width='198' height='136' />"; } else { $image = "<img class='align-left' src='{$config->urls->templates}img/no-image-198-136.png' width='198' height='136' />"; echo $image; } echo "<h2><a href='{$article->url}'>{$article->title}</a></h2>"; $body = strip_tags(preg_replace("/(<h[1-6]>.*?<\/h[1-6]>|\[.*\])/m","",$article->body)); if (strlen($body) > 340) { $excerpt = excerpt($body, 0, 340); echo "<p>" . $excerpt . '<a href="' . $article->url . '"> više</a></p>'; } else { echo "<p>" . $body . "</p>"; } } } // Home Article function homeArticle($category) { $category = wire('pages')->get("/kategorije/$category/"); foreach($category->children as $subcategory) { $subcategories[] = $subcategory->name; } $array = implode("|",$subcategories); $articles = wire('pages')->find("subcategory=$array, template=article, start=2, limit=4, sort=-date"); foreach($articles as $article) { echo "<li>"; if(count($article->images) > 0) { $image = $article->images->first(); echo "<img class='img-left' src='" . $image->getThumb('thumb') . "' alt='{$image->description}' width='96' height='64' />"; } else { $image = "<img class='img-left' src='{$config->urls->templates}img/no-image-96-64.png' width='96' height='64' />"; echo $image; } echo "<a class='article-title' href='{$article->url}'>{$article->title}</a>"; $body = strip_tags(preg_replace("/(<h[1-6]>.*?<\/h[1-6]>|\[.*\])/m","",$article->body)); if (strlen($body) > 100) { $excerpt = excerpt($body, 0, 100); echo "<p>" . $excerpt . '<a href="' . $article->url . '"> više</a></p>'; } else { echo "<p>" . $body . "</p>"; } echo"</li>"; } } What could be wrong? Link to comment Share on other sites More sharing options...
nik Posted March 20, 2013 Share Posted March 20, 2013 I'm not quite sure why this would be any slower when using functions, but here's a couple of things that you could make a bit more effective. Some of it is mostly cosmetic though.This bit of code: $category = wire('pages')->get("/kategorije/$category/"); foreach($category->children as $subcategory) { $subcategories[] = $subcategory->id; } $array = implode("|",$subcategories); $articles = wire('pages')->find("subcategory=$array, template=article, sort=-date"); Could be written like this (letting the core do what you done yourself): $array = wire('pages')->find("parent=/kategorije/$category/"); $articles = wire('pages')->find("subcategory=$array, template=article, sort=-date"); The other two functions have the same bit of code, but with $subcategory->name. I would have thought that doesn't even work.. does it? I think you meant the same thing in all those cases anyway.Then, if you're calling the same functions for the same categories and they all do the same subcategory-thing commented above, it would be better to construct the subcategories just once and use the same array three times. Just give the subcategory array as an additional parameter to the functions you're calling.Maybe there's something there I didn't see right away, but I hope these help even a little bit . The effect isn't necessarily huge as ProcessWire does a good job caching previously fetched Page objects, but I guess it's worth a try anyway. 1 Link to comment Share on other sites More sharing options...
nikola Posted March 20, 2013 Author Share Posted March 20, 2013 Thanks nik, I ended up with the code in the template itself in one big foreach that outputs the same code above and page executes in one second with all the extra code in header and footer. It looks like to me that it chokes somewhere when used through function... Link to comment Share on other sites More sharing options...
ryan Posted March 21, 2013 Share Posted March 21, 2013 In addition to what Nik mentioned, I would see if you can narrow down where the bottleneck is. Add the following to the beginning of each function: $timer = Debug::timer(); And add the following to the end of each function: echo "<p>" . __FUNCTION__ . " with page $category->path executed in " . Debug::timer($timer) . " seconds.</p>"; That might help to narrow it down. But if these function calls really are generating navigation with 400+ items, I probably wouldn't expect it to be lightning fast. It would be a good candidate for using MarkupCache. To use MarkupCache, replace all your "echo string" lines in the function with "$out .= string", so that you are populating a variable with the output rather than echoing it. Ideally your functions return the output so that the caller can do the echo, but you could also just put your echo at the bottom of the function. Once you've done that, you can use MarkupCache by putting this at the top of your function: $seconds = 86400; // 1 day, or 3600=1 hour $cache = wire('modules')->get('MarkupCache'); $out = $cache->get("homeHeader($category)", $seconds); if($out) return $out; // or echo $out; // ...the rest of your function code... $cache->save($out); return $out; // or echo $out; 2 Link to comment Share on other sites More sharing options...
nikola Posted March 25, 2013 Author Share Posted March 25, 2013 I've sorted it out. The problem was with the array wrongly set up. It pulled page references that weren't needed at all. I wrapped it all up in a single function and automated categories and subcategories pulling with custom selectors for articles and it works fast and smooth Thanks for your help guys! 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now