How do I optimize repeated queries for pages in Rails? - ruby-on-rails

On the side of each page on my site I list the other Pages in that Section. I also mark if the User visited or completed each page. Every time a page loads, Rails has to check the database to see if the User visited or completed each page in the Section, which makes displaying a page take longer. Is there a way I can speed this up?
Example: user visits page 2 and the sidebar loads. He then visits page 3 and the sidebar loads again, but likely with a different mark next to Page 2.
Page 2
------
- ✓ page 1 | Main Content
- > page 2 | The quick brown fox...
- page 3 |
...

There are a few areas you could improve performance, both in database lookup and in rendering.
For rendering, you should look at fragment cacheing the sidebar for visited links, although your scenario is a bit out of the ordinary in terms of keeping track of visited links in your app.
For each link in the side bar you could save a fragment that represents visited and unvisited, then the outer container could represent any permutation of visited and unvisited since it doesn't really matter which user it is when you display it. You will end up with a lot of various side bars for each of those scenarios.
For the database you could look at something like identity_cache and hold the list of users page visits in the cache to avoid unneeded lookups, invalidating when they hit a new page.
This is as good as I can get for such a broad question in relation to Rails and speed ups in general, which seems to be what the question is asking. There are numerous other platforms specific speedups that you can get by playing with different caching back-ends and servers as well.

I assume you are keeping track of the pages they have visited and/or completed in a database table because this data needs to remain stateful.
If so, first off, make sure your table is properly indexed on the columns it needs to look up.
Then, cache the results in a sessions variable, so that you can retrieve it from there and only go to the database when necessary (e.g. something changes the state or a certain period of time lapses)

Related

Best Practice for storing Query Results for page refreshes

I have a search control that breaks results into multiple pages. Currently it operates by executing the query then storing the results in a session variable. When a second, third, x page of results is requested it pulls the data from session to display the required elements.
However once the page is navigated away from the session data remains unnecessarily. It seems like I'd want to remove it once I no longer need it. On the other hand, if the user navigates back to the search results, keeping it in session data means I don't need to re-run the query... though it seems possibly dangerous.
I'm wondering if there's a standard practice that's worth following in this scenario that someone could link me to or suggest to improve the design that's in place.
Thanks.

Rails - Show number of users currently visiting a page

I got a page in my App where users can chat. Now I want to display the number of Users that are currently viewing the chatpage.
Is there a way to do that?
I thought of an action, that gets called everytime the site gets loaded from a user and increases the value of a variable and decreases it when the user leaves.
Things to take into consideration:
reloads
multiple browserwindows
You can use the impressionist gem, it gives you a lot of nice stats including what you're looking for. Good luck!

Is there a way to do lazy loading in Rails 3.2?

I've built, maintain and continually improve a website for an insanely complex fantasy football league I'm in where GMs have $130 of salary cap a year, players all have a starting salary value and may be signed to longterm deals using that initial salary amount as a starting point for subsequent years.
There's a lot more to it, but that's enough for what I need info on. Each GM has a team page that shows all the players he has on his team/signed to longterm deals along with some other roster breakdowns, historical payout information, draft rosters (basically a drag-and-drop sortable "shopping list" of players to keep an eye on), pending/completed/rejected trade requests, and private messages along with a lot of other information:
As you might imagine, this is an INSANE amount of information to load for each team. Upgrading to Ruby 2.1.2 alleviated a LOT of issues (page load times dropped from ~7 seconds to ~3 seconds on average), but there's still more that could be done.
Is there any way to make my 93-line teams#show action load lazily? So, like, for instance, the Roster and all associated variables would load when going to a team page since that's the first/default tab. But then the Payouts, Draft Rosters, Trades and Messages variables wouldn't fire their queries to set the variables until each of their tabs was activated? I've been trying to find anything I can about Rails lazy loading but I've had no luck at all finding anything even remotely close to what I want to do.
You can create one controller action per tab.
So you have something like this. The main page would be the users#show action. That would render the main layout and the tabpanel (with the roster tab).
Then create one action per tab. So you would have:users#payouts, users#draft_rosters, users#trades users#mailbox
Those actions can be loaded via ajax only when the tab is clicked for the first time: http://jqueryui.com/tabs/#ajax
Each tab would have it's own html.erb file. This file is the content of the page.
This way each tab has it's own instance variables that are only loaded when the tab is clicked.

How to cache an entire page save for one element

I'm running an e-commerce website and many pages are dynamic but for a widget displaying the number of items in the visitor's cart. I want to cache the page yet retain this dynamism. I'm considering caching the fragments before and after this widget but I was wondering if there was a simpler way to get this done.
Edit: Perhaps something which decided to give the cached page or not depending on whether the cart was empty or not would be a good start.
Kindest of Regards,
-- Jack
One way to do it is have the cart items displayed using JavaScript that's inserted after the page is loaded. You can see this on places like StackOverflow where your login status gets injected into the page if it wasn't already cached. jQuery can make this pretty straightforward.
You can set the number of items in a cookie accessible to JavaScript, not in the session hash as that's not exposed to the client, and handle that in the document.onload section.

Loading page while rails app starts?

I have a rails application on a shared server that also has a decently sized database, which is still growing, behind it. The application takes a long time to start/load the homepage, about 20-30 seconds for me, although some people report waiting up to several minutes.
Is there a way to flash a notice that informs people that the database may take several minutes to load while they are waiting?
It's hard to say based on your question, since we don't know exactly what your home page is showing or how it's displaying it, but assuming you are referring to an AJAX (based on the tag) call that is retrieving something from the database to be displayed on your homepage, there are a few things you can try:
Paginate the items. Is whatever you're loading a long list of items? If so, only retrieve a few at once, and let the user decide if they want to see more.
Load the rest of the page (header, footer, navigation bar, etc), and then place a loading gif spinner in the area where the content is to be loaded. If you use a javascript library like jQuery this is pretty trivial, and there are a ton of tutorials out there for it. Here is a good site for free loading indicators: http://ajaxload.info/. What you'll want to do is make the AJAX call and use your javascript library to set the loading image. Then, in the success callback for your ajax call, hide the spinner and show the content.
Load one item at a time. Make a separate ajax call for each item you're going to load, so that the user sees them coming in. This will probably end up taking longer overall (you're hitting the database more often), but the visual may be a nice psychological hack.
Look at how your database queries are set up. Are you getting everything you need in one find? That's the best way to do it, as every time you have to make another trip to the database you're increasing the wait time.
Other than that the best thing you can do is get better hardware if possible, maybe look into a VPS like linode.com.

Resources