Hacker News new | past | comments | ask | show | jobs | submit login
Improving Angular performance with 1 line of code (medium.com/hackupstate)
221 points by lolptdr on May 3, 2016 | hide | past | favorite | 114 comments



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%. "

-Donald Knuth [1]

[1]https://books.google.com/books?id=SJHvCgAAQBAJ&pg=PT471&lpg=...


>>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.

Everybody wins.


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.


So, what have you done to improve the situation?


My philosophy: As a professional, you should always consider the user of your product to be your client, whether they're paying you or not.


Only in this specific case it's exactly one line of code. Unless your hourly rate is obscenely high it is essentially a free optimization.


Hopefully in the future browsers will show bandwidth and energy use per domain.


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.


I like this comment and I'd add one more thing:

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.


Interesting to note that generally even quite nice sets of draws have cheap wood at the back...


You have watched too much Norm Abram. Put down the remote and go outside.


Yeah, what kind of asshole carpenter wastes his customer's money by inflating materials costs for no reason?


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


One I would pay, because he values quality over ROI optimization. Something I look for when choosing craftsmen to work for me.


Sometimes there are tight deadlines that need to be met

Where would you say these come from?


> most of the time the code runs fast enough

Tell that to my Nexus 5 struggling to render a basic news article of 1000 words and a few images.


I'd put dollars to doughnuts the slowdown is caused by ads & trackers, not a lack of framework-specific perf tweaks.


So terrible performance is OK if it's caused by ads & trackers? They don't count as part of a page's Javascript payload?


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.

You're talking apples while holding up an orange.


Use Firefox Mobile with uBlock. It's been a long time since I've seen ads on web


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.

[0] https://www.nngroup.com/articles/website-response-times/


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.


do you have any articles discussing react natives increased battery usage? why would it be any more than a native app?


>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).


And you upgrade your machine not when the response time goes up, but when the response time goes up too much.


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.


Some deoptimizations are ahead-of-time planted to make performances increases easy to enable in the future.

http://thedailywtf.com/articles/The-Speedup-Loop


I have a better solution to this problem.

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?


Is there a linter or some such which will catch the most common of these mistakes?


1) Make it work

2) ???

3) Make it work fast


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 particular flag wasn't released until version 1.3 so by opting in rather than out it wasn't released as a breaking change.

When it was released and we tried to use it, it broke our site entirely due to third-party libraries we were using.


It should be on for test and dev builds, and off for production.


Just another reason to hate angular.


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.

[1]: https://www.npmjs.com/package/react


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.


The official Angular docs describe it thusly:

    You may want to disable this in production
    for a significant performance boost
https://docs.angularjs.org/api/ng/provider/$compileProvider

I'm inclined to believe the engineers who wrote the docs on this.


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.


If you tested on your machine, I hope you factored in that your users may not have an up to date machine.


Shouldn't debugging be something you opt-in to rather than opt-out of?

Seems like a weird design choice


> Seems like a weird design choice

Angular.js in a nutshell.


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.


Only if you opt not to use strict dependency injection, and strict DI has been best practice for quite a while now.


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.


Since performance rarely matters and debugging usually does, doesn't seem totally crazy.


Django has DEBUG set to True by default, too.


They have a fairly obvious "SECURITY WARNING: don't run with debug turned on in production!" above it though.


Yes, but it's a setting that you can see and are required to define, it's not a built-in constant that is True unless you define it to be False.


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.


It's a little different though, as debug symbols won't slow down the execution of a compiled program, they just take up space in the binary.


Really? Limited experience, but doesn't GCC require -g to enable debug symbols?


Looks like it's the first suggestion in their production developer guide, https://docs.angularjs.org/guide/production


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.


Given the condescending tone of this article, you'd think the author has some data to back himself up.


I guess after checking 77 web pages if they have this flag enabled or not he didnt have any time left for actual performance testing.


Wow, I did not know that everyone else also right clicked to "inspect element" all over the place, for no reason...

I love moments like this.


It comes in quite handy when you're dealing with sites that attempt to hide content behind a paywall, with just a front-end solution...

#nevertrusttheclient


That still works? Cool.

Off the top of your head, do you remember any examples of sites that expose paywalled content like this?


Not a pay wall, but Quora requires login, and you can just remove the overlay and the "noscroll" body class.


www.kansascity.com


Dude should have made a small fortune selling optimization services to those big corps.


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.


Does Angular 2.0 make this one weird trick unnecessary?


Angular 2 forces you to opt in to debug mode, as opposed to the Angular 1 mechanism of opting out.


This article reminds me of those X Hate Him! ads.

http://i1.kym-cdn.com/photos/images/newsfeed/000/633/254/14f...


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:

https://www.madewithangular.com/static/js/main.js

Though that may be intentional so that people can see how it is written.


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.


Slow websites hate him!


Check out this one weird trick to making your websites 20% faster!


Line 17 will make you furious.


New Law in Your State changes website performance forever!


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.


>>Don't blame the developers using the software, blame the Angular developers for choosing shitty defaults.

I like to blame developers who don't read the friggin documentation on the software they are using.

This particular suggestion is literally the very first one in the developer guide for running Angular in production: https://docs.angularjs.org/guide/production


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.


Less link-baity title - "Using development options in production is bad for performance."


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


I think another question to ask is why calling angular.element().scope() is considered use of "debug info"


Forgive my ignorance, but doesn't the Angular framework

* have this off by default and you have to turn it ON in prod? * have it cause a Console.Log("DEBUG IS ON Y'ALL");

Either way, I mean, there's ways to give folks the heads up, right? It seems odd to have to ADD this in Prod.


Protractor also works with debugInfo turned on from v 3.1.0

https://github.com/angular/protractor/blob/master/CHANGELOG....


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.


Nobody will write that one line until somebody says that it's time to make performance a priority.


This might have went unnoticed to most if the web was binary blobs...


tried this but it broke the angular-datatables directive


tried this but broke the angular datatables directive...


Improve Angular performance with 1 line of code: rm -rf /


TL;DR


this. is. awesome. (and sad that i didnt know this already)


Whatever. I'm using Clojurescript. I'm happy. When I used angular - I wasn't.


Flagged for being written as SEO spam, which is unfortunate because the content is actually useful.




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: