Minify calls to Math, Number, etc. with Terser - javascript

The code that Terser produces for my project contains many calls to the Javascript Math object and I am wondering if there is an easy way to minify these calls.
Here is a screenshot of part of the minfied code with Math highlighted (altogether there are almost a thousand calls to Math):
I could certainly do the optimization in my original code by setting const min = Math.min etc, but this would be hard to maintain and generally an abominal micro optimization.
As I see it properties in the mangle options cannot be used for this, as properties explicitly will NOT work for built-in Javascript properties.
Does anybody have an idea how calls to Math, Number, etc. can be minified with Terser?

I could not find a solution for this using Terser.
BUT I came to the conclusion, that it would not make much sense to minify all calls to Math for the following reasons:
Obfuscation does not really improve. The mapping would be visible inside the file, so unmapping would be very easy for anyone determined to unobfuscate the code.
File size may be smaller, but since files are sent gzipped over the internet, the actual difference would be very small or none, since multiple string occurences like calls to 'Math' will be compressed by gzipping.
So in conclusion this seems to be neither possible nor necessary.

Related

ASP.NET Application Performance of HTML References

Quick question regarding scripts and html.
In a html file, would there be a difference speed wise (although it might be minor) in the following two examples if I included a JavaScript script using:
<script src="http://localhost:56090/Scripts/jquery-2.1.4.js"></script>
and
<script src="~/Scripts/jquery-2.1.4.js"></script>
The first one includes a script from a different project in the same ASP.NET solution, whereas the second one uses a script from the same project as the html file.
What would be the difference?
On a side note (but kind of related), how do the projects of a solutions relate to each other, are they compiled into a single application domain or are they separate applications but linked to each other?
Many thanks :)
Client-side there is zero difference. Both get emitted to fully-qualified URLs (possibly even the exact same URL, depending on what ~ resolves to) and the client sees no difference between the two.
Server-side there is a tiny difference because ASP.NET needs to translate ~ into a path. That's a very optimized, very fast operation. You shouldn't notice a difference. But if you're at a scale where you really need to squeeze every millisecond possible (like, Google-scale), this adds a millisecond.
In all likelihood you should use whichever makes the most logical sense for your application needs. The performance difference is negligible.
no difference
as
<script src="~/Scripts/jquery-2.1.4.js"></script>
is compiled into the correct string...
The view is compiled anyway regardless of the ~
The the difference in time is basically unmeasureable in c#...
so you wouldn't be able to tell using convention tools if there was actually a difference.... we are probably talking about nanoseconds here or smaller.
so its better to use
<script src="~/Scripts/jquery-2.1.4.js"></script>
than hard coding any values.
Advantage is that the base url is dynamic/relative to what the site is.
i.e. if you hard coded localhost... you are going to have Huge issues when you try and deploy this to an actual url. e.g. www.mycoolwebsite.com

Spaces in equal signs

I'm just wondering is there a difference in performance using removing spaces before and after equal signs. Like this two code snippets.
first
int i = 0;
second
int i=0;
I'm using the first one, but my friend who is learning html/javascript told me that my coding is inefficient. Is it true in html/javascript? And is it a huge bump in the performance? Will it also be same in c++/c# and other programming languages? And about the indent, he said 3 spaces is better that tab. But I already used to code like this. So I just want to know if he is correct.
Your friend is a bit misguided.
The extra spaces in the code will make a small difference in the size of the JS file which could make a small difference in the download speed, though I'd be surprised if it was noticeable or meaningful.
The extra spaces are unlikely to make a meaningful difference in the time to parse the file.
Once the file is parsed, the extra spaces will not make any difference in execution speed since they are not part of the parsed code.
If you really want to optimize download or parse speed, the way to do that is to write your code in the most readable fashion possible for best maintainability and then use a minimizer for the deployed code and this is a standard practice by many web sites. This will give you the best of both worlds - maintainable, readable code and minimum deployed size.
A minimizer will remove all unnecessary spacing, shorten the names of variables, remove comments, collapse lines, etc... all designed to make the deployed code as small as possible without changing the run-time meaning of the code at all.
C++ is a compiled language. As such, only the compiler that the developer uses sees any extra spaces (same with comments). Those spaces are gone once the code has been compiled into native code which is what the end-user gets and runs. So, issues about spaces between elements in a line are simply not applicable at all for C++.
Javascript is an interpreted language. That means the source code is downloaded to the browser and the browser then parses the code at runtime into some opcode form that the interpreter can run. The spaces in Javascript will be part of the downloaded code (if you don't use a minimizer to remove them), but once the code is parsed, those extra spaces are not part of the run-time performance of the code. Thus, the spaces could have a small influence on the download time and perhaps an even smaller influence on the parse time (though I'm guessing unlikely to be measurable or meaningful). As I said above, the way to optimize this for Javascript is to use spaces to enhance readability in the source code and then run a minimizer over the code to generate a deployed version of the code to minimize the deployed size of the file. This preserves maximum readability and minimizes download size.
There is little (javascript) to no (c#, c++, Java) difference in performance. In the compiled languages in particular, the source code compiles to the exact same machine code.
Using spaces instead of tabs can be a good idea, but not because of performance. Rather, if you aren't careful, use of tabs can result in "tab rot", where there are tabs in some places and spaces in others, and the indentation of the source code depends on your tab settings, making it hard to read.

Semi-obfuscate/uglify JavaScript

I know about JS minfiers, obfuscators and minifiers. I was wondering if there is any existing tool (or any fast-to-code solution) to partially obfuscate JavaScript. By partially I mean that it should become difficult to read, but not appear as uglified/minified. It should keep indentation, but lose comments, and partially change variable names, making them unclear without converting them to "a, b, c" like an obfuscator.
The purpose of this could be to take an explicit and reusable code and make it implicit and difficult to be reused by other people, without making it impossible to work with for yourself.
Any idea from where to start to achieve this ? Maybe editing an existing obfuscator ?
[This answer is a direct response to OP's request].
Semantic Designs JavaScript obfuscator will do what you want, but you'll need two passes.
On the first pass, run it as obfuscator; it will rename identifiers (although you can control how much or how that is done), strip whitepspace and comments. If you limit its ability to rename the identifiers, you lose some the strength of the obfuscator but that's your choice.
On the second pass, run it as a prettyprinter; it will introduce nice indentation again.
(In fact, the idea for obfsucation came from building a prettyprinter; if you can print-pretty, surely it is easy to print-ugly).
From the point of view of working with the code, you are better off working with your master copy any way you like, complete with your indentation and nice commentary as documentation. When you are ready to obfsucate, you run the obfuscator, shipping the obfuscated result. Errors reported in the obfuscated result that involve obfuscated names can be mapped back to the original names, using the map of obfuscated <--> original names produced during the obfuscation step.
This a product of my company. I'd provide a link but SO hates it when I do that, so you'll have to find it via my bio or googling.
PS: It works exactly as #georg suggests, by parsing to an AST, mangling, and prettyprinting. It doesn't use esprima.
I'm not aware of a tool that would meet your specific requirements, but it seems to be relatively easy to create, given that the vital parts already exist.
parse the source into an AST, using esprima or similar
manipulate the tree in the way you want (eg. remove comments, mangle identifiers etc)
rebuild the source from the tree using escodegen

GWT reduce compiled javascript size

I have found that the size of the compiled JavaScript grows faster than I had expected. Adding a few lines of Java code to my project can increase the script size in several Kbs.
At the moment my compiled project weights 1Mb. I'm not using any external libraries except for those for MVP (Activities & Places) , testing (JUnit) and logging.
I would like to know if there are any coding practices/recommendations to keep the compiled script as small as possible. I'm not refering to code splitting, but to coding techniques or patterns that can make the compiled JavaScript effectively smaller.
Many thanks
GWT uses a "pay as you go" design philosophy, and since you're not allowed to use reflection the compiler can statically prove (on a method-by-method basis) that a section of code is "reachable", and eliminate those that are not. For example, if you never use the remove() method on ArrayList, then that code does not get included in the resulting JavaScript.
If you are seeing several kilobyte jumps with the addition of just a few lines, it probably means that you've introduced the use of a new type (and possibly one that depends on other new types) that you had not yet been using. It might also mean that you've made a change to send this new type "over the wire" back to the server, in which case a GWT generator had to include JavaScript for marshaling that type, and any new types that are reachable via its "has-a" and "is-a" references.
So if it were me, I would begin there: when you catch a 2-line change making a multi-kilobyte increase, start by looking at the types and asking whether it is a type that you have used before, and whether you're sending a new type over the wire, and whether that type also depends on other types under the hood.
One final thought: in Ray Ryan's 2009 presentation at Google I/O he mentioned a superstition that he had picked up from the GWT compiler team, where they recommended against using generic types (I'm not speaking of Java Generics here, but rather supertypes) as RPC arguments & return values. In particular, instead of having your RPC call take or return a Map, have it take or return a HashMap instead. The belief is that the GWT generator can then narrow the amount of serialization code that it has to create at compile time (because it could, for example, refrain from generating serialization code for a TreeMap).
I hope this helps.
GWT creates different output versions for each supported browser, so when you say the project size is 1MB are you then referring to the combined size of these ? (each browser only download's the one it actually needs).
I have tried to experiment with the generated output when using various inheritance/class/generics constructs. Unfortunately the extra complexity introduced far outweighs the small size improvements gained (when fx. dumping generics).
I have been on some large GWT projects (+50.000 lines) and have found that code obfuscating coupled with turning on compression on the web server to be the simplest most effective way to minimize the downloads. If this does not shrink the code enough, then look into GWT's compilation report which you can use to pinpoint potential problematic classes and places to insert code splitting.

Single letters for naming variables and functions

Context
I read a JavaScript code example written by Google. It used:
Single lowercase letters for naming variables
Single uppercase letters for naming functions
So the code was illegible.
Questions
Why this naming?
What tools are using to do this?
Often when large Javascript libraries are put into production the code is "minimized" in order to...
Decrease the download size
Make it more difficult to reverse engineer the code
I think the primary motivator is #1 however.
This process generally involves things like removing comments and whitespace and changing variable references to single characters.
For instance, take a look at JSMin.
Fewer letters means fewer bytes means faster downloads, which is Google's (stated) primary concern.
They probably use Closure Compiler but YUI Compressor is still popular.
That's JavaScript Obfuscation!
Some people do this to obfuscate, but many do it to minify because the fewer characters means that it is a smaller file to transmit.
You can use minification/compression tools and google even has one that is open source:
http://code.google.com/closure/compiler/
It serves two main purposes
reduced bandwidth, since Google serves so many pages
obfuscation
http://blogoscoped.com/archive/2008-02-08-n74.html

Categories

Resources