HNHacker News
TopNewBestAskShowJobs

wingspan

266 karma · joined September 12, 2011

Software Engineer at Netflix, building components for TV.

https://ianobermiller.com

submissionscomments
wingspan··on Flux Application Architecture
Don't cursors still suffer from the problem of intermediate components needing to pass on state they don't use? For example, a list of articles might have an author for each article. Then you have the following components: App > ArticleList > ArticleItem. So App will have to have a list of authors and a list of articles, and pass that down to ArticleList, which, for each Article, will instantiate an ArticleItem and also find the correct author to pass to it. Instead, what if ArticleItem just got an Article, and then asked the author store to give it the Author? ArticleList shouldn't really care about the authors.

The example is a bit contrived, but hopefully you see the problem? Especially consider if there are a couple more layers between App and whatever leaf component is rendering something,

wingspan··on Flux Application Architecture
Yes, it is the dispatcher. ArticleActions.update basically calls Dispatcher.dispatchAction(ARTICLE_UPDATE, {article: article})
wingspan··on Flux Application Architecture
Good question. I haven't used backbone at all, and only know what I've read about it. Flux is a complete replacement for backbone as far as I can tell.

As you say, the models live in stores, so building on my other comment, you would have an ArticleStore that is responsible for providing access to and caching all of the Article objects. As a rule, if you want to mutate data, you do so by calling an action (ArticleActions.update, for example). See my other comment for how the update flow works: https://news.ycombinator.com/item?id=7721381

If you want to fetch data, you go to the store (ArticleStore.getByID, or ArticleStore.query). The ArticleStore will then call into the ArticleDAO (data access abstraction) to fetch data asynchronously, and when it returns the ArticleStore incorporates the data into its cache and "informs", which is basically a pub-sub push (the views/components subscribe to the stores they want to get data from).

wingspan··on Flux Application Architecture
We had talked about using promises at a lower level, but for actions it is very desired for them to be fire and forget. The view (component) fires the action in response to some user interaction (e.g. clicking a button). The action is dispatched, and the stores listen for that action, update themselves, and then "inform", which notifies the component that its data has changed. In the case of data mutations, our action modules end up having a fair amount of logic in them:

1) User clicks a button to favorite an object, lets say an Article 2) View (component) listens for the click handler and calls ArticleActions.favorite(articleID) 3) ArticleActions.favorite fires a preliminary ARTICLE_UPDATE action, for any stores that want to update optimistically 4) ArticleActions.favorite calls into the ArticleDAO (the data access abstraction) via ArticleDAO.update, a function that takes an ID, some updates, and two callbacks, success and error. 5) In the success callback, ArticleActions.favorites fires off ARTICLE_UPDATE_COMPLETED, along with the updated article object 6) In the error callback, ArticleAction.favorites fires off ARTICLE_UPDATE_FAILED, along with the error 7) Stores listen for the COMPLETED and FAILED actions to know when to update their data, including stores that show error notices

As you can see,the action layer itself should not really be accepting callbacks/returning promises. It might be easier, however, if the DAO layer returned promises, and this is something we have talked about migrating to.

wingspan··on Flux Application Architecture
From first-hand experience, I can say that React+Flux has scaled well to 8+ developers over 800+ JS files and ~60k lines of code in a large single page app here at Facebook. I'm happy to answer any questions! Some things that we've struggled with:

1. All data should be kept in stores. You may have some local component state, but it shouldn't be anything you want to persist if the component is unmounted. We have tried using state several times, and always go back to keeping it in singleton stores. It also works better with the action-dispatcher pattern.

2. Now all your data is in stores, but how do you get it into the specific component that needs it? We started with large top level components which pull all the data needed for their children, and pass it down through props. This leads to a lot of cruft and irrelevant code in the intermediate components. What we settled on, for the most part, is components declaring and fetching the data they need themselves, except for some small, more generic components. Since most of our data is fetched asynchronously and cached, we've created mixins that make it easy to declare which data your component needs, and hook the fetching and listening for updates into the lifecycle methods (componentWillMount, etc).

3. Actions don't have callbacks, as they are by design fire-and-forget. So if you need to be notified when some item has finished being created, for example, you need to listen for the follow up action that the CREATE action fires (yeah, actions firing actions, a bit ugly). Even then, how do you know that CREATE_COMPLETED action correlates to the CREATE that you fired, and not another? Well, actions also come with a payload, so what we ended up doing was passing a context object into the payload and plumbing it all the way down into the CREATE_COMPLETED and CREATE_FAILED actions. Being really strict about actions is a major reason why Flux has scaled well for us.

wingspan··on What happens when a host cancels with Airbnb?
Last time we used Airbnb was for an apartment in Copenhagen. We found out when we arrived that instead of the "Whole apartment" as it was listed, we would be in one room and sharing the rest of the place with the owner and her daughter. Airbnb didn't do anything to help us; we just stuck with it and vowed to be more careful next time.
wingspan··on Why open-office layouts are bad for employees, bosses, and productivity
Interesting! I worked in that same office when FUSE Labs was there in the post-Ozzie time (2012), and like some of the other commenters pointed out, I never saw a single one of my coworkers doing actual work outside of their offices. It was awesome for team meetings, though.
wingspan··on How to make fake data look meaningful
I was hoping (by the title) that this was something about generating real-looking test data for your app, something very useful for UI devs before the API or backend is in place.
wingspan··on Optimizing AngularJS
No reason in particular, just put it together quickly. Yours is a good option since it keeps the DOM count low instead of letting it grow as you mouse around :)
wingspan··on Optimizing AngularJS
For comparison, I wondered how React would fare. Turns out it can be pretty fast. I did have to use a similar trick of breaking up the line only when the mouse is over it, but the rest is just React's architecture. See the demo here: http://jsfiddle.net/ianobermiller/tZhSp/1/

Edit: updated link, forgot to save

Edit: for more info, React takes care of reusing DOM elements, and also uses event delegation by default.

Edit: for comparision, here is a version without the optimization: http://jsfiddle.net/ianobermiller/QT9Tx/1/

wingspan··on Web Giants Threaten End to Cookie Tracking
I think swapping out Microsoft for Yahoo is probably not a bad tactic for garnering more upvotes on HN.
wingspan··on Bittorrent Protocol Specification v1.0
Or check out the specification at bittorrent.org: http://webcache.googleusercontent.com/search?q=cache:Dm_oT-Y... (site was down when posted...)
wingspan··on How We Detect Adblock
This brings up another case for detecting AdBlock: if you think your users are receptive to whitelisting non-annoying ads, you could detect the plugin and let them know that you strive to incorporate ads in a non-intrusive way and kindly ask them to disable AdBlock.

Edit: sounds like this is what reddit does. Props to them!

wingspan··on How We Detect Adblock
To all the bashers: detecting AdBlock or other plugins like Disconnect is sometimes necessary for ad-free sites as well. Some sites malfunction when the user has such an extension installed, and it is a great user experience when the developer is thoughtful enough to put up a banner at the top of the page saying "This site may not work correctly if you are using AdBlock". (sorry for the "some sites"; I was browsing recently and saw such a banner, but cannot recall where). Of course the better option is to test your site under AdBlock and make sure it works regardless, but sometimes the detection is needed.
wingspan··on How We Detect Adblock
Can anyone else confirm this? Personally, I've always used AdBlock, but never used a Javascript blocker because it is substantially more effort and I am lazy. I do use Disconnect, though, to block that certain flavor of JS.
wingspan··on Callbacks are Pretty Okay
I never thought of using nested functions like that. It does make the code much more readable, and using 100% JS is a big win. Not as pretty as yield/await, but much more debuggable and compatible.
wingspan··on HTML.js – Befriend the DOM
I don't think this is true:

"jQuery Core has more lines of fixes and patches for WebKit than any other browser." [1]

[1] http://blog.methvin.com/2013/02/tragedy-of-webkit-commons.ht...

wingspan··on Scientific Breakthrough Lets SnappyCam App Take 20 Full-Res Photos Per Second
It also doesn't work for me in Chrome on Win8. It does work in IE10, though.
wingspan··on Microsoft reveals $900M write-down on Surface RT tablet
Is it just me, or was that article constantly confusing million and billion?
wingspan··on A surprising JavaScript memory leak found at Meteor
The C# compiler does the same thing:

http://blogs.msdn.com/b/ericlippert/archive/2007/06/06/fyi-c...

This is an old article, but I believe it still applies to the latest iteration of the language.

wingspan··on Show HN: Remove backgrounds from images online
Really nice work! I tried a fairly complicated image and it worked quite well.

Couple bugs: 1) Chrome on Win8 consistently gives me the Network Error dialog when trying to upload 2) Was able to get it working fine on IE10, but sometimes the background still shows up in the preview, even though it is erased correctly in the download. http://i.imgur.com/fSB4n4r.jpg

wingspan··on Show HN: Find the cheapest Amazon for your books
I typically use http://bigwords.com for multi-book price comparison; it gives you the cheapest total price with shipping, and allows you to tweak parameters (new/used, internation, etc).
wingspan··on BitTorrent’s Secure Dropbox Alternative Goes Public
> I also enjoy fantastic two way integration with photo management tools, with tagging syncing back.

Which photo management tools do you use? I currently have around 45k photos (~200GB) and Picasa is sometimes just too slow. I am planning to get a DSLR soon, so total size is going to be expanding rapidly. What kind of tools would you suggest? I am on Windows mainly, so Mac-only is not an option. Thanks!

wingspan··on The Power of ‘And’ (Azure IaaS Now Cheaper, Generally Available)
This is the most interesting piece:

That’s why today we are also announcing a commitment to match Amazon Web Services prices for commodity services such as compute, storage and bandwidth. This starts with reducing our GA prices on Virtual Machines and Cloud Services by 21-33%. Regardless of how you choose to buy Windows Azure, you’ll get the benefit of this price reduction. As our operations GM Steven Martin said, “If you had concerns that Windows Azure was more expensive, we’re putting those concerns to rest today.”

wingspan··on Exposed Webcam Viewer
Looks like Windows 98 fed directly into a cam: http://cryptogasm.com/webcams/webcam.php?id=27279
wingspan··on Users don't like social login
I am an avid LastPass user and I already have my CC details in LastPass. But, until now I didn't realize you can add them to the Form Fill details! Thank you tempestn!
wingspan··on Users don't like social login
Totally agree! Because I am not the biggest fan of PayPal, one of the best things I did to speed up ecommerce for myself was to memorize my CC details.
wingspan··on Is getting rich worth it?
Hmm, I just clicked "close" in the dialog and was able to read all the replies.
wingspan··on Show HN: LeanSentry - Better Monitoring for Windows Server Apps
Looks cool, certainly seems to provide value above and beyond typical monitoring tools.

It would be great if there was a simple calculator on the pricing page, to give a really quick and rough estimate for how much we'd be paying, especially considering the volume discounts and prepay. E.g. 30 large Azure instances for one year. By my calculations that would work out to ~$2300/mo when prepaying for a year (ouch!).

wingspan··on Why fonts look awful in Chrome, and how to fix it
I thought this was going to fix the big difference I see between Chrome and IE10 on Win8 desktop:

http://i.imgur.com/e2Dwi.png

Guess not :( Any ideas?

← PreviousPage 2 of 4Next →