Introducción
Tengo (en su mayoría) una sola página application construida con BackboneJS y un servidor Rails.¿Cómo mejorar el rendimiento de la aplicación de una sola página?
Como la mayor parte de la interacción ocurre en una página de la aplicación web, cuando el usuario visita la página por primera vez, básicamente tengo que extraer gran cantidad de información de la base de datos en una consulta grande profundamente unida.
Esto me está provocando tiempos de carga bastante extremos en esta página.
NewRelic me parece estar diciendo que la mayoría de mis problemas se deben a que de 457 llamadas a métodos rápidos individuales.
Ahora he hecho toda la carga ansiosa que puedo hacer (he comprobado con el Bullet gem) y todavía tengo un problema.
Estas llamadas a métodos son más comunes en mi serializador Rabl que utilizo para serializar un grupo de JSON para incrustar en la página para inicializar Backbone. No necesita comprender todo esto, pero basta con decir que podría agregar hasta 457 llamadas a métodos.
object @search
attributes :id, :name, :subscription_limit
# NOTE: Include a list of the members of this search.
child :searchers => :searchers do
attributes :id, :name, :gravatar_icon
end
# Each search has many concepts (there could be over 100 of them).
child :concepts do |search|
attributes :id, :title, :search_id, :created_at
# The person who suggested each concept.
child :suggester => :suggester do
attributes :id, :name, :gravatar_icon
end
# Each concept has many suggestions (approx. 4 each).
node :suggestions do |concept|
# Here I'm scoping suggestions to only ones which meet certain conditions.
partial "suggestions/show", object: concept.active_suggestions
end
# Add a boolean flag to tell if the concept is a favourite or not.
node :favourite_id do |concept|
# Another method call which occurs for each concept.
concept.favourite_id_for(current_user)
end
end
# Each search has subscriptions to certain services (approx. 4).
child :service_subscriptions do
# This contains a few attributes and 2 fairly innocuous method calls.
extends "service_subscriptions/show"
end
Parece que tengo que hacer algo al respecto, pero no estoy seguro de qué enfoque tomar. Aquí está una lista de posibles ideas que tengo:
ideas de mejora del rendimiento
Dumb-Abajo de la interfaz
Tal vez pueda llegar a la forma de presentar la información al usuario que no requieren el actual datos para estar presente. Aunque no veo por qué debería hacerlo, otras aplicaciones de una sola página, como Trello, tienen interfaces increíblemente complicadas.
Concepto Paginación
Si pagino conceptos, se reducirá la cantidad de datos que se extraen de la base de datos cada vez. Sin embargo, el producto tendría una interfaz de usuario inferior.
Almacenamiento en caché
Por el momento, actualizar la página simplemente extrae toda la búsqueda de la base de datos de nuevo. Tal vez pueda almacenar en caché partes de la aplicación para reducir los hits de DB. Sin embargo, esto parece desordenado porque no muchos de los datos con los que trato son estáticos.
múltiples peticiones
Técnicamente es mala para servir a la página sin incorporar el JSON en la página, pero tal vez el usuario se sentirá como si las cosas están sucediendo más rápido si me carga la página despoblado y luego recuperar los datos.
Índices
Debo asegurarme de tener índices en todas mis claves foráneas. También debería tratar de pensar en lugares en los que ayudaría tener índices (como los favoritos?) Y agregarlos.
Mover llamadas a métodos en DB
Quizás pueda almacenar en la base de datos algunos de los resultados de la iteración que hago en mi capa de vista y simplemente extraerlos en lugar de calcularlos.O podría sincronizar cosas en escritura en lugar de en lectura.
Pregunta
¿Alguien tiene alguna sugerencia en cuanto a lo que debería gastar mi tiempo en?
Aunque estoy de acuerdo en que la optimización de la entrega de activos es un paso importante para aumentar el rendimiento, no creo que sea el problema principal que tengo aquí. Si bien hay una luz de JS en la aplicación, está comprimida, minimizada y llega a ~ 100kb. También se debe almacenar en el caché en el lado del cliente, por lo que el costo de la carga se reduce al mínimo para los visitantes que repiten. –