Am I correct to say that JavaScript code isn't compiled, not even JIT? If so, does that mean that comments have an affect on performance, and I should be very careful where I put place my comments? Such as placing function comments above and outside the function definition when possible, and definitely avoid placing comments inside loops, if I wanted to maximize performance? I know that in most cases (at least in non-loop cases), the change in performance would be negligible, but I think that this would be something that is good to know and be aware of, especially for front-end/js developers. Also, a relevant question was asked on a js assessment I recently took.
Am I correct to say that JavaScript code isn't compiled, not even JIT?
No. Although JavaScript is traditionally an "interpreted" language (although it needn't necessarily be), most JavaScript engines compile it on-the-fly whenever necessary. V8 (the engine in Chrome and NodeJS) used to compile immediately and quickly, then go back and aggressively optimize any code that was used a lot (the old FullCodegen+TurboFan stack); a while back having done lots of real-world measurement, they switched to initially parsing to byteocde and interpreting, and then compiling if code is reused much at all (the new Ignition+TurboFan stack), gaining a significant memory savings by not compiling run-once setup code. Even engines that are less aggressive almost certainly at least parse the text into some form of bytecode, discarding comments early.
Remember that "interpreted" vs. "compiled" is usually more of an environmental thing than a language thing; there are C interpreters, and there are JavaScript compilers. Languages tend to be closely associated with environments (like how JavaScript tends to be associated with the web browser environment, even though it's always been used more widely than that, even back in 1995), but even then (as we've seen), there can be variation.
If so, does that mean that comments have an affect on performance...
A very, very, very minimal one, on the initial parsing stage. But comments are very easy to scan past, nothing to worry about.
If you're really worried about it, though, you can minify your script with tools like jsmin or the Closure Compiler (even with just simple optimizations). The former will just strip comments and unnecessary whitespace, stuff like that (still pretty effective); the latter does that and actually understands the code and does some inlining and such. So you can comment freely, and then use those tools to ensure that whatever minuscule impact those comments may have when the script is first loaded is bypassed by using minifying tools.
Of course, the thing about JavaScript performance is that it's hard to predict reliably cross-engine, because the engines vary so much. So experiments can be fun:
Here's an experiment which (in theory) reparses/recreates the function every time
Here's one that just parses/creates the function once and reuses it
Result? My take is that there's no discernable difference within the measurement error of the test.
The biggest effect that comments have is to bloat the file size and thereby slow down the download of the script. Hence why all professional sites use a minimizer for a productive version to cut the js down to as small as it gets.
It may have some effect. Very minimalistic effect, though (even IE6 handles comments correctly ! to be confirmed...).
However, most people use a minifier that strips off comments. So it's okay.
Also:
V8 increases performance by compiling JavaScript to native machine code before executing it.
Source
It can prevent functions from being inlined, which affects performance, though this shouldn't really happen.
In some perhaps isolated circumstances, comments definitely somehow bog down the code execution. I am writing a lengthy userscript, using in the latest Firefox on Mac using TamperMonkey, and several days' increasingly frustrated troubleshooting came to an end when I stripped the lengthy comments from the script and suddenly the script execution stopped hanging completely on Facebook. Multiple back-and-forth comparisons running the same exact script on a fresh user account, the only difference being the comments, proved this to be the case.
Related
It looks like I'm asking about a tricky problem that's been explored a lot over the past decades without a clear solution. I've seen Is It Possible to Sandbox JavaScript Running In the Browser? along with a few smaller questions, but all of them seem to be mislabeled - they all focus on sandboxing cookies and DOM access, and not JavaScript itself, which is what I'm trying to do; iframes or web workers don't sound exactly like what I'm looking for.
Architecturally, I'm exploring the pathological extreme: not only do I want full control of what functions get executed, so I can disallow access to arbitrary functions, DOM elements, the network, and so forth, I also really want to have control over execution scheduling so I can prevent evil or poorly-written scripts from consuming 100% CPU.
Here are two approaches I've come up with as I've thought about this. I realize I'm only going to perfectly nail two out of fast, introspected and safe, but I want to get as close to all three as I can.
Idea 1: Put everything inside a VM
While it wouldn't present a JS "front", perhaps the simplest and most architecturally elegant solution to my problem could be a tiny, lightweight virtual machine. Actual performance wouldn't be great, but I'd have full introspection into what's being executed, and I'd be able to run eval inside the VM and not at the JS level, preventing potentially malicious code from ever encountering the browser.
Idea 2: Transpilation
First of all, I've had a look at Google Caja, but I'm looking for a solution itself written in JS so that the compilation/processing stage can happen in the browser without me needing to download/run anything else.
I'm very curious about the various transpilers (TypeScript, CoffeeScript, this gigantic list, etc) - if these languages perform full tokenization->AST->code generation that would make them excellent "code firewalls" that could be used to filter function/DOM/etc accesses at compile time, meaning I get my performance back!
My main concern with transpilation is whether there are any attacks that could be used to generate the kind code I'm trying to block. These languages' parsers weren't written with security in mind, after all. This was my motivation behind using a VM.
This technique would also mean I lose execution introspection. Perhaps I could run the code inside one or more web workers and "ping" the workers every second or so, killing off workers that [have presumably gotten stuck in an infinite loop and] don't respond. That could work.
I want to improve my Coffeescript coding style. When I program in Scala, I can write a module in an hour or two, run it and have only a few minor bugs that I can quickly identify and fix.
In Coffeescript, I spend about the same time up front but I end up having a staggering amount of small bugs that would have been caught by a static type checker and I end up having to compile, reload the browser, step through some code, add some break points, etc. It's an infuriating experience and takes significantly longer.
It's much harder to abstract and encapsulate functionality due to the lack of interfaces and many other OO-features.
Are there design patterns that replace the encapsulation/abstraction generally provided by OO? Or is there a primer/guide on how to think in a more Coffeescript-y way (or how to solve problems using a prototypical approach)?
What have you done to become more productive in Coffeescript (or Javascript - perhaps even any dynamically typed languages)?
If you're coming from a statically-typed, class-centric language like Java or Scala, learning JavaScript/CoffeeScript is going to be a challenge. The compiler doesn't help you nearly as much, which means that it takes you minutes to discover small mistakes instead of seconds.
If that's your major bottleneck, then I'd suggest embracing a more test-driven coding methodology. Use a library like QUnit to write small tests for each piece of functionality you develop. Used properly, this style gives you the same benefits as a static compiler without compromising the flexibility of a dynamic language.
Don't go straight to Coffee Script. Learn the core concepts from prototype and Javascript OO. IMMO You can learn both at the same time, but you will benefit much more if you get Vanilla Javascript first. Based on my personal experience, Coffee Script syntactic sugar for classes can be a trap if you don't understand prototypical inheritances (it's easy to get stuck on a bug).
Coffee Script debugging is still not a completely solved matter in terms of tools, the only way I know it can be done is to write tests (a pain when you're just starting) or look at the generated code (at least for the more obscure bugs).
It was odd for me too; in my case coming from a C/C++ background.
What clicked for me is that you can reduce your iteration time significantly with a few tweaks of your work environment. The idea is to reduce it enough that you can write code in small chunks and test your code very very frequently.
On the lack of compile time checks: You'll get used to it. Like significant white space, the lack of compile time type checking just melts away after a few weeks. It's hard to say how exactly, but at least I can tell you that it did happen for me.
On the lack of interfaces: that's a tricky one. It would be nice to get a little more help in larger systems to remind you to implement entire interfaces. If you're finding that you really are losing a lot of time to that, you could write your own run time checks, and insert them where appropriate. E.g. if you register your objects with a central manager, that would be a good time to ensure that the objects qualify for the role they're being submitted to.
In general, it's a good to bear in mind that you have decent reflection abilities to hand.
On the lack of encapsulation: Given that coffeescript implements a very nice class wrapper to the prototype scheme, I'm assuming you mean the lack of private variables? There are actually a number of ways you can hide details from clients, if you feel the need to, and I do; usually to stop myself from shooting my foot in the future. The key is usually to squirrel things away in closures.
Also, have a look at Object.__defineGetter__ / Object.defineProperty? Getters and setter can help a lot in these situations.
On reducing iteration time:
I was using the built in file watcher in coffee to compile the scripts on change. Coupled with TextMate's ability to save all open files on losing focus, this meant that testing was a matter of switching from textmate to chrome/firefox and hitting refresh. Quite fast.
On a node.js project though, I've setup my views to just compile and serve on the fly so even the file watcher is superfluous. They're cached in release, but in the debug mode they're always reloaded from disk, recompiled, and on encountering errors I just serve them up instead. So now every few minutes I switch to the browser, hit refresh and either see my test running, or the compiler errors.
How much overhead is there when use functions that have a huge body?
For example, consider this piece of code:
(function() {
// 25k lines
})();
How may it affect loading speed / memory consumption?
To be honest I'm not sure, the good way to help answer your question is to measure.
You can use a javascript profiler, such as the one built into Google Chrome, here is a mini intro to the google chrome profiler
You can also use Firebug profiler() and time(): http://www.stoimen.com/blog/2010/02/02/profiling-javascript-with-firebug-console-profile-console-time/
Overhead is negligible on a static function declaration regardless of size. The only performance loss comes from what is defined inside the function.
Yes, you will have large closures that contain many variables, but unless your declaring several tens of thousands of private variables in the function, or executing that function tens of thousands of times, then you won't notice a difference.
The real question here is, if you split that function up into multiple smaller functions, would you notice a performance increase? The answer is no, you should actually see a slight performance decrease with more overhead, although your memory allocation should at least be able to collect some unused variables.
Either way, javascript is most often only bogged down by obviously expensive tasks, so I wouldn't bother optimizing until you see a problem.
Well that's almost impossible to answer.
If you realy want to understand about memory usage, automatic garbage colection and other nitty gritty of closure, start here: http://jibbering.com/faq/notes/closures/
Firstly, products like JQuery are built on using closures extremely heavily. JQuery is considered to be a very high performance piece of Javascript code. This should tell you a lot about the coding techniques it uses.
The exact performance of any given feature is going to vary between different browsers, as they all have their own scripting engines, which are all independantly written and have different optimisations. But one thing they will all have done is tried to give the best optimisations to the most commonly used Javascript features. Given the prevelance of JQuery and its like, you can bet that closures are very heavily optimised.
And in any case, with the latest round of browser releases, their scripting engines are all now sufficiently high performance that you'd be hard pushed to find anything in the basic language constructs which consitutes a significant performance issue.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 8 years ago.
Improve this question
I need to write a GUI related javascript library. It will give my website a bit of an edge (in terms of functionality I can offer) - up until my competitors play with it long enough to figure out how to write it by themselves (or finally hack the downloaded script). I can accept the fact that it will be emulated over time - thats par for the course (its part of business). I just want to have a few months breathing space where people go "Wow - how the f*** did they do that?" - which gives me a few months of free publicity and some momentum to move onto other things.
To be clear, I am not even concerned about hard core hackers who will still hack the source - thats a losing battle not worth fighting (and in any case I accept that my code is not "so precious"). However, what I cannot bear, is the idea of effectively, simply handing over all the hard work that would have gone into the library to my competitors, by using plain javascript that anyone can download and use. If someone is going to use what I have worked on, then I sure as hell don't want to simply hand it over to them - I want them to work hard at decoding it. If they can decode it, they deserve to have the code (they'll most likely find out they could have written better code themselves - they just didn't have the business sense to put all the [plain vanilla] components in that particular order) - So, I'm not claiming that no one could have written this (which would be a preposterous claim in any case) - but rather, what I am saying is that no one (up to now) has made the functionality I am talking about, available to this particular industry - and I (thinking as an entrepreneur rather than a geek/coder), want to milk it for all its worth, while it lasts i.e until it (inevitably) gets hacked.
It is an established fact that not one website in the industry I am "attacking" has this functionality, so the value of such a library is undeniable and is not up for discussion (i.e. thats not what I'm asking here).
What I am seeking to find out are the pros and cons of obfuscating a javascript library, so that I can come to a final decision.
Two of my biggest concerns are debugging, and subtle errors that may be introduced by the obfuscator.
I would like to know:
How can I manage those risks (being able to debug faulty code, ensuring/minimizing against obfuscation errors)
Are there any good quality industry standard obfuscators you can recommend (preferably something you use yourself).
What are your experiences of using obfuscated code in a production environment?
If they can decode it, they deserve to have the code (they'll most likely find out they could have written better code themselves - they just didn't have the business sense to put all the [plain vanilla] components in that particular order).
So really, you're trying to solve a business issue with technical measures.
Anybody worth his salt as a Javascript programmer should be able to recreate whatever you do pretty easily by just looking at the product itself, no code needed. It's not like you're inventing some new magical thing never seen before, you're just putting pieces together in a new way, as you admit yourself. It's just Javascript.
Even if you obfuscate the script, it'll still run as-is, competitors could just take it and run with it. A few customizations shouldn't be too hard even with obfuscated code.
In your niche business, you'll probably notice pretty quickly if somebody "stole" your script. If that happens, it's a legal issue. If your competitors want to be in the clear legally, they'll have to rewrite the script from scratch anyway, which will automatically buy you some time.
If your competitors are not technically able to copy your product without outright stealing the code, it won't make a difference whether the code is in the clear or obfuscated.
While you can go down the long, perilous road of obfuscators, you generally don't see them used on real, production applications for the simple reason that they don't really do much. You'll notice that Google apps, which is really a whole heap of proprietary and very valuable JavaScript when you get down to it, is only really minimized and not obfuscated, though the way minimizers work now, they are as good as obfuscated. You really need to know what you're doing to extract the meaning from them, but the determined ones will succeed.
The other problem is that obfuscated code must work, and if it works, people can just rip it wholesale, not understanding much of it, and use it as they see fit in that form. Sure, they can't modify it directly, but it isn't hard to layer on some patches that re-implement parts they don't like without having to get in too deep. That is simply the nature of JavaScript.
The reason Google and the like aren't suffering from a rash of cut-and-paste competitors is because the JavaScript is only part of the package. In order to have any degree of control over how and where these things are used, a large component needs to be server-based. The good news is you can leverage things like Node.js to make it fairly easy to split client and server code without having to re-implement parts in a completely different language.
What you might want to investigate is not so much obfuscating, but splitting up your application into parts that can be loaded on-demand from some kind of service, and as these parts can be highly inter-dependent and mostly non-functional without this core server, you can have a larger degree of control over when and where this library is used.
You can see elements of this in how Google is moving to a meta-library which simply serves as a loader for their other libraries. This is a step towards unifying the load calls for Google Apps, Google AdSense, Google Maps, Google Adwords and so forth.
If you wanted to be a little clever, you can be like Google Maps and add a poison pill your JavaScript libraries as they are served dynamically so that they only operate in a particular subdomain. This requires generating them on an as-needed basis, and while it can always be removed with sufficient expertise, it prevents wholesale copy-paste usage of your JavaScript files. To insert a clever call that validates document.href is not hard, and to find all these instances in an aggressively minimized file would be especially infuriating and probably not worth the effort.
Javascript obfuscation facts:
No one can offer a 100% crack free javascript obfuscation. This means that with time and knowledge every obfuscation can be "undone".
Minify != obfuscation: When you minify your objective is: reduce code size. Minified code looks completly different and its much more complex to read (hint:jsbeautifier.com). Obfucation has a completly different objective: to protect the code. The transformations used try to protect Obfuscated code from debugging and eavesdropping. Obfuscation can even produce a even bigger version of the original code which is completely contrary to the objectives of minification.
Obfuscation != encryption - This one is obvious but its common mistake people make.
Obfuscation should make debugging much much harder, its one of it objectives. So if it is done correctly you can expect to loose a lot of time trying to debug obfuscated code.That said, if it is done correctly the introduction of new errors is a rare issue and you can easily find if it is an obfuscation error by temporarily replacing the code with non obfuscated code.
Obfuscation is NOT a waste of time - Its a tool. If used correctly you can make others waste lots of time ;)
Javascript obfuscation fiction: ( I will skip this section ;) )
Answer to Q2 - Sugested obfuscation tools:
For an extensive list of javascript obfuscator: malwareguru.org. My personal choice is jscrambler.com.
Answer to Q3 - experiences of using obfuscated code
To date no new bugs introduced by obfuscation
Much better client retention. They must come to the source to get the source;)
Occasional false positives reported by some anti-virus tools. Can be tested before deploying any new code using a tool like Virustotal.com
Standard answer to obfuscation questions: Is using an obfuscator enough to secure my JavaScript code?
IMO, it's a waste of time. If the competitors can understand your code in the clear (assuming it's anything over a few thousand lines...), they should have no trouble deobfuscating it.
How can I manage those risks (being
able to debug faulty code,
ensuring/minimizing against
obfuscation errors)
Obfuscation will cause more bugs, you can manage them by spending the time to debug them. It's up to the person who wrote the obfuscation (be it you or someone else), ultimately it will just waste lots of time.
What are your experiences of using
obfuscated code in a production
environment?
Being completely bypassed by side channel attacks, replay attacks, etc.
Bugs.
Google's Closure Complier obfuscates your code after you finish writing it. That is, write your code, run it through the compiler, and publish the optimized (and obfuscated) js.
You do need to be careful if your using external js that interfaces with the lib though because it changes the names of your objects so you can't tell what is what.
Automatic full-code obfuscation is so far only available in the Closure Compiler's Advanced mode.
Code compiled with Closure Advanced mode is almost impossible to reverse-engineer, even passing through a beautifier, as the entire code base (includinhg the library) is obfuscated. It is also 25% small on average.
JavaScript code that is merely minified (YUI Compressor, Uglify etc.) is easy to reverse-engineer after passing through a beautifier.
If you use a JavaScript library, consider Dojo Toolkit which is compatible (after minor modifications) with the Closure Compiler's Advanced mode compilation.
http://dojo-toolkit.33424.n3.nabble.com/file/n2636749/Using_the_Dojo_Toolkit_with_the_Closure_Compiler.pdf?by-user=t
You could adopt an open-source business model and license your scripts with the GPL or Creative Commons BY-NC-ND or similar
While obfuscation in general is a bad thing, IMHO, with Javascript, the story is a little different. The idea is not to obfuscate the Javascript itself but to produce shorter code length (bandwidth is expensive, and that first-time users may just be pissed off waiting for your Javascript to load the first time). Initially called minification (with programs such as minify), it has evolved quite a bit and now a full compiler is available, such as YUI compiler and Google Closure Compiler. Such compiler performs static checking (which is a good thing, but only if you follow the rules of the compiler), minification (replace that long variable name with 'ab' for example), and many other optimization techniques. At the end, what you got is the best of both worlds, coding in non-compiled code, and deploying compiled (, minified, and obfuscated) code. Unfortunately, you would of course need to test it more extensively as well.
The truth is obfuscator or not, any programmer worth his salt could reproduce whatever it is you did in about as much time as it took you. If they stole what you did you could sue them. So bottom line from the business point of view is that you have, from the moment you publish, roughly the same amount of time it took you to implement your design until a competitor catches up. Period. That's all the head start you get. The rest is you innovating faster than your competitors and marketing it at least as well as they do.
Write your web site in flash, or better yet in Silverlight. This will give your company unmatched GUI, that your competitors will be salivating about. But compiled nature of flash/dotnet will not allow them easily pick into your code. It's a win/win situation for you ;)
I'm making an AIR application (so the download time doesn't have a huge impact). Does combining and minifing all the JavaScript files affect the performance? How would obfuscating affect the performance?
Minifying improves performance for your page overall by decreasing the load time (even if only slightly).
Neither minifying nor obfuscating alter the execution time by any perceivable amount for the vast majority of JavaScript code out there.
I do recommend minifying for those reasons and more. Minifying multiple scripts together (like jQuery and its plugins) can yield even greater savings.
As pointed out, on constrained devices and/or with very large codebases minifying could yield a noticeable result.
Minification
Minification does improve performance for two reasons:
Reduced file-size (because it removes comments and unnecessary white spaces), so your script loads faster. Even if it is embedded into the <head>.
It is parsed faster, since comments and white spaces don't have to be explicitly ignored (since they're not there).
Combining
I've written quite a few HTML/JavaScript AIR applications, and from personal experience, combining files won't make a difference. In fact, it's good practice to separate the script based on certain criteria (classes, global functions, SQL functions, etc.). It helps keep them organised when the project becomes too big.
Obfuscation
Obfuscating is usually a combination of minification and renaming variables. It involves using eval to blow up the code again. This reduces performance for obvious reasons, but it depends on the size of your code.
I'd suggest running tests to understand this best for your specific situation.
Everyone here already talked about minifying, but nobody talked about the second part of your question - combining. This will definitely improve performance, probably even more than minifying.
Multiple files require multiple HTTP requests, so when you put them all into one file, only one request is needed. This is important for two reasons:
each individual HTTP request may take longer to load for various routing reasons, and one file will potentially delay your whole application.
browsers and other clients have a maximum limit of files they are allowed to download concurrently from a single domain. Depending on the number of files in your application, this may mean the client queuing them up, thus making the load even longer.
Also, besides minifying and combining, you have to absolutely make sure you have some sort of server-side compression enabled. This can save you 90% or even more in the amount of bytes transferred, depending on the files.
You can read more about compression (gzip, deflate) in How to make your site lightning fast by compressing (deflate/gzip) your HTML, JavaScript, CSS, XML, etc. in Apache.
Minification does not improve the speed at which JavaScript executes at runtime, which I believe it what you're really interested in. In fact, if you use Packer's Base64 compression, it's actually slower on initial load.
Minification will reduce the size of the JavaScript though, making your application's download size smaller.
Minifying strips out all comments, superfluous white space and shortens variable names. It thus reduces download time for your JavaScript files as they are (usually) a lot smaller in filesize. So, yes it does improve performance.
The obfuscation shouldn't adversely affect performance.
The article Best Practices for Speeding Up Your Web Site talks about minifying.
I'd like to post this as a separate answer as it somewhat contrasts the accepted one:
Yes, it does make a performance difference as it reduces parsing time - and that's often the critical thing. For me, it was even just simply linear in the size and I could get it from 12 seconds to 4 seconds parse time by minifying from 3 MB to 1 MB.
It's not a big application either. It just has a couple of reasonable dependencies.
So the moral of the story here is: Yes, minifying is important for performance - and not because of bandwidth, but because of parsing.
According to this page:
Minification in JavaScript is the process of removing all characters that are not necessary from the JavaScript source code. That is why it is called “minification” – because all of the data that is not necessary to the functioning of the JavaScript is removed from the source code, and therefore the JavaScript is “minimized”. Even though these characters are removed from the JavaScript source code, the functionality of the JavaScript code does not change at all.
So, your JavaScript code will behave exactly the same even after it goes through the minification process. Code that has gone through the minification process is also known as “minified” code
What are the benefits and advantages of JavaScript minification
The main purpose of JavaScript minification is to speed up the downloading or transfer of the JavaScript code from the server hosting the website’s JavaScript. The reason that minification makes downloads go faster is because it reduces the amount of data (in the minified JavaScript file) that needs to be downloaded. Less data means that the user’s browser spends less time processing that data, which is why time is saved. So, we can say that minification is performed on JavaScript source code because it is essentially a performance enhancement – and it allows websites that use minified JavaScript to load faster.