As someone who's specialized in AngularJS optimization [0], this doesn't surprise me in the least. Developers leave plenty of performance optimizations on the table, some worse than this one. The truth of the matter is that in the general case, it doesn't matter. We engineers like to go on and on about this or that perf efficiency but most of the time the code runs fast enough (and the majority of the time when it doesn't, ads are to blame over framework tweaks).
Heck, I shouldn't even be saying this as it'll cut into my very lucrative field but unless you've got a confirmed performance problem, you shouldn't think about it at all. Really. Leave all of the fancy perf tweaks behind. Sure, you might get ridiculed on Medium but that's par for the course here on the internet. I'm afraid articles like these will cause lots of cargo-cult 'optimization' that just makes the job harder for future devs.
Make it work, make it work well, THEN make it work fast.
[0] I wrote Batarang's new perf panel before Google abandoned the project
"Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. "
>>The truth of the matter is that in the general case, it doesn't matter. We engineers like to go on and on about this or that perf efficiency but most of the time the code runs fast enough
THIS!
This is why battery life on mobile sucks
everyone who thinks this way is the reason
.
As everything moves to the web, the performance of your code matters
.
So what if my phone has just enough CPU to render your site? You should not be content with that - you should strive to use less, so my CPU can go to sleep faster.
.
Your job is supposed to be hard. you're an engineer! Please consider the consequences of your actions.
> Your job is supposed to be hard. you're an engineer! Please consider the consequences of your actions.
My clients pay my wages and they are the ones who choose what my priorities should be. Where are these mythical developers who get to choose how long to spend on optimising working code without any financial imperatives? Outside of hobby projects there's always someone counting the pennies.
As a consultant, my clients do not dictate at all what my priorities should be. I work with them to identify what their priorities are, what they'd like to see done. I train them to value performance and quality, not the lowest bottom line. I also train them to learn how to identify performance and quality. I give them feedback on their ideas/priorities, and always include my own suggestions for platform/software maintenance/improvement/enhancement. I'm their consultant and vendor, not their employee.
I probably take this to a weird degree for some, but I actively think about my client's software quite often, and frequently toss ideas their way whenever they hit me. You'd be surprised how often those ideas--which I thought were cool, hence the sharing--come back later as something they want. It's just basic sales.
Of course, I'm always building large, custom projects from scratch, not taking on projects that ask me to optimize "working code without any financial imperatives". On the other hand, when I identify a part of their software that can gain performance or some other kind of improvement—say, some dependency has improved that will ease X, making priorities Y and Z easier to implement—they listen to me and put it in their list of priorities.
I agree, but this is a moral imperative, not a financial one. And before you say "it's immoral to spend the client money on things they don't want", you're right. Your job is to convince the client it is "worth" it.
You don't even need a mobile phone to prove that.
Every Adobe desktop software iteration takes twice than the previous one to open and offers pretty much the same functionalities just arranged in a different manner. And buggier.
Yes developers your developer-time is the most precious thing in the universe but please consider your user's time and their computing resources as well.
It's a customer's decision, not a developer's one. A one liner like the one in the post should be added at zero cost by any developer, but more important optimizations compete with the budget of the features that sell the product of the customer. In my experience customers want features first, optimizations last and only if the unoptimized app/site runs too slow on their devices. And developers don't like to work for free.
Even if the customer doesn't demand it, you should have your own standards for quality and performance and never compromise on them when it comes to your deliverables.
You're actually harming your business if you choose to do shitty work for small bucks and good work for big bucks. If you take your standards very seriously it improves the capabilities of your team and let's you take on more lucrative contracts.
> And developers don't like to work for free.
Oddly enough, the highest earning developers I know don't think like that.
I understand your feelings but I don't think they match the reality of many places around the world.
Maybe those developers earn so much that they can provide quality even if their customers don't explicitly demand it. But we can look at it in another way: their customer pay so much because they also pay for that quality and take it for granted. Deliver to them an unpolished product (in any way) and somebody else will code the next one.
Unfortunately not all customers are like that. Many of them fight for every single dollar/euro/whatever. They know they are compromising on quality and accept the tradeoff. After all, it's their privilege to decide the limits of their budget and maybe there is nothing they can do about it. The developer must accept it too, get the job done as quickly as possible and take another job. Or do very few and very long high quality jobs at unbearable costs and end up bankrupt quickly (and possibly piss off the customer because you're taking so long to deliver.)
Btw: customers give constraints also on time. There is no time to provide much quality when they want a feature delivered in a couple of days on a system you never saw before. It happened to me a few weeks ago. I made it but I could have done it better if I had at least one week? Sure. Would they pay me twice as much? Nope.
>>unless you've got a confirmed performance problem, you shouldn't think about it at all.
I like to write high quality code that I'm proud of. This means code not just works, but works efficiently and fast. It goes back to what Steve Jobs said once:
“When you’re a carpenter making a beautiful chest of drawers, you’re not going to use a piece of plywood on the back, even though it faces the wall and nobody will ever see it. You’ll know it’s there, so you’re going to use a beautiful piece of wood on the back. For you to sleep well at night, the aesthetic, the quality, has to be carried all the way through.”
That said, this is more of an ideal to strive towards and it's not always possible. Sometimes there are tight deadlines that need to be met, and something has to give. In such scenarios, I agree with your order of priorities: 1) code that works, 2) code that works well, 3) code that works fast.
Absolutely - I love digging into the core of frameworks & the language itself to eke out every last bit of performance. But that takes time, something I'm usually short of. All of the examples given in the article weren't neat perf side projects, they were live sites with customers & deadlines. I write the best code I can given the constraints I'm under.
Given the chance, we'd all like to write perfect code but reality tends to interfere.
The same kind that was the CEO of one of the most successful companies in the history of the world.
Steve Jobs may have missed the mark on some of his products during his long tenure at Apple, but his focus on quality in every possible area of what he had a part in creating has paid its benefits
If you're going to complain about the slowness of pages because of the idiosyncrasies of one library over another, then complain about that.
If you're going to complain about the slowness of pages due to trackers and ad servers regardless of which library (or none at all) is used for primary content formatting, then complain about that.
Depends. There's been lots of studies linking page speed to revenue. I would imagine it doesn't manifest much in lower traffic sites where there's too much noise for it to play out, but as you grow in your userbase, working fast starts to become necessary for it to work well.
The tone of your comment sounds like you think I said one should never look at performance. I do this professionally, I should hope folks out there need performance. Let me be clear: A developer should place performance priority in the Right Place, and a good dev will know where that is.
Would you mind linking a few of these studies? I'm curious as to what the point of diminishing returns is.
nngroup [0] says that 100ms feels instantaneous. A good digest cycle run (the basic unit of Angular performance) is 16ms, a mediocre one is 20ms. So a mediocre application has 5x space to grow before the app stops feeling instantaneous.
And what makes it OK to burn X% additional battery life across all your users devices?
I take your general point but battery life is also a problem I have with React Native. Sure, you can drive animations from the JS thread and on modern devices in some cases you can't even tell the difference. But your battery can.
>So a mediocre application has 5x space to grow before the app stops feeling instantaneous.
Not really. Those 100ms are from click to render done, so you also need to account for the physical transmission latency, the transmission of the data and finally the rendering (which is where your 16-20ms are).
Tried this out on a work project a month or two ago, found it worked quite well and had a noticeable performance boost.
Unfortunately a bunch of inherited legacy code uses angular.element().scope() in a lot of places which then breaks without this turned on, so I had to revert it.
I optimize one module at a time, and I optimize it deeply. The number of people whose stuff I might break is kept to a minimum, the surface area of regression testing is controlled, and next quarter when they ask me for more power I can repeat it, until I run out of modules (hopefully someone will write some more in the meantime).
The whole idea of the Tall Tent Pole is pretty enticing, but the thing is nobody is ever gonna buy into going back for the last 20% in any one part, and these things always have a multiplicative factor. If you're in a field with no competition, this isn't a big deal, but how often does that happen?
This is a case of bad defaults - why should a developer be required to write code, even if it is a one liner, to _disable_ debug? It should be the other way around - you write a single liner to enable debug.
Correct. Debug options should never be a default. They should be enabled explicitly through the act of debugging (perhaps a flag somewhere in your web app, etc). I'm guessing it is the way it is for simplicity so someone can debug without trying to figure any of this out.
That's not just Angular. From the React README[1]:
> Note: by default, React will be in development mode. The development version includes extra warnings about common mistakes, whereas the production version includes extra performance optimizations and strips all error messages.
> To use React in production mode, set the environment variable NODE_ENV to production. A minifier that performs dead-code elimination such as UglifyJS is recommended to completely remove the extra code present in development mode.
I'd like to see some data indicating there is actually an appreciable performance difference. Indeed, with only one line of code to add, the setup cost is low, but this article asserts a performance gain without any evidence.
A Twitter engineer mentioned this in a lightning talk in the AngularJS SF meetup a little more than a year ago - he mentioned that he found speed gains of about 33% with that one line.
It's a great tool to have in your belt for optimizing angular apps, most people working with angular are not aware of this unfortunately.
I'd be inclined not to believe even myself, had I wrote such a thing, without hard data. Even if I was right then, things may have changed. And just what constitutes significant, anyways?
Not a very rigorous test - but I just applied this to one of our (very) large angular 1.x apps and it had a consistent 20-30% reduction in profiled execution time across the couple of test interactions I did.
That said, I'm not sure it made much perceptible difference as the app already performed adequately and the reduction is amortized across all of the interactions the user makes.
Keep in mind Angular is a framework where, when you pass it a callback function, it will sometimes behave differently depending on what you named the function's parameters. @_@
(Or at least it used to when last I checked. It does it by calling toString on the function and parsing the result.)
This is known as Dependency Injection and makes testing and codebase componentization a breeze. You may have seen it called "inversion of control" elsewhere. In essence, my components define what they need to run (through the function params) and Angular hands it to them.
For instance:
myApp.service('foo', function (bar, baz) {
registers a service named `foo` that depends on the `bar` and `baz` components. My service doesn't need to know how/where bar & baz come from, it just knows that it'll have them at runtime.
This isn't all callback functions (in fact, Angular is built on Promises, not callbacks) but rather functions when you register a new component.
You can override what gets injected (say, mocking things out in tests).
DI is a fantastic pattern that reduces or otherwise eliminates all sorts of snarls that can come up.
Cheers for the explanation, but this isn't so much "DI", as "reflection for the sake of DI", right? I mean, libraries can have DI without being quite this magical.
I say this naively as a non-user, but in my case this specifically is what made me decide not to use Angular. I was trying it out for a new project and running through tutorials, but when I realized it was being that clever behind the scenes I decided that learning all its quirks would take longer than the rest of the project, and switched to something way simpler.
When I've implemented (toy) DI in C#, I've also used reflection. How else are you finding the types to load? (Happy to see examples in other languages, too)
Sure, Angular has strict DI, which looks like this:
myApp.service('foo', ['bar', 'baz', function (bar, baz) {
Now it doesn't need to read the function params as it has the strict strings. This'll survive function param mangling (a typical minification step).
Sorry to hear you felt you weren't up to learning Angular & DI patterns. It can be tough for some folks who are still learning programming & JavaScript in general, so there's no shame in passing. Maybe next time - challenge yourself!
> Sorry to hear you felt you weren't up to learning Angular & DI patterns. It can be tough for some folks who are still learning programming & JavaScript in general
I'm sure you don't mean that to sound condescending, but that's really not what I said. It was a question of magicalness vs. payoff - I needed a front-end framework that would handle a bunch of databinding and stay out of my way, and halfway into my first tutorial I found none of the sample code worked (either because I changed a local variable name or because my project already had minification set up, I don't recall). Either way the docs and tutorial I was using didn't even mention the function was being introspected, I had to go source-diving to find that out.
It all worked out to make Angular feel less like a framework and more like a career choice - I couldn't just give it idiomatic javascript and expect things to work. If this introspection thing is the one and only magical part of Angular and I just happened to trip over it, maybe I got the wrong impression.
I'd be interested in how significant the actual performance hit is - I see no measurements.
There are plenty of times you'd want to enable various debug features, even in production, even if it means leaving them always on. The only real question is if the tradeoffs are worth it - the performance hit, if any, and the security implications, if any, versus the productivity gains.
It wasn't an option before 1.3, so I imagine it was debug by default to avoid breaking sites in the wild (ours uses angular.element().scope() in some old code which breaks with debug info off)
It's the same design choice as most C compilation toolchains: you get debug symbols during the compilation process, and you can strip the binaries later if you want.
I've searched a few minutes for any blog post or article which demonstrates the performance difference between turning this setting on or off, and I haven't found anything.
If you don't have a benchmark, you don't have a performance boost.
This is a silly statement. Not everything is placebo. I'm working on a bigger Angular application and adding this one line of code made a small perceivable difference.
Did you do a double blind test or use any instrumentation to confirm your perception? I ask as someone who has more than once been convinced that I'd made something faster only to prove myself wrong after measuring it.
There was a 3 job string in the late nineties where the first impressive thing I did was go fix the log levels of the code and get transaction times down by 50%. Sometimes the simplest tricks are the best.
I've also been known to take a couple minutes off a build process or fix something that is annoying everybody to break the ice.
I agree. He kept repeating "this one line of code that improves Angular performance!" like he's trying to optimize for SEO on the term "improve angular performance".
I see this more as a tooling failure. All the yeoman/grunt/gulp/webpack/boilerplate/starterkit BS that you need to do to get a minified/concatenated/compressed build deployed and none of that turns this option off?
The only way I was ever able to get an angular project built/tested/deployed was by using something like yeoman. It's kind of shocking that the default project templates set up everything that you need except for this one thing.
I do notice that the made with angular site isn't even minifying their code:
Yeah, this is the hidden cost of not choosing sane defaults. If you're not sure what "sane" is, default to "most likely/common use case". It's good to hear this is changed to opt-in in Angular 2 though.
What the author discovered is really shitty defaults for Angular. Most software is like that. Don't blame the developers using the software, blame the Angular developers for choosing shitty defaults. Instead of choosing production ready defaults, they chose development ready defaults, creating more work for everyone.
I think it would create much more work to optimize the defaults for production than development. I'd guess fewer than 1% of all debugged angular apps ever go into "production", and even fewer in situation where the performance gained by this would be meaningful.
Oh please. There are thousands of Angular guides out there. Some people don't use the official documentation, especially when it's as shitty as Angular's is.
My experience is that Ember.js does a good job in that area. Through ember-cli they provide sane defaults when deploying for production vs a local development environment.
I've played with this setting on a few projects and didn't notice any big difference so I'd like to see benchmarks for it. I reasoned that if it's not significantly slowing the code down and could be used for easier debugging later I didn't see the harm leaving it in.
Yeah this seems more like something that Angular should be doing, rather than the end user. If you're in a production environment Angular should enable this for you.
Great trick. Incredible that it's not on by default.
if you've applied that trick and still find yourself wondering what's taking up time, we just released a performance monitoring tool. We're looking for feedback, so please let me know how you find it: https://opbeat.com/angularjs
If you're using Ionic 1.x, the debugging info is forced to enabled, since some of Ionic's internals depend on this for some reason. Haven't tested with 2.x to see if they've improved this yet.
Heck, I shouldn't even be saying this as it'll cut into my very lucrative field but unless you've got a confirmed performance problem, you shouldn't think about it at all. Really. Leave all of the fancy perf tweaks behind. Sure, you might get ridiculed on Medium but that's par for the course here on the internet. I'm afraid articles like these will cause lots of cargo-cult 'optimization' that just makes the job harder for future devs.
Make it work, make it work well, THEN make it work fast.
[0] I wrote Batarang's new perf panel before Google abandoned the project