Wednesday, November 26, 2014

Revisit requirejs 2.1.x

1. baseUrl
The baseUrl is normally set to the same directory as the script used in a data-main attribute for the top level script to load for a page

baseUrl can be set manually via the RequireJS config. If there is no explicit config and data-main is not used, then the default baseUrl is the directory that contains the HTML page running RequireJS.

2. path

paths config is relative to the baseUrl, and never includes a ".js" extension since the paths config could be for a directory.

if you use a tool like volo, it will stamp the package.json with the version information but keep the file on disk as "jquery.js".

3. module ID
If a module ID has one of the following characteristics, the ID will not be passed through the "baseUrl + paths" configuration, and just be treated like a regular URL that is relative to the document:

Ends in ".js".
Starts with a "/".
Contains an URL protocol, like "http:" or "https:".

that is, indicated by a dependency string starting with a slash, has a protocol, or ends in .js

For require("./relative/name") calls that can happen inside a define() function call, be sure to ask for "require" as a dependency, so that the relative name is resolved correctly:

4. shim
use the shim config for some traditional/legacy "browser globals" scripts that do not express their dependencies via define()

For "modules" that are just jQuery or Backbone plugins that do not need to export any module value, the shim config can just be an array of dependencies. e.g. 'jquery.scroll': ['jquery']

You should use the mainConfigFile build option to specify the file where to find the shim config. The other option is to duplicate the shim config in the build profile.

If you are using uglifyjs to minify the code, do not set the uglify option toplevel to true.

5. data-main
use a data-main script to set configuration options and then load the first application module.
If you want to to do require() calls in the HTML page, then it is best to not use data-main. data-main is only intended for use when the page just has one main entry point, the data-main script.

Be aware that the data-main script is loaded asynchronously.

6. require
module dependency injection via require() call

Normally you should not need to use require() to fetch a module, but instead rely on the module being passed in to the function as an argument.

7. define
defines a well-scoped object that avoids polluting the global namespace. since global variables are not created, it makes it possible to load multiple versions of a module in a page.

There should only be one module definition per file on disk. The modules can be grouped into optimized bundles by the optimization tool.

Types of module through define() call
a. Simple Name/Value Pairs
b. Definition Functions
c. Definition Functions with Dependencies
    The function will be called to define the module once all dependencies have loaded. The function should return an object that defines the module. Also, the order of the function arguments should match the order of the dependencies.
d. Define a Module as a Function
    Modules do not have to return objects. Any valid return value from a function is allowed.
e. Define a Module with a Name
    It is normally best to avoid coding in a name for the module and just let the optimization tool burn in the module names.

8. Config
data-main entry point js file,
you can define the config object as the global variable require before require.js is loaded

There is a common need to pass configuration info to a module. Modules can then read that info by asking for the special dependency module ID called "module" and calling module.config().

paths config
path mapping could be for a directory

paths config fallbacks
paths fallbacks only work for exact module ID matches. This is different from normal paths config which can apply to any part of a module ID prefix segment.

map config
This feature only works well for scripts that are real AMD modules that call define() and register as anonymous modules. Also, only use absolute module IDs for map config. Relative IDs (like '../some/thing') do not work.

bundle config
allows configuring multiple module IDs to be found in another script

Supported configuration options:
    baseUrl: the root path to use for all module lookups.
    paths: path mappings for module names not found directly under baseUrl.
    bundles: Introduced in RequireJS 2.1.10: allows configuring multiple module IDs to be found in another script.

Thursday, November 13, 2014

Bootstrap progressbar caused high CPU

We met this issue twice from different engineers. Usually front-end performance is mainly about javascript esp. loop to do IO operations (like network, localstorage etc), however, rendering is also a big impact like css animation, UI reflow.

The solution to progressbar is to remove it from DOM after done. Don't keep it in DOM.
Avoid UI reflow by using createDocumentFragment