Friday, October 18, 2013

Performance matters

If spending a few days on improving overall performance can save you 30% of your server costs, you should probably do it.

That means 



  • getting rid of your prototyping language for something more fit for production (drop ruby/php, get python or drop java/python, get cpp, or drop cpp get c).
  • reworking your datamodel to optimize transfers, seek times, etc. through caching and pre-computed data sets
  • getting rid of your prototyping datastore for something more fit for production (drop mysql, get postgresql, drop NoSQL as main data store if your model contains more than one different item, drop NoSQL as main data store if the only thing you need is an ultra fast K/V store)
  • getting rid of your prototyping infrastructure for something more fit for production (drop your standard ec2 and get something optimized for your needs, do some profiling, fix your bottlenecks, use physical boxes with loads of RAM and SSDs)


For any big company, it should be simple to make that choice, you may invest a few hundred thousand in research and save 60%+ on a huge budget (like facebook could and has begun doing).

For a startup, it's even more relevant, since that extends your runway significantly, and pushes back the scaling discussion an order of magnitude or two (in number of users) later.

Usual replies:



  • "a language fit for production will reduce productivity" : 

that's never been proven in any way. it's pure OO propaganda.

  • "ruby is ready for production" :

rails had an sql injection weakness (the kind of security hole a 1-month beginner would never leave open), and it's much slower than Java or Python

  • "Python is ready for production" :

it's still changing rapidly, has no stable version that could have been time-tested for security and performance, and we're still talking 4x slower than C at least

  • "MySQL is just fine" :

most of the listed features are buggy, slow and incomplete, and the declared feature set covers maybe 5% of the SQL standard, most of it being incompatible with said standard.

  • "NoSQL is scalable" :

noSQL is just scalable by anyone including those who have no clue at all about databases, and is made scalable by being inconsistent.

  • "the cloud>you" :

go ahead and try to get one million IO per second in that cloud and tell me how much it cost you, I'm willing to sell you a physical box that does that for less than half of your yearly costs

  • "your approach isn't scalable" :

don't you think pushing the limit from 1000 concurrent users to 100.000 concurrent users on the same box is already a good step towards scalability? don't you think it'll make the scale out that much easier (i.e. a thousand boxes instead of 100.000 ? )

  • "your approach is more expensive" :

less servers, less expensive servers, more performance per server, ... it HAS to be more expensive indeed.

  • "<professionals I know> say you're wrong" :

In a field where 99% of the people don't understand what they're doing ? picture me shocked.

  • "facebook is right, you are wrong" :

I'm not telling you blue isn't the best color, I'm telling you a 30mpg car will go three times as far as a 10mpg car on the same fuel.

It's logic and mathematics, it doesn't depend on points of view, feelings or past experiences.
The only thing one could discuss is the actual cost of the performance improvement, but even rewriting all of facebook in pure optimized ASM would cost less than 10% of facebooks yearly server costs.

jQuery live is dead

the new live

So here's how I reintroduced $.live to my jQuery.
Unfortunately, .on(action,selector,func) does not seem to understand anything but the most basic selectors, and that makes it much much worse than the old live, which could handle 

$('.module_container .core_data th.secondary').live('click',function(){});
This, as well as most complex selectors are now impossible to .live() it seems (or maybe my version of jQuery is full of bugs, it's called 1.10.1 or whatever).
(function($){
    $.fn.live = function (action,func) {
        $(document).on(action,this.selector,func);
        return this;
    };
}(jQuery));



live vs on

You should still try and learn .on, which lets you put the delegation on any element rather than the document itself.
If your element has 0 static parent elements apart from body/html (i.e. it is dynamically added to the body or html), live is the correct approach (and having javascript create 99% of your html is the correct approach to the modern web application).
Otherwise, you should be using .on in order to make event handling lighter - the lookup for the handler can become slow if you add a zillion handlers on the same element, which is what happens when you use .live for everything.




event delegation is slow

The reason live and on are slow, is because when an event is delegated using the jQuery method, an event handler is created on the document (or your selector) that will check whether or not the bubbled event target matches the selector.
So what's actually slow is the selector itself, and the very long list of if(match(ev.target,selector)){callback1234();} which is bad design, whether you use "on" or "live".




the solution

If you still hit performance bottlenecks related to handler lookup, you should consider dynamically adding .on handlers to children elements (delegated event delegation), or go all the way and dynamically adding handlers to the elements you create (no event delegation).
It mostly depends on the percentage of events that are actually triggered and the number of different events that bubble up to the same delegated element, but you can have your answer with just profiling.
Actually, $(document).on or live both get you your handlers in every case. $(anything else).on will fail if it's not handled post load, i.e. packaged in a function and called on purpose in .ready().



the best solution

Drop jQuery. It takes 96KB to do mostly nothing. Write your own event delegation and enjoy a freedom that far surpasses both what .on() and .live() ever did.

Learn dynamic event delegation delegation ;) (it's called eventception)

Reinventing the Wheel

Most of my very short career was spent reinventing the wheel (alright, I'm cheating, I've been doing that for longer).

And that kicks ass, because today I'm among the best wheel inventors and builders, and I never have to drive a car with octogonal wheels.

So while you spend your time fixing your car due to shock damage, I'm just driving, and driving, and driving.


In other words, don't be so afraid to check the wheel, figure out that it's broken, and fix it. On the long run (that is, as short as my career), it's worth it.

Wednesday, October 16, 2013

The Retina Bias

It seems most designers have successfully migrated to retina MBP.

Unfortunately it seems some of them have not yet realized that most people don't want to use that computer to surf the web, be it because it runs the crappiest OS of all times, because 2880*1800 is not a logical resolution choice or because it's just very expensive for no good reason.

Here's one example (most websites are like that) of a startup website that suffers from "The Retina Bias"

In Retina resolution:

It's very empty, but then so are most websites on any big screen (from full HD on).




In full HD (the standard for us real tech guys).
You can still see the phone, but the reflection is dead and so is the rest of the page content.






In 1366*768 (the poor man's laptop, pretty much standard as of today). You can guess there's a phone but you have zero idea of the application layout or the rest of the page content.





There are other standard resolutions in between, and all of them will result in a more or less useless combination of waste of space and lots of scrolling. Scrolling is bad. scrolling is ugly and annoying, scrolling hides what you're supposed to be showing to your visitors. IF you absolutely have to scroll, scroll one div, not the whole page. Be sure though that everytime you make someone scroll, a kitten dies.



What you should be doing instead



Basically what I do: avoid scrolling at all costs, try and use more of the page, think about standard resolutions and take the time to make a beautiful design (not like me).

In retina resolution: retina resolution is a bad idea, 4K will be another discussion, until then you can upscale everything with 10 lines of javascript if you want to take them into account (change body font-size) and it will simply look like full HD with more pixels.




In full HD



In 1366*768







In half full HD (windows+left)
















On S3 > android > chrome


















Sure, this website is ugly, but I'm not the guy who's supposed to have worked on his drawing skills, that's the designer's job.
Like it should be the designer's job to make webpage content usable for people without scrolls and without trouble.

In every example I used chrome without any toolbar, i.e. the thinnest chrome you can ever have and the best screen use possible aside from full-screen which noone uses.

The negative effects of bad webpage sizing are even more visible when you have toolbars, favorite bars, not-chrome or an Apple OS that thinks you shouldn't ever maximize your browser window unless you want to do that manually.

So please all of you MBP-retina-biased designers, design stuff that the world can use, not just people who bought an MBP retina and an iPhone7.

Fight vertical scrolling, kill page scrolling and please don't kill our bandwidth with retina size graphics.

If you want to think Retina, use svg, not huge static files.