Airbnb Releases Infinity.js: A Javascript Library for Smoother Scrolling
airbnb.github.com
airbnb.github.com
for(var index = 0, length = listItems.length; index < length; index++) { listItems[index].remove(); }
and I think to myself -
_(listItems).invoke('remove')
In the novel native martians do exist and they are very smart. "Grok" it's the martian word for "water" and "to drink". Water is a scarce resource there, and, like here, very important for life.
Drinking is putting water inside you but also occurs that this water becomes part of you.
Then, in that society, drinking is used as the metaphor for understand something in a level that becomes part of you.
I'm a native spanish speaker and I don't know if that word sounds bad in english, but for me the metaphor is so powerful and beautiful that I like it very much.
"To really understand something REALLY well".
[1] http://wikibin.org/articles/baader-meinhof-phenomenon.html
As a Lisp hacker and current learner of Haskell, this makes my spleen rupture.
It's just functional programming 101, seriously.
That's all it is.
In simple terms, it goes through the array, and calls the named function on every element. You could read it as - "For this array, invoke the 'remove' function on every element."
My point basically was that
_(listItems).invoke('remove')
is actually short for
* [content of http://underscorejs.org/underscore-min.js] _(listItems).invoke('remove')*
and even if you removed all non-called parts from underscore, that's still a lot more complex than
for(var index = 0, length = listItems.length; index < length; index++) { listItems[index].remove(); }
it's just hidden, out of sight and out of mind.
They were attempting to use a meme acronym sarcastically -- an example of content-free commenting that works well for karma elsewhere but hopefully doesn't gain a foothold here.
On topic, I agree with your amplification of your point.
(They tend to be downvoted to oblivion, 'round these parts.)
I guess while syntactic sugar is usually considered a functionality of the language itself, it surely is used in the way I meant it, too... random search result:
http://www.developerdrive.com/2012/05/an-introduction-to-und...
"In this part of the tutorial we’re going to take a look at some of the syntactic sugar that Underscore gives us to work with array-like collection."
And of course, even if I had been utterly wrong for using the term, my point would stand unmoved, but you know that :)
Underscore as a production library is 4kb. The functions are terse, and its extremely easy to understand what they're doing - nothing is generally hidden (this example is pretty easy to understand, yet one of the most "complex" uses of underscore I've seen).
At the end of the day on a production javascript app of multiple thousand lines of JS, it likely actually saves me bytes over the wire from not having to write "for(var x = 0...." every time I want to iterate through something or filter an array or find if an array includes something etc (There's around 70 bytes removed in this single example).
But if you do it a lot in your code, that just means you can easily copy and paste it from a nearby place? At least that's what I often end up doing.
http://jsperf.com/native-for-loop-vs-array-foreach-and-array...
map (.remove!),list-itemsYou could mitigate this but it would be useful to see what benefits people think infinite scrolling introduces and (if there are any) see if there is a solution that gives the same benefits with fewer costs.
Maybe some hybrid 'paged' infinite scrolling where you can keep going but clear pagebreaks are displayed which are mirrored in the browser history.
Unfortunately, I had to custom roll this solution. I started on a plugin but making it universally usable for a number of use-cases is a bit time consuming.
I just check it out once every 2 or 3 days for a quick laugh and eventually I stumble upon some images I've already seen, which is when I close the site.
Sites like Facebook do this, and I have no idea why.
Want to "Create a page". Well there's a link at the bottom. But if you scroll to the bottom of the page, it's going to load more content and push the link down.
I just tried it, and the page reloaded 15 times before I gave up... never did get to the link.
This is clearly unintuitive, but at least it exists.
I have noscript installed, but all scripts on that page were allowed.
Off:
A script on this page may be busy, or it may have stopped responding. You can stop the script now, or you can continue to see if the script will complete.
Script: https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js:4
On: A script on this page may be busy, or it may have stopped responding. You can stop the script now, or you can continue to see if the script will complete.
Script: http://airbnb.github.com/infinity/infinity.js:154
Firefox 14.0.1 without NoScript, Linux 3.4.0.Also, looking at their code, the first thing I laid eyes on was this statement:
var infinity = window.infinity = {};
Which, in this context, would be the exact same as var infinity = {};Don't have a footer. Example of this error: LinkedIn. Try to get to their ToS or Help Center from the logged in home page. Good luck.
Those memory limitations are simply nonexistent for the web for almost all but the smallest number of cases (ie, infinite lists).
But lets pretend that this infinite scrolling is even a real problem (honestly it's probably not the best UI for large infinite lists of things on the web).
The current implementation clearly needs some work. It's trying to over-optimize for memory to the point of choking the scrolling.
This, however, can be fixed fairly trivially.
Allow the user to scroll anywhere (even past loaded content). If you can't eagerload elements to compensate for it, then lazyload after the user gets to that point. This gives users the illusion that the scrolling is truly smooth and responsive. The important thing is never allow scrolling to stop unless it's truly at a dead end and there is absolutely no more elements to load.
The above is how UITableView functions. Infinity.js is UITableView for loading elements, but does not function anything like UITableView from a user interaction standpoint.
The demo is not any smoother on my 27" Apple display driven by a late 2010 model MacBook air. However, even low res hardware accelerated video renders choppy at large window sizes (although perf gets better when VLC or QuickTime is true fullscreen; presumably the compositor is off)
Faster JavaScript is unlikely to be effective at enhancing buffer flip times, which (for me) dominate repaint times.
We experimented with using display:none instead of removing the elements; it increased scrolling performance just as much as actual element removal, but the relayouts when new content was appended got to be prohibitively expensive once a certain amount of content was loaded (literally pausing the browser for a noticeable amount of time), because the browser still had to traverse a giant tree of HTML entities during the relayout. So even if the buffer flip times are still too slow for you to get completely smooth scrolling in complex demos like this -- and that makes sense, given your large-screen setup -- you'll hopefully still benefit some from the faster, non-browser-freezing relayouts.
When actually is defined as for some on certain machines, judging from the number of directly contradictory observations in this thread.
The word "actually" ought to be reserved for concrete facts with zero counter examples.
The word "hopefully" in your closing sentence seems more apt.
That said, very much appreciate the sharing of the hypothesis and implementation. It's great to see ideas from other areas (video game terrain feature pop in) leveraged to improve end users' browsing experience.
[1] http://newcoursys.herokuapp.com/courses/2012sp-cmpt-165-c1/a... [2] http://newcoursys.herokuapp.com/#marking-interface
When I move the scrollbar on the "on" version, it flashes white and constantly drops images in and out until I let go or stop in one place. Then it whites out again next time I scroll. Quite distracting actually, like viewing the bottom part of a long page while it's still loading images.
The "off" version scrolls as one would expect, no flashes, no missing or reflowing content. Just like you'd expect.
PgUp/PgDown and arrow keys don't seem any different between the two.
"UITableView for the web" … what does that mean? Why should a web dev know or care?
Make "demo" not "on" and "off" prominent. That's what I'm scanning the page for. Especially if you say "Infinity on and off" and it's the first time you use the word Infinity at all. Use Infinity or the symbol and then stick to it. At least introduce the name first.
Or, since I think Google uses javascript in its crawlers, I wonder how it handles it. Presumably it would just keep scrolling until the content ran out or it gave up. But does it ever come back later? I know with pagination it could pick up on the links it left off on, but couldn't really do that here, right?
edit: I guess this is really a question of infinite scrolling more than this particular implementation. Kudos to Dropbox for releasing a well-done version of the technique.
jQuery.fn.infinity = function (options) {...};
$(el).infinity(options);
And so on.In order to calculate the size of each ListItem you add it to the dom briefly when its appended to the ListView. This seems to be a fast operation since you do it hundreds of times yet the page is loading quickly. Is there a trick there that is avoiding having to calculate a ton of layout, or is that just not a big concern compared to other work the browser is doing?
Thanks!
"...but because there are fewer elements in the DOM tree, relayouts are cheaper as well"
If I understand, this also applies? When I add the 400th (or whatever) ListItem it does trigger a layout when its added to the dom (to calculate its dimensions) but its much faster due to only having the currently viewable ListItems contained in the ListView?
Thanks again!
.height() .width() .offset() .remove() .append() .prepend() .prependTo() .find() .parent() .on() .off() .scrollTop() .outerHeight() .length
It seems to me like all of these would be covered by zepto. Or qwery. Or you could make your own adapter with Prototype. Or Mootools. Or Ext. Or YUI. Heck, you could probably whip up your own little library based on sizzle, or even just querySelectorAll. Then just fork infinity to use your lib, and you're good to go.
I hope you're not confused any more!
[I'm not affiliated with airbnb, just thought I'd help you out]
There.