Javascript Optimization

Version 12

    Status

    WIP.

    Description

    This article describes our work to improve the JavaScript Framework of GateIn.

     

    After working a while on Resource Controller, we realize that to increase significantly the speed of web page loading/displaying, the optimization of JavaScript Framework is essential.

    Specification

     

    The goals of our work on JavaScript code are:

     

    - Clean up unused/bad code.

    - Optimize the implementation.

    - Reduce the total size.

    - Simplify JavaScript files 's inter-dependencies.

    - Etablish an optimal organization of JavaScript files into resources Resource Controller

    - Integrate JQuery Framework.

     

     

    Use of JQuery

     

    We tend to replace the core part of our JavaScript Framework with JQuery Core as the latter has been proved to be better in term of performance and portability across browsers. On the other hand, the code built over JQuery is often more concise and readable, that makes total size of JavaScript code smaller.

     

    The only thing in the core part of existing JavaScript Framework we must keep is the support of right to left

     

    Use of JSON syntax

     

    In legacy JavaScript code, the prototype style was used widely to define object

     

     

    {code:javascript}

    function A(){};

    A.prototype.foo = function(){};

    A.prototype.bar = function(){};

    eXo.A = new A();

    {code}

     

    This prototype style gains better performance if we have multipe objects A in a web page (which is rare in GateIn), but the code looks ugly and has bigger size. So, we decided to use JSON syntax to define objects. In a nutshell, the above code becomes

     

    {code:javascript}

    eXo.A = {

    foo : function(){},

     

    bar : function(){}

    }

    {code}

     

    Lazy load and assynchronous load

     

    The speed of displaying a web page is often measured by the DOMContentLoaded time (for the concept of DOMContentLoaded time, read this blog entry). To minimize it, we tried to apply following mechanisms

     

    1. Load independent resources in parallel if the browser supports async attribute in <script> element.

    2. Use a callback function of document's onload event to load JavaScript code that is not required before DOM content is loaded.

     

    Code Changes Description

     

    In this section, we enlist all JavaScript files of JS Framework along with the major changes on them.

    eXo.js

     

    Changes:

    - Define the method loadJS which enables JavaScript loading and has control over loading order.

    - Deprecate require method  and suggest loadJS as an alternative.

    AsyncLoader.js

    Changes:

    - Replacement of the former Loader.js, provides mechanism to load resources lazily( scripts and stylesheets) and supports assynchronous loading (depend on browser)

    Util.js

    eXo.core.Util provides extension to Javascript Core, thanks to the prototype property.

     

     

    {code:javascript}

    Array.prototype.extendedMethod : function(){

     

    };

    {code}

     

    Changes:

    - Clean up non-widely used extension

    JSON.js


    Changes:

    - Remove the parse method and replace it usages with parseJSON in JQuery core

    Skin.js

    Changes:

    - Delete addCoreSkin and addApplicationSkin methods.

    Browser.js

     

    Changes:

    - Remove methods whose equivalence could be found in JQuery Core

    - Move eXo.core.Mouse to UIRightClickPopupMenu.js

    DOMUtil.js

    Changes:

    - Delete the file DOMUtil.js.

    - Replace usage of legacy DOMUtil with JQuery selectors.

    UIPopup.js

    Changes:

    - Break the dependence on UIMaskWorkspace.js

    - Make Drag-n-Drop methods work with DragDrop2.js

    UIPopupSelectCategory.js

    Changes:

    - Remove hide method

    - Use JQuery in UIPopupSelectCategory.js

    UIMaskLayer.js

    Changes:

    - Break the dependence on UIMaskWorkspace

    - Use jQuery in UIMaskLayer.js

    UIMaskWorkspace.js

    Changes:

    - Replace init method with the pair show/hide methods

    I18n.js

    Changes:

    - Most of methods are deleted after API handling I18n for JS is introduced in resouces-loading branch.

    PortalHttpRequest.js

    Changes:

    - Integrate JQuery Core

    I18NMessage.js

    Changes:

    - Keep only one utility method

    HTMLEntities.js and HTMLUtil.js

    Changes:

    - Delete both files and replace their usage with the pair of methods text/html in JQuery Core

    DragDrop.js

    Changes:

    - Delete this file and replace its usage with DragDrop2.js

    DragDrop2.js

    Changes:

    - Use DragDrop2 for all DnD code in GateIn.

    - Support Escape key event.

    UIGadget.js

    Changes:

    - Use DragDrop2 instead of legacy DragDrop

    - Integrate JQuery Core

    UIPortlet.js

    Changes:

    - Delete this file, we use CSS hover feature for the control icons in portlet windows.

    UIPopupMenu.js

    Changes:

    ScrollManager.js

    This new file groups scroll-managing methods defined in UIPortalControl.js

    UIPortalNavigation.js


    - Define  mouseEnterTab/mouseLeaveTab methods as an equivalence of changeTabNavigationStyle method

    in UIHorizontalTabs.js

    UITabbedDashboard.js

    Changes:

    - Move the file to dashboard portlet application.

    - Integrate JQuery Core

     

    UIDashboard.js

    Changes:
    - Apply JQuery Core to the implementation

     

    UIDashboardUtil.js

    Changes:
    - Apply JQuery Core to the implementation

    UIPopupWindow.js

    Changes:

    - Refactor initDND method, using DragDrop2 instead of DragDrop

    - Replace init method with the pair show/hide

    - Integrate JQuery Core

    UIPortal.js

    Changes:

    - Move content-editing-relevant methods to PortalComposer.js

    - Move methods used for language/skin switching to associated Groovy templates.

    - Move sitemap-relevant code to JavaScript code of SiteMap portlet.

    - Delete definition of UIComponent object type.

    - Cleanup content-searching methods, replace their usage with JQuery selector.

     

    PortalComposer.js

    This new file groups methods serving content edition which were belongs to UIPortal.js

    PortalDragDrop.js

    Changes:

    - DnD working flow bases on DragDrop2.js instead of DragDrop.js

    - Integrate JQuery Core

    UIForm.js

    Changes:

    - Replace usage of DOMUtil with JQuery Core 's equivalence

    VerticalScrollManager.js

    Changes:

    - Replace usage of DOMUtil with JQuery Core 's equivalence

    UIItemSelector.js

    Changes:

    - Replace usage of DOMUtil with JQuery Core 's equivalence

    - Cleanup unused methods

     

    UIDropDownControl.js

    Changes:

    - Replace usage of DOMUtil with JQuery Core 's equivalence

    - Cleanup unused methods

    UIHorizontalTabs.js.

    Changes:

    - Move changeTabNavigationStyle method to mouseEnterTab/mouseLeaveTab in UIPortalNavigation.js

    - Cleanup unused/bad code.

    - Replace usage of DOMUtil with JQuery Core 's equivalence

     

    UIPortalControl.js

    Changes:

    - Decouple into UIPortalControl.js, ScrollManager.js and VerticalScrollManager.js

    UIVirtualList.js

    Changes:

    - Replace DOMUtil traversing with JQuery selector

    UIUpload.js

    Changes:
    - Apply JQuery Core to the implementation

    UIVerticalSlideTabs.js

    This file would be moved to upper product as it is not used anywhere in GateIn.

    UICombobox.js

    This file would be moved to upper product as it is not used anywhere in GateIn.

    UIRightClickPopupMenu.js

    Changes:

    - Replace DOMUtil traversing with JQuery selector

    - Use JQuery code style to setup callbacks

    UINotification.js

    Changes:

    - Apply JQuery Core to the implementation.

    - Replace DOMUtil traversing with JQuery selector

    UICalendar.js

    Changes:

    - Apply JQuery Core to the implementation

    UIColorPicker.js

    Changes:

    - Apply JQuery Core to the implementation

     

    Resource Organization

     

    About dividing JavaScript files into resources along with our effort on JavaScript code, we have reach following structure

     

    Resouces:

     

    jquery, bootstrap, base, common, webui, webui-ext, portal and some resources with portlet scope

     

    Dependencies:

     

    base -> jquery, bootstrap

    common -> base

    webui -> common

    webui-ext -> common

    portal -> common

    navigation -> base

     

    To get the detail of each resources, readers are invited to look at the configuration file  eXoResources/src/webapp/WEB-INF/gatein-resources.xml