joelday / Badonkatrunc

jQuery plugin for dynamic text layout and truncation
http://badonkatrunc.com
Other
32 stars 10 forks source link

Extremely CPU intensive #2

Open ChrisCinelli opened 11 years ago

ChrisCinelli commented 11 years ago

I have a page with 30 boxs (Pinterest style) of multiline text. Using .badonkatrunc({fitDirection: 'vertical'}) create a noticeable lag. CPU spikes and everything in the browser tab is frozen. On some machine it takes 8 seconds. On chrome for android on a quad-core CPU takes even longer.

I think you can optimize a lot the algorithm that you use to find where to truncate. A binary search like mechanism will make it already n/log(n) faster but I feel like there is more room for optimization.

boxwhine commented 11 years ago

Thanks for your feedback, Chris. It's great to know that people are using badonkatrunc!

There is definitely a max number of badonkatrunc instances that can be init'd before the browser starts getting overworked. We had further optimization in mind when releasing the plugin, but haven't had many free dev resources since then (nor any in the foreseeable future)!

So, I can't promise any quick fixes, but if you don't want to wait for us, you're more than welcome to take a crack at it! :)

joelday commented 11 years ago

0.25 seconds per truncation seems a bit high. Make sure it isn't being invoked/refreshed more than necessary. Since it sounds like you're doing a masonry style layout, it occurs to me that there could certainly be a bug associated with truncating with a container that only has a max-height, if that is the case.

Assuming that the plugin is working properly (and as efficiently on its own as is reasonably achievable), I would focus on improving the user-perceivable symptoms by deferring truncation (or perhaps the rendering of the masonry box entirely) across multiple time slices using setTimeout or requestAnimationFrame. Some things are just hard work if the browser doesn't have a decent native feature, so cooperative multitasking is the only way to reduce the burden introduced that the user actually notices.

ChrisCinelli commented 11 years ago

I run some benchmarks on a page with 30 boxes of text. I think Badonkatrunc can be dramatically faster if you do a logarithmic search to find the text that should be visible instead that a linear one and you reduce the number of accesses to the DOM.

Badonkatrunc

Test at: http://jsfiddle.net/K4u7j/2/ It takes 8600ms(!!!) on my HTC Evo 4G. It takes around 1600ms on Firefox on my MAC.

Truncate

https://github.com/tbasse/jquery-truncate

Test at: http://jsfiddle.net/Ueyrg/1/ It takes around 3600ms on Firefox on my MAC :-(

truncText

https://gist.github.com/ChrisCinelli/5688048

Test at: http://jsfiddle.net/JfSQN/1/ Take 3ms on Firefox on my MAC :-) Not as fancy as Badonkatrunc but effective for boxes of the same size where you know how many characters can approximately contain.

joelday commented 11 years ago

DISCLAIMER: I am the original author, but I am not affiliated with or represent Plexipixel, Inc.

Badonkatrunc's algorithm isn't quite a binary search, but it isn't just linear either. (Testing overflow has limitations when it comes to vertical truncation.) That being said, I'm absolutely sure that it can be improved. The question is of what level of effort is required to make that improvement without introducing a regression or changing the performance characteristics of other modes, and is that effort is the most efficient path to responsive user experience.

Here's a demo that saves some iterations by using lower quality vertical truncation. If your boxes aren't very wide, it probably won't be an issue. It also demonstrates the value of performing this work over multiple iterations of the event loop rather than blocking the UI to truncate items that the user hasn't even scrolled down to see yet.

http://jsfiddle.net/joelday/9YXSj/

Here's a 1.0.1 build with a lower memory footprint that never got added to this repo: http://badonkatrunc.com/js/mylibs/jquery.badonkatrunc.js

By all means, use whatever library provides the best value proposition for you and your project. I'm sure that a pull request with an improved algorithm would be accepted.