Why load all pagers on every node view? Jeff Eaton, have you lost your damn mind?

robertDouglass - January 31, 2009 - 00:35
Project:Custom Pagers
Version:6.x-1.x-dev
Component:Code
Category:bug report
Priority:normal
Assigned:Unassigned
Status:active
Description

(Hope you've been watching Chocolate News ;-)

<?php
function custom_pagers_nodeapi(&$node, $op, $teaser, $page) {
  switch (
$op) {
    case
'view':
     
// We want to make sure we don't try to output when print.module is active.
      // It's a bit of special casing but it doesn't do much harm.
     
if ($teaser == false && empty($node->printing)) {
       
$pagers = _custom_pagers_load_all_pagers();
        foreach (
$pagers as $pager) {
          if (
$pager->position != 'block' && _custom_pagers_visibility($pager, $node)) {
           
$nav_array = custom_pager_build_nav($pager, $node); <-- THIS WILL LOAD AND EXECUTE A VIEW FOR EVERY PAGER IN SOME CONDITIONS
?>

So, the problem is that I have a content type. And I have six node queues. And six custom pagers. The pagers all use a view provided by a different node queue. Some nodes are in fact in more than one queue, but really they're usually in one queue. So I used the content type to determine visibility, which is a mistake. Because now, for every node load, all six node queue views get loaded and executed, even though only one of them will be used to created the pager.

How to fix this? Well, you could require me to write PHP to calculate the visibility, and I'd have to determine whether the given node is in a given node queue, but really the best solution would be to add a third option (perhaps replacing the PHP altogether), and that is to use a view to determine visibility. This would let you front-load the view->execute() (to determine visibility) and reuse the $view for generating the pager.

#1

eaton - March 31, 2009 - 16:08

Hmmm, I'm not sure how it would be any better using a view to filter -- we'd still need to load all the pagers on every node view to get the names of the Views to USE for filtering... It does to static caching, so if multiple nodes are being viewed in one page cycle it only hits the custom_pagers table once. But, the idea of filtering with views is definitely intriguing...

How to fix this? Well, you could require me to write PHP to calculate the visibility, and I'd have to determine whether the given node is in a given node queue, but really the best solution would be to add a third option (perhaps replacing the PHP altogether), and that is to use a view to determine visibility. This would let you front-load the view->execute() (to determine visibility) and reuse the $view for generating the pager.

The performance impact of a pager on a site that has a large number of nodes is... scary, in part because the views are executed without any limiting. One possibility is to run the query for each view -- WITH a custom 'AND node.nid = $nid' filter added to the query. If the results come up empty, it's not in the view. I'm not sure if that would actually help with the query speed if the view itself is crazy-complicated, though. Will need to take a look. Hmmmmmm...

If this does work and the performance hit isn't hellacious, it might be worth removing the 'content type' filtering entirely, and just relying on the views. I'm still worried about the potential impact of running a bunch of views on a large site just to determine whether the pager should be visible. Hmm.

#2

robertDouglass - April 1, 2009 - 14:35

Agree it's a hard problem. Glad you're thinking about it.

#3

Flying Drupalist - April 19, 2009 - 00:38

WHOA! This is huge!

Subscribe, and I'm hoping for a solution soon!

#4

asak - July 13, 2009 - 12:35

Subscribing...

 
 

Drupal is a registered trademark of Dries Buytaert.