That already works quite well today. I've been using ClojureScript in production for over a year now. It leverages the Google Closure compiler that produces well optimized Js as the target. Since ClojureScript has its own semantics, I'm well insulated from Js except for rare cases where I have to do interop. That said, it will be nice for people writing transpilers, as you could just target the bytecode instead of Js.
given who the author is, the claims are unlikely to be just marketing fluff.
however, i think many frameworks can mostly "disappear" if you compile the entire app with Closure compiler's ADVANCED_OPTIMIZATIONS [1].
[1] https://developers.google.com/closure/compiler/docs/api-tutorial3
They do! They invest a lot of time and research into making their web products load as efficiently as possible, so much so that they made the Closure Compiler to compress their JS assets as much as possible. You also have to think about how much code Google actually has... around 2 <em>billion</em> lines of code. Obviously, that's not all code that can be minified (or should), but that's just a little insight as to how much code they deal with. Whether you're parsing an interpreted language like Python, transmitting HTML, compiling C++, whatever, it's generally a good rule of thumb that the larger the data you're transmitting/compiling/interpreting, the longer/more resources it takes.
As a couple of other people pointed out above, this was most likely not done by the original code writers. It was more likely done when the javascript was run through Google Closure Compiler to cut down on the script size.
> I really want to write in a half assed untyped language
You can use Javascript in a typed fashion using tools from Google or Microsoft:
looks like they used a closure / minifier / obfuscator
https://github.com/mishoo/UglifyJS2 https://developers.google.com/closure/compiler/
I used to work in a shop that would run production ready code thru one or two of them at least to make it harder for others to steal.
Most of the big "JS" apps aren't written in plain JS. E.g. most of Google's stuff is CC-annotated JS or GWT (Java). Some of the new stuff is written in Dart or TypeScript.
Plain JS (ES3/5 in particular) doesn't scale very well. Writing somewhat larger applications with 2+ developers is needlessly difficult. I recommend to download VS Code and give TypeScript a try. You'll probably like it a lot better. Plus, the improved tooling makes it more accessible to beginners.
If you aren't using it on the server-side, you won't need to know any of it, but knowing some might come in handy some day.
> pseudo typecasting
Did you make that term up? Because what you're describing is precisely Hungarian notation, which has several disadvantages and is very rare to find in JS these days; I prefer good IDE and adequate documentation (jsdoc, Google's Closure annotations, etc.) instead.
This particular example should happen so fast that it doesn't really matter if it's concating every time. If you are doing this on a scale where that time actually matters, I would take a look at a library that was built to handle the DOM for you. Something like React would probably be a much better way to deal with large-scale DOM manipulation.
That said, if you just want to make this code as absolutely fast as possible, I would take a look at Closure Compiler.
You will have to write all your Javascript the Closure-way to make use of the advanced compiler mode (which is what makes it better than any other compiler). This means you need to annotate everything with JSDoc plus there are some other quirks when working with external (non-Closure) libraries and objects, you'll have to register them so Closure knows about them.
As far as the library goes: it is has everything jQuery has and more, but fully modularized. You can use goog.require("goog.dom") to get all the DOM functionality or goog.require("goog.dom.query") to get only the dom query stuff. The closure compiler will take care of your dependencies much like Browserify would.
Using Plovr you can actually serve all these dependencies separately during development. So you'll have sort of AMD during development and concatted app for live, which is great (don't think anything like that exists for es6-modules/Browserify).
The pitfall for me was the lack of documentation and following/community. Using JSDoc just feels like too much work for most applications. Maybe not if you're building GMail.
I haven't tried it with Grunt of Gulp yet. The compiler is written in Java, so you'll need that installed. There are grunt/gulp closure tools which will download the compiler.jar and setup tasks, so that should work fine. See: http://closureplease.com/tools/
The bytecode is still just a sort of language that's interpreted via a C program (when using CPython). If your language isn't compiled directly into machine code, then as far as I know it's being executed by an interpreter (though the interpreter may JIT-compile certain hotspots into machine code).
Analogous to CPython, HotSpot JVM is just a C++ program that's an interpreter for Java bytecode, even though there's a "javac" command and even though people sometimes refer to "compiling" Java code. gcc and rustc are examples of actual compilers (rather than interpreters).
Python .pyc files and Java .class files are just caches of the bytecode that the source is converted to, to save the interpreter some time when running the code again.
The ambiguity here is due to "compile" being used to mean both "converting one thing to another thing" and the subset "converting a programming language to machine code". An interpreter may do some "compiling" under the first definition, in the same way that a JavaScript minifier could be called a "compiler" (like the Closure Compiler), and maybe a little under the second definition (if it has JIT compilation features), but it's still very different from a compiler in the sense of gcc, where the entire source code is converted directly into native machine code all at once and only the machine code is spit out. If you want you could never run the compiler again and the machine code would still run because it's raw instructions for your CPU and not dependent on any interpreter/runtime.
The best might be this one - though you need java for it to work, but it's got three compression levels, with the last obe requiring relatively strict coding conventions to not break your code. https://developers.google.com/closure/compiler/ Or you could just use their online version of the tool, if you don't have to automate it.
Space Person - Action RPG twin stick roguelite
Having removed around 100 dead/duplicate events today (and adding them back in via include directives) I am very pleased this still works! The actual html zip generated is not that much smaller, but I think that is down to Googles Closure Compiler - https://developers.google.com/closure/compiler/?csw=1
Great stuff.
Please, break my game and tell my why it sucks!
Yeah I particularly liked the part about
> This small collection of convenience helper methods equates to just a tiny fraction of jQuery’s overall functionality, without wrapping Elements or providing any additional abstraction.
If you don't write ridiculous code and you run your JS through Closure, you'll only ship the parts of jQuery you actually use over the wire to the customer.
Not that that's even the best way to do it - if you reference jQuery from a widely-used CDN, the client's browser will just load it from cache.
You also have the closure compiler! Also you can use compression as well. https://developers.google.com/closure/compiler/?hl=en
But people still use libraries way too much, those tools can just help to some degree. Libraries are written to be expandable with tons of functions, those "compilers" cut away code that's been unused but the used code can still be way larger than needed for a small function. Not to mention duplicates of functions that libraries have their own variants of.
I use google's Closure Compiler in my game.
Compiling your code in 'advanced mode' will give you a few things:
Just a caveat on this stuff:
I use Google's Closure Compiler to transform the hundreds of source files into a single, compressed file. In this process, Closure will rename just about everything in the code. For example, if there's a property in the code called 'experiencePoints', Closure may end up renaming it to 'q'.
Closure will use whatever names it wants when doing this, and there's no guarantee that the names it chooses will be the same from one version of the game to the next.
So, if you spend the time figuring out the 'console commands' for how to give yourself multiple victories, or something like that, all that stuff could easily change in the next release when I recompile the code.
Just so you know.
ClojureScript only requires Java for compilation. The compiled Js can be used anywhere you like and has nothing to do with Java. The Google Closure compiler that's used to compile ClojureScript is written in Java and nobody is going to try to rewrite it as it's a mature piece of software that produces optimized Js code.
As far as I can tell, it's written in JS, but with a compiler/optimizer/framework developed by Google.
Now that I look into it a bit more, I agree that they are very similar. They both:
Can anyone else chime in with differences? The obvious one is jsig-style vs. jsdoc-style, though Google does support a jsdoc style that's really similar to jsig (eg. Closure's @type {function(string):boolean}
would be (String): Boolean
in Flow's syntax).
Dynamic and weak typing is definitely a huge weakness of JavaScript, but I like to program using the Closure compiler (https://developers.google.com/closure/compiler).
You do have to be diligent about typing all your variables, but that's no different than C++. Plus, you get the extra benefit of ignoring types completely when you just want to prototype something.
I would like to point you to these two resources regarding closure compiler.
Then there are some truly great features in closure.
memory leak detection http://static.googleusercontent.com/media/research.google.com/en//pubs/archive/40738.pdf The paper that describes it, compiler option: compilerOptions.setCheckEventfulObjectDisposalPolicy (CheckEventfulObjectDisposal.DisposalCheckingPolicy .AGGRESSIVE);
it has dead code analysis/tree shaking
you can write your own compiler passes (extremely easy to do, we have several in production)
They are in the midst of rewriting the type system internals as well, using the java api* through CompilerOptions.setNewTypeInference, which is making the compiler more aware.
> What would be nice is some tool that just adds type annotations to plain JS, perhaps in special comments à la JSDoc, and then can analyze them.
Closure compiler does exactly this. At least in theory. In practice, I don't think I've ever managed to get a type error, so I'm a little dubious about its efficacy.
Especially when writing javascript for websites there even are tools to shrink your code to save some traffic/loading time.
e.g. naming the most occuring variable just "a" , if function "refresh_screen()" comes up very frequently, it might be renamed to "b()" etc.
https://developers.google.com/closure/compiler/docs/gettingstarted_ui
Get ready for an adventure. It involves Google's own special way of handling JS comments, some of which guide the minifier in how to minify your code. It also involves either bundling all of your code into one, gigantic file before minification so it can consider ALL dead code possibilities, or carefully declaring external dependencies that need to not be removed because you know they'll be called later.
But the upshot of all this work is it can often identify code you're not using at all. For example if you do things right it can throw out a lot of jquery and jqueryui for you, getting you dramatic code savings you can't get with any other minifier.
Big trade off.
https://developers.google.com/closure/compiler/docs/api-tutorial3
Google uses Closure Compiler for their JavaScript. It turns readable JavaScript into optimized and minimized JavaScript. They are working from readable source code. What you see is the result of the compiler.
Alternative option: Run your entire js bundle through the closure compiler and serve your minimized bundle along with your page and style sheets yourself.
https://developers.google.com/closure/compiler
This way you have one less external dependency, and you control all the code bring embedded. If you absolutely have to use a CDN for ads or something stick it inside an iFrame to limit it's access scope.
There are other good answers here for TypeScript, but I'll note that there are benefits to compiling JS (and I do not mean transpiling ES2018 to ES5). If you run a true compiler then you can get some of the same optimizations that you get from other compiled languages such as inlined functions, unrolled loops, etc. That way you can (generally) write your code in a more readable fashion and still have faster code produced for production. Transpilation and polyfilling for older browsers can be handled here too but those can also be done by many other projects.
However, the only ones I know of that do this (other than a bit of tree shaking for dead code elimination) are TypeScript's compiler and the Google Closure Compiler. I was stunned to find out that TypeScript's compiler was written in TypeScript. I realize that's kind of a cool thing to do, but I think the performance really suffers over writing it in a native language.
eslint + custom rules for style.
The Google Closure Compiler (in advanced mode) for actual validation/compilation/minification.
Typescript/tsc would also be a good option.
Well I'm on mobile and somehow hit add before I was done haha.
Anyways they already exist for css as /ubirdyboy18 mentions and the front uncss has links to how to use it with WordPress.
Js there is Google closure compiler with dead code removal https://developers.google.com/closure/compiler/docs/api-tutorial3
Roll-up js with tree shaking https://rollupjs.org/ I think even webpack does this now too
I did not compress this one. But just because it has no semicolons, doesn't mean you can't compress it. I've used the Google Closure Compiler to compress javascript with no semicolons before, and it has worked perfectly.
I have no semicolons, because I am using the standard style of Javascript. The standard style prevents you from littering your code with unnecessary whitespace and newlines, so it makes the code much cleaner and terser.
I think typescript has some features in addition to type annotations that don't copy 1:1 (such as classes/extends etc)
I think the closure compiler would be more akin to what your suggesting https://developers.google.com/closure/compiler/docs/js-for-compiler
This page is probably most relevant. It's a description of all the annotations you can have in your doc comments, as well as the syntax for specifying types:
https://developers.google.com/closure/compiler/docs/js-for-compiler
Nope still Java: https://developers.google.com/closure/compiler/docs/gettingstarted_app
That's kind of annoying to deal with, although this NPM module looks like it helps a little: https://www.npmjs.com/package/closurecompiler
Sometimes it's because people don't want to use some post-processing featuring dead code elimination (this is specially common with libraries). To optimize Javascript, one can use the Google closure compiler.
But note that images typically dwarf the cost of transmitting Javascript, specially the high-resolution images that are used in some sites.
Major Google apps like docs, inbox, gmail and calendar don't use angular. They're primarily closure js based. There are also some larger ui frameworks that aren't public.
Angular is primarily used internally by smaller teams and projects with limited size.
There is absolutely no jquery or angular in any of the apps I mentioned. Inspecting any production Google js manually yourself will be a bit difficult though as all customer facing js must be compiled with the closure compiler
https://developers.google.com/closure/compiler/?hl=en
The interesting thing about Google, for better or worse, is that there is relatively little software there that is not totally homegrown.
Minifiers typically only munge local identifiers. E.g.:
function foo(bar) { ... }
"bar" would be renamed while the global "foo" would not.
If I wrap the whole thing in an IIFE, "foo" would be also renamed.
In advanced mode, the Closure Compiler is more aggressive, but there are ways to control this:
https://developers.google.com/closure/compiler/docs/api-tutorial3#export
you could use google closure compiler and the dead code removal.
you could run the site in a dev enviroment and block scripts one by one (ugggghhhhhh)
you could use google chromes profiler to see what functions were called on the page (I've never personally done this)
you could do a grep search :-(
or you could use a javascript code coverage framework/ tool here are some from stackoverflow
I'm sure there are more but I'm drawing blanks currently
Typescript does not support the same types as closure (yet), their roadmap (which I read this week) will likely bring it on par. Things like union and tuple types have been available for a long time. All this said, I think Typescript is a great project, but for me until I can extend the compiler and have tree shaking it is not ideal. This said, one of our teams at work use angular (and are .net based) and I am going to introduce the Typescript compiler into their process over the next 2 months. Resources like optionally typed also gives me warm and fuzzy feelings and I am glad MS embarked on this project. have a read through https://developers.google.com/closure/compiler/docs/js-for-compiler if you are interested.
IntelliJ has great support for the closure annotations, refactoring is a fair bit behind where most JVM languages are in terms of support, but fairly decent. in the refactoring space check out the refaster tool google published, here is a doc describing it https://docs.google.com/document/d/14-rsX1-VoTN2lpFalbwr4_yupxXYW-qNYn2XGVvhLwE/view#heading=h.v5znd73iml8n
Awesome, nice job. You should minify the bundle.js file you have up at the moment. Closure Compiler is probably still the best around for minifying JavaScript.
Edit:
You need to alert the user in some way when it starts downloading. I am not sure if you do or don't because I put in a hash and hit the button, but nothing happened.
I know, I use minifiers, I just now realize that "why the fuck do we have js minifiers" could've been taken the wrong way. Just look at jquery - uncompressed 223kb, minified 93kb - it doesn't seem like much but it's still 50%. I also have the experience that some js heavy sites I was working on were sluggish on tablets/phones if the js files weren't minified (transition were choppy for example).
What I meant to say was - I have no idea why people try to do work of minifiers :)
edit: and I think you mean closure compiler
When I said "actually used" I was thinking of the module-to-module definitions, but in terms of call-graphs I believe Dojo 1.9's build system uses Closure Compiler which also does dead-code detection on a more granular level.
Even if there are some edge-cases with a runtime-only dependency, the loading framework has enough information to say: "Oh, that wasn't preloaded? I'll just go grab it a la carte", which at least changes the risk from "doesn't run" to "takes a few milliseconds longer to start".
+1 - this is far closer to 'statically' typing your code as it will get checked during build/dev time and will not impact performance negatively. The type checking only occurs at dev time, and does not occur in browser.
Another alternative is the Google Closure compiler -> https://developers.google.com/closure/compiler/. It can also do this sort of static type checking for you, and it doesn't alter language at all but uses JSDoc style documentation tags to infer types.
EDIT: spelling
>three.js, CubicVR.js, all emscripten-compiled libraries, gl-matrix.
That's niche stuff and you know it.
>Note that you don't necessarily need a library to be closure-friendly.
If it doesn't adhere to a set of rules, things will break.
https://developers.google.com/closure/compiler/docs/limitations
https://developers.google.com/closure/compiler/docs/api-tutorial3
If the code wasn't written with CC in mind it generally won't work. That's the reason why most people use other minifiers.
This is very different from Dart's tree shaking, which just works.
Why would that happen? The download speed is bound to the user bandwidth. If the user has a 1Mb bandwidth then it won't download each file at 1Mb.
The only situation where what you say would be faster would be if the files were distributed across different servers, each with an upload speed lesser than the user download speed, a situation that would be extremely uncommon.
Also, combining all the files into one big file allows you to use JavaScript compressors with advanced options, like ClosureCompiler.
While Clojure the JVM language is great, this is the Clo*<em>s</em>*ure Compiler, with a s. They're actually different things. Just making sure you didn't get confused by my post :P.
For what it's worth, Clojure the language is much more interesting than the Closure Compiler. The former is a cool lisp dialect that can use Java libraries while the latter is just an admittedly clever JavaScript minifier that also does some optimization. (It could actually do more; I haven't used it myself, but it's not a new language.)
So if you just want to learn something new, Clojure is a good bet, but it has nothing to do with my comment :P.
> The lack of adequate static analysis to prevent you from shooting yourself in the foot with type mismatches tends to make javascript (in my experience) extremely painful to use for large, non-trivial programming tasks.
https://developers.google.com/closure/compiler/
> It parses your JavaScript, analyzes it, removes dead code and rewrites and minimizes what's left. It also checks syntax, variable references, and types, and warns about common JavaScript pitfalls.