0

I have an XML-feed with references to rather large external image files (200kb). They are causing really long load times which in turn cause the page to crash. In one div I load 20 images like this. Each div is loaded in a separate partial. These partials (product_item) take between 40-400 ms to load (!), mostly because of the large images.

The external images needs to be external (so any AWS solution) will not work.

The "slow-portion" is below the fold and could easily be hidden 'until needed'.

<div id="slow-portion">
<% @product.each do |product| %>
<%= render 'product_item' %>
<% end %>
</div>

I just implemented lazy load of the images (http://www.appelsiini.net/projects/lazyload) which I thought would solve this problem but it seems like the page will still wait until everything is loaded (including the large image files) before it shows the page. The load times for each product_item is still the same.

This is getting quite frustrating so I wonder, in quite general terms, how I should address this problem.

  1. Is it possible to timeout a partial in Rails. I.e. if "slow-portion" has not been loaded in 3 seconds, it should not show?
  2. Should lazy load of images solve this type of problem? I.e. is this where I should trouble shoot the problem?
  3. Can I solve this with ajax-loading of the slow-portion of the page? Basically, that portion will show a "Waiting symbol" until the "slow-portion" has been fully loaded?
  4. Is there any other ways of not causing a crash (503 error) and timeouts due to view-load times being too large?

Any solution that will work is fine for me!

Christoffer
  • 2,271
  • 3
  • 26
  • 57
  • What does your `'product_item'` template look like? – arjabbar Jan 14 '16 at 11:25
  • It has a header title, a image_tag and a link. – Christoffer Jan 14 '16 at 11:33
  • So basically, the browser fetching the images is what takes 400ms? Not the actual rendering of the `` tags by the server right? If you were to use `curl` or `wget` to fetch this page then it would load relatively fast right? – arjabbar Jan 14 '16 at 11:37
  • According to the 'better-errors' gem it is the partial. I cannot see any real delays in the db-requests so my only conclusion is that the fetching of images is what takes time. My questions more general, however, since I have similar problems once in a while (one portion of a website causes a delay which crashes it all). Basically, I would like to have a rescue on timeouts that says "if you have not been able to load this partial in 2 secs rescue and show a 'partial not loaded'". Is that possible? – Christoffer Jan 15 '16 at 05:45

1 Answers1

0

I never seen a request for an image prevent a page from loading, but if the app gets hung up trying to render those partials, and you really can't find a way to try and speed things up, then you could try loading each of those partials using jQuery. It's possible to just setup a route that serves out those partials without any layout html around it.

If there are a ton of products, I wouldn't fetch all of them at the same time. So you will have to implement something that throttles all those ajax calls as well.

Then you could add a css class to the parent div (something like .loading) of where the partial is about to be rendered and add styling to indicate that something is loading there. In the function that gets called once your ajax request finishes for that partial, you can remove that .loading class from the element.

But your issue does seem a little odd to me. Your partials don't have a lot to them, so I would expect them to be rendered within milliseconds. To the server, those images are just <img/> tags with urls in them. It shouldn't make any attempt to render an image at all. That's the browser's job. Then, when the browser fetches the page, it will see those <img/> tag source urls and it will fetch those images asynchronously while the rest of the page loads.

Normally if those images are just insanely big, and the browser isn't able to get them from the url it was given, then you'd see that little broken image icon instead.

Community
  • 1
  • 1
arjabbar
  • 6,044
  • 4
  • 30
  • 46