2012-02-29 13 views
5

Comencé mi viaje para acelerar el autocompletado de jQuery esta tarde, y decidí que probablemente era una buena idea comenzar memcaching todo. Como se sugiere en este artículo: Speeding up autocomplete.Acelerando jQuery AutoComplete (listas innecesariamente largas)

Sin embargo, todavía estoy lidiando con un tiempo de respuesta lento incluso después de instalar y usar Memcached.

El problema en mi caso es que estoy tratando con listas extraordinariamente largos, en mi caso, sobre miembros individuales. (Todos los géneros o géneros de todas las plantas)

El cuello de botella parece estar construyendo la tabla y rellenando la lista del lado del cliente, y no es causada al recuperar la información de Memcached.

Si alguien más se ha encontrado con este problema en particular, me gustaría saber de una forma inteligente de resolverlo. Voy a publicar mi código a continuación.

Nota: Esta página en particular no está disponible para el público en general, y soy consciente de que hay algunos agujeros de seguridad muy abiertos.


require_once 'oo/Database.php'; 

$mysqldb = new Database; 

$memcache = new Memcache; 
$memcache->connect('localhost', 11211) or die ("Could not connect to memcache"); 

$sql = "SELECT DISTINCT `Genus` FROM importlist.plants"; 

$key = md5('query'.$sql); 

$result = $memcache->get($key); 


//check if we got something back 
if($result == null) { 

    //fetch from database 
    $result = $mysqldb->rawSelect($sql)->getResult(); 

    //set to memcache, expires after 1 hour 
    $memcache->set($key,$result,0,3600); 
} 

//Result array 
$Genera = ($memcache->get($key)); 

//Add required "quotation marks" for autocomplete 
foreach ($Genera as &$Genus){ 
    $Genus = '"'.$Genus[Genus].'"'; 
} 
$Genera = implode($Genera,','); 

//PHP to generate jQuery  
echo <<< EOT 

    <script> 
    $(function() { 
     var availableTags = [$Genera]; 
     $("#tags").autocomplete({ 
      source: availableTags 
     }); 
    }); 
    </script> 
EOT; 

?> 

<input id="tags" /> 
+2

No sé si esto lo aceleraría en absoluto, pero debería poder establecer '$ Genera = $ result' en lugar de hacer la segunda llamada a la Memcache. O mejor aún, solo use '$ result' en su' foreach() 'en vez de' $ Genera' – jprofitt

+2

¿Puede usar una solicitud de Ajax para llenar los datos después de que la página se cargue o antes de que el usuario intente usar el autocompletado? – jmort253

+4

Parece que está emulando creando una notación json de una matriz. Probablemente 'json_encode' te dará una mejor velocidad que el foreach. Sin embargo, primero debe averiguar qué parte de ese fragmento de código consume tanto tiempo. Localice el cuello de botella primero ejecutando algunas métricas. – hakre

Respuesta

5
$(document).ready(function() { 

    // once page loads, make AJAX request to get your autocomplete list and apply to HTML 
    $.ajax({ url: '/path-to-get-tags-as-json.php', 
     type: "GET", 
     contentType: "application/json", 
     success: function(tags) { 
      $("#tags").autocomplete({ 
       source: tags 
      }); 
     } 
    }); 
}); 

Coloque la dirección URL de su archivo PHP en genera la lista de autocompletar en el parámetro anterior AJAX url marcador de posición. En su código PHP, modifique la generación de la lista para que devuelva una matriz JSON de valores, así:

[ "first" , "second" , "anotherEntry" , "in" , "the" , "array" ]  

Esto se definitivamente no acelerar el lado del servidor proceso de, pero se proteger su usuarios de algunas de las demoras en la aplicación de la lista de autocompletar. Esto supone, en gran medida, que el usuario no ejecuta de forma instantánea una acción que requiere la función de autocompletar, sino que puede cargar la página y permitir que el usuario realice otras acciones. La carga de la lista de autocompletar debería, en su mayor parte, parecer silenciosa e ininterrumpida.

Esto es ideal para tiempos de carga que son de menos de unos pocos segundos, pero si le lleva más tiempo que eso, entonces los usuarios pueden tener problemas de usabilidad.

Si todavía hay retrasos en el servidor, considere usar algunas sentencias de tiempo para intentar determinar dónde está el cuello de botella.

+0

Si utiliza esto, puede reemplazar su ciclo foreach con json_encode. –

+4

Exactamente lo que estaba pensando. No sería difícil hacer el cambio, y lo haría ver más Web 2.0 y posiblemente un poco más rápido. También debo agregar que Afonso puede necesitar establecer el tipo de contenido en PHP en "aplicación/json" antes de devolver la matriz JSON para que el navegador la reconozca como JSON. – jmort253

+1

http://stackoverflow.com/a/6807488/367456 – hakre

1

Puesto que no se puede buscar nada hasta que el usuario escribe al menos 1 carácter, puede crear 26 listas diferentes. Cada lista de autocompletar solo contiene los elementos que comienzan con esa letra. Sus listas serán significativamente más pequeñas y más rápidas de cargar.

Para que sea aún más rápido, cree más listas. Probablemente solo necesites los primeros 30-40 elementos para mostrar. Si el artículo no está en la lista abreviada, es muy probable que el usuario escriba otra letra. A continuación, puede dividir sus listas en 26 * 26 listas únicas. Cada lista contiene solo elementos que comienzan con las primeras 2 letras.

Puede dividir sus elementos en tantas listas como sea necesario. Hacemos esto en un sitio que administro donde tenemos más de 500,000 ítems disponibles en nuestra cabecera.

Cuestiones relacionadas