Ruby on Rails - print output to buffer

Go To StackoverFlow.com

0

I have a large method that returns one large HTML string. This is very ineffective and takes a long time for the browser to load the HTML all at one time. My question is: Does Ruby on Rails have a way to print parts of the HTML to the buffer so it doesn't do it all at once?

Here is what I mean:

module TestHelper
    def my_method
        output = ""
        output += "<div>"
        output += "<span>Test</span>"
        output += "</div>"
        return output
    end
end

But I'm wondering if I can do it like this:

module TestHelper
    def my_method
        print_to_page "<div>"
        print_to_page "<span>Test</span>"
        print_to_page "</div>"
    end
end

My question is not on how to do it a different way or the "right" way, there is a reason why I'm doing it this way. I've searched the web and read about with_output_buffer but I don't know how that works. Any suggestions?

2012-04-05 17:59
by Artem Kalinchuk
There's no good reason I can think of why incrementally outputting a string would perform significantly better than doing so all at once. That said, you should be using <<, not +=, to build the string. <code>+=</code> creates a new object every time it's called while <code><<</code> does not. That change will improve your performance (perhaps dramatically depending on your actual code) - Andrew Marshall 2012-04-05 18:07
It seems to be a big difference because I have a PHP version which outputs a string as it goes (the function calls itself many times) and also a Ruby version which returns a string at the end. I also do it a little differently...I add strings to an array and then join the array. But I don't think that's the problem because the slow part is on the client/browser side - Artem Kalinchuk 2012-04-05 18:13
I see, you care about "partial page" (for lack of a better term) load time where at least some of the page has been displayed, not final page load time. You might want to consider trying to optimize the slow method first, IMO seeing some of the content fast isn't much better for the user if they don't see all of it for the same duration—but again that's just my opinion and I don't know your wider use case - Andrew Marshall 2012-04-05 18:18
Well actually it's much slower than the PHP version. PHP displays all of the content in 5 seconds while the Ruby version takes about 60 seconds to display it - Artem Kalinchuk 2012-04-05 18:20
Then make your method faster! Output buffering won't increase total load time. I already gave you one suggestion, profile the page and figure out why it's loading so slowly - Andrew Marshall 2012-04-05 18:38
It's not a problem with the method being slow. I did a test. Loading <span></span> takes less than a second. Loading 100,000 of those span tags (with a loop) takes 5 seconds to loop by 20 seconds to display on the page. The page itself freezes and Chrome sometimes says "Do you want to close or wait?" - Artem Kalinchuk 2012-04-05 22:13
Making output a string and using << to append worked. I guess appending to an array and then joining it into one string is what caused the problem loading the HTML - Artem Kalinchuk 2012-04-06 14:30


0

The later versions of rails support streaming, which effectively gives you what you are asking for.

But! Be careful that what you are asking for is what you need. Use firebug's net tab to see how long the page is taking to load, and where the time is being spent. If the browser spends and especially long time waiting to get any page data, then maybe streaming will help you. But also, keep in mind that to make use of streaming your code also has to be able to produce the HTML page in chunks. This can be harder than you think - things like

<%= table_tag { render_huge_table } %>

cannot be used.

2012-04-05 19:46
by Michael Slade
Ads