Javascript execution & require js - javascript

I have been looking into requirejs for couple of days. I think it's a great tool for code structure, modules etc. I'm more interested in performance and lazy loading of modules in production environment. It can minify & merge js and loads modules on demand.
I don't really understand how requirejs achieves this feature(lazy loading of modules in a minified and concatenated file)? I'll appreciate if someone can shed some light on this?
From requirejs:
The optimizer will only combine modules that are specified in arrays of string literals that are passed to top-level require and define calls, or the require('name') string literal calls in a simplified CommonJS wrapping. So, it will not find modules that are loaded via a variable name:
Not sure what above statement means? Can we achieve this lazy loading feature with vanilla JS?

It does not minify and concatenate on demand. The documentation you have read is for r.js - the require.js optimizer which can run on nodejs and can minimize and concatenate your code, but not "on demand" - you have to run the optimizer to create the minified and concatenated files and then put those on your live site.
It can't take non-minified files on your live site and minify them when a user requests them.

Related

Javascript bundling and module loading

I've recently been thrown in to clean up a project which has like 45-50 individual .js javascript files. I wonder what the best approach would be to decrease the loading size of them all. Just concatenate all files into one with npm or gulp? Install some module loader? webpack?
If you're already concatenating, minifying, and uglifying and you don't want all the files to be loaded on all the pages due to a monolithic bundle, you might be looking for something like Webpack's Commons Chunk Plugin.
This plugin walks down the tree of dependencies for each endpoint defined in your Webpack.config file and determines which modules are required across all pages. It then breaks the code into two bundles, a "common" bundle containing the modules that every page requires, which you must load with a script tag on each page:
<script src="commons.js" charset="utf-8"></script>
And an endpoint bundle for each individual page that you reference normally in a script tag placed after the commons script tag:
<script src="specificpage.bundle.js" charset="utf-8"></script>
The result is that an individual page will not have to load modules that will only ever be used on other pages.
Again, this is a Webpack plugin. I don't know if this functionality is available as a Gulp plugin, because it must have knowledge of all endpoints in order to determine which dependencies are common to them all.
I redirect you to the very good https://github.com/thedaviddias/Front-End-Checklist
In particular the following advises:
JavaScript Inline: High You don't have any JavaScript code inline
(mixed with your HTML code).
Concatenation: High JavaScript files
are concatenated.
Minification: High JavaScript files are minified (you can add the .min suffix).
You can accomplish this with a package manager such as gulp, grunt or webpack (for the most famous ones). You just need to choose what you prefer to use.
If you consider webpack, You can start with my very simple (but understanding) starter: https://github.com/dfa1234/snippets-starter
There's no much thing that you can do, basically is:
Concatenation - https://www.npmjs.com/package/gulp-concat
Minification - https://www.npmjs.com/package/gulp-minify
Instead of creating all those scripts, you can get something to re-use on yeoman, f.e. the Fountain, so it will reduce a lot of time just typing procedural code for doing the concatenation/minification.
Also if you can use some lazy load (like RequireJS or some frameworks have support to lazy load the module, like Angular) that will improve the performance of your aplication
EDIT:
If you want even more performance, you can install some compression tool in your server, for example this one for NodeJS https://www.npmjs.com/package/compression
I'm my personal opinion, if you have time, the best approach would be to read and understand the purpose of the project. Then plan a proper refactor. You are not fixing anything with concatenating, this is just a deployment step.
You should analyze which technologies are being used and if you want to maintain this code, in the long run, make a proper refactor into a much more modern stack, maybe you can take a seed project with ES6, webpack, Babel... and create a proper repository well maintained with proper modularity and dependencies resolution.
Once you have that, decreasing the load its just about adding proper tools in build time (babel, webpack, etc).
You would like to add some unit tests and continue working properly :)

Is there still a need for a module loader with applications that use JavaScript ES6 modules and classes?

If you code an application using ES6 modules and classes, is there any need to use a module loader framework, or is the best practice to just use a build tool to concatenate all the code into a file (or files) and include those using a normal script tag?
Yes. Somebody, somewhere along the line has to load the module.
I think you're conflating compiling modules ahead of time vs loading them individually. Webpack is a module loader that outputs a single file for the browsers to use later, while the System API and requirejs et al load a number of individual files.
There are performance factors on both sides, particularly longer build time (when precompiling) vs longer load time (with multiple files).
Webpack, Browserify, and most other module loaders (with the notable exception of the System API) allow you to define some loaders for certain file types and automagically compile your (S)CSS or templates on the way through, as well as running other tools to uglify or obfuscate your code. The ES6 System API does not provide these features, but is a more robust runtime loader than most.
This boils down to two trade-offs:
support for non-JS modules (styles, templates) vs build time
single request and longer build vs many requests and short/no build
Evaluate them for your users (high-bandwidth vs mobile), environment (if you have two dozen CI agents, who cares if the build takes an extra 3s?), and stack (if you have a lot of template files, compiling them AOT could be important).

Eliminating need for require js from optimized app

I've built my app using require.js in order to keep everything modular. Having finished it turns out that require.js itself is bigger than my optimised app code. Is there some way I can get r.js to optimise in such a way that I don't need to include require.js in the final page (e.g. replacing all my define calls with direct definition of properties on a namespace object, with the whole thing wrapped in a closure).
I'm only using define() - never require(), if that makes a difference..?
You still need an AMD loader but you can switch to a much lighter one, such as almond. almond is around 1 kilobyte when minified and gzipped.
From the FAQ:
almond is an AMD API shim that is very small, so it can be used in
place of require.js when all of your modules are built into one file
using the RequireJS optimizer.

To require or not to require?

So I've been building a single page web app for a while now and I've been writing all my code in an extremely modular approach. I've been using the javascript module pattern for all modules and my main API uses the revealing module pattern to expose a small API for plugins and other modules.
So even if I've been writing my code like this someone mentioned I should be using require.js as it gives a better modular approach.
I decided that require.js doesn't really make it more modular so my next thought was how require.js separates out dependencies. Require.js forces you to name dependencies in each module file. But this to me seems to be a task I have to do for every module and I have a lot of modules. At the moment all my files are concatenated into a single javascript file in my grunt build process so really all my files are loaded at the start. I need most of my modules loaded at the start so it made sense to do this.
So my question is... Should I use require.js even though my code is modular and all my files are concatenated together and loaded at the start? Do i need to worry about dependencies or loading order? Any help/advise or previous experience when dealing with this situation would really help. Thanks
Have you had annoyances putting <script> tags in the correct order to handle dependencies right?
Having a requirejs config file where you declare the third-party code and your own code dependency tree is a much more organised approach than declaring <script> tags by yourself.
When you are testing your app in dev environment, wouldn't be helpful to have all those modules in separated files that are easier to debug instead of all of them concatenated?
With requirejs you can switch between optimised/concatenated/minified code used in production environment and a list of independent files representing each module in the development environment.
Are you creating a global variable for each module in your app?
Requirejs avoids creating a global variable for each module so your global scope doesn't get cluttered.
It's usually a good practice to follow conventions in the way you declare modules. Requirejs implements AMD specification that is a well thought way of loading modules in client javascript.
http://requirejs.org/docs/whyamd.html
It's way easier to follow conventions if they're already implemented in a mature framework. And sometimes we don't notice but between apps we do the same thing differently and that affects in the maintenance phase.
Take a look at the requirejs optimizer. Look all the options it give you. It allows you to exclude files, to change versions of a given module, to change the minification tool, to integrate the optimization process with other tools like grunt or bower, etc.
http://requirejs.org/docs/optimization.html
If you don't need any of this, then just continue doing it in your way.

what are the advantages of using an AMD like requirejs or commonjs modules in javascript?

I've read a lot of articles on AMD solutions like RequireJS or module loaders that follow CommonJS style in Javascript.
Let's say I have an app splitted in this parts:
App definition that rely on the framework i use
Model 1 that rely on App definition and framework
Model 2 that rely on App definition, Model 1 and my framework
I may write each part as a RequireJS module or a common JS module and split my project in how many files I want but what's the advantage of writing each part as a module or splitting them in many files and then load them in the right order (to avoid dependency problems) maybe concatenatening all the files in a big one to reduce HTTP requets (as done by r.js optimizer)?
In my opinion, there are three rather important reasons:
You can create and re-use modules without polluting the global namespace. The more polluted your global namespace is, the bigger the chance of a function/variable collision. That means you define a function called "foo" and another developer defines the function "foo" = one of the functions gets overwritten.
You can structure your code into separate folders and files and requirejs will load them asynchronously when needed, so everything just works.
You can build for production. RequireJS comes with its own build tool called R.JS that will concat and uglify your javascript modules into a single (or multiple) packages. This will improve your page speed as the user will have to make less script calls and load less content (as your JS is uglified).
You can take a look at this simple demo project: https://c9.io/peeter-tomberg/requirejs (in cloud9ide).
To build your modules into a single app, all you have to do is have requirejs npm package installed and run the command: r.js -o build/build.properties.js
If there are any questions, ask away.
Edit:
In development, having all modules in separate files is just a good way to structure and manage your code. It also helps you in debugging (e.g. error on "Module.js line 17" instead of "scripts.js line 5373").
For production, you should use the build tool to concat and uglify the javascript into a single file. This will help the page load quicker as you are making less requests. Every request you make to load something slows down your page. The slower your page, the less points Google gives you. The slower the page, the more frustrated your users will be. The slower your page, the less sales you will get.
If you wish to read more about web page performance, look at http://developer.yahoo.com/performance/rules.html

Categories