2. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Agenda
1 Performance Problem
2 Problem Analysis
3 JavaScript Code Organizing
4 RequireJS Library
5 RequireJS Integration
Minh Hoang TO Modularize JavaScript with RequireJS
3.
4. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Bad User Experience
Numerical Reports
Slow Login Page
Open login form of Dagens Nyheter (http://dn.se) or browse for the first
time to
https://auth.dn.se/login?appId=dagensnyheter.se
↓
↓
Minh Hoang TO Modularize JavaScript with RequireJS
5. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Bad User Experience
Numerical Reports
Low PageSpeed Scores
Figure 1: PageSpeed scores of https://auth.dn.se/login?appId=dagensnyheter.se
Minh Hoang TO Modularize JavaScript with RequireJS
6.
7. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Firebug Timeline
Fundamental Causes
Initiative Idea
Firebug Timeline
Figure 2: Loading timeline on all resources
Figure 3: Loading timeline on JavaScript resources
DOMContentLoaded time: 7.6s
Load main.js time: 5s
Minh Hoang TO Modularize JavaScript with RequireJS
8. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Firebug Timeline
Fundamental Causes
Initiative Idea
Blocking JavaScript
Browser loads the entire main.js file (314.4KB) before rendering DOM content
Figure 4: Blocking main.js
Minh Hoang TO Modularize JavaScript with RequireJS
9. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Firebug Timeline
Fundamental Causes
Initiative Idea
Too Sequential Loading
main.js = jquery + jquery-ui + some jquery plugins + business code of DN
→ Should find one way to load library parts in parallel
Minh Hoang TO Modularize JavaScript with RequireJS
10. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Firebug Timeline
Fundamental Causes
Initiative Idea
Initiative Idea
Organize JavaScript code into modules with loose dependencies so that they
are eligible to deferred, lazy and parallel loading
Minh Hoang TO Modularize JavaScript with RequireJS
11.
12. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Common JavaScript Style
Innovative JavaScript Style
Math Functions
Minh Hoang TO Modularize JavaScript with RequireJS
13. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Common JavaScript Style
Innovative JavaScript Style
Math Functions - Drawbacks
Blocking and sequential load of JavaScript resources:
Browser loads square.js and fourthPower.js too early
Evaluation of fourthPower.js requires function declared in square.js,
sequential load is inevitable
→ See if new JavaScript code styles help?
Minh Hoang TO Modularize JavaScript with RequireJS
14. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Common JavaScript Style
Innovative JavaScript Style
Asynchronous Module Definition
Provide resource containing factory method of R, denote this resource as F(R),
instead of providing directly resource R
F(R) holds:
Name of module R
Names of dependency modules of R
Factory method that generates R
Minh Hoang TO Modularize JavaScript with RequireJS
15. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Common JavaScript Style
Innovative JavaScript Style
Math Functions - AMD Modules
Figure 5: squareAMD module defined in squareAMD.js
Figure 6: fourthPowerAMD module defined in fourthPowerAMD.js
Minh Hoang TO Modularize JavaScript with RequireJS
16. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Common JavaScript Style
Innovative JavaScript Style
AMD - Valuable Features
Browser evaluation of F(R) does not trigger evaluation of R, that
heavy-weight work could be deferred
F(R1), F(R2), . . . , F(Rk ) have no inter-dependencies at evaluation time
even if R1, R2, . . . , Rk do → ideal for parallel loading
Minh Hoang TO Modularize JavaScript with RequireJS
17. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Common JavaScript Style
Innovative JavaScript Style
Math Functions - Use of AMD Modules
Figure 7: Use AMD modules in AMD style
Execution of require block triggers:
Resolution1
of squareAMD and fourthPowerAMD modules
Execution of callback method on completing module resolution
squareAMD and fourthPowerAMD are wired to sq and fp, respectively.
1
Full explanation on resolution is given in RequireJS slides
Minh Hoang TO Modularize JavaScript with RequireJS
18. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Common JavaScript Style
Innovative JavaScript Style
Inversion of Control
Inversion of Control pattern applied to JavaScript
Use of AMD requires JavaScript loader library2
which:
Manages lazy (on demand) and parallel loading of factory resources
F(R1), F(R2), . . . , F(Rk )
Invoke factory methods with proper execution order
Provides naming service for modules
2
RequireJS is such a library
Minh Hoang TO Modularize JavaScript with RequireJS
19.
20. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
General Information
How To Use RequireJS
General Information
http://requirejs.org
JavaScript file and module loader library
Supports Asynchronous Module Definition
Minified size: 14.7KB
Minh Hoang TO Modularize JavaScript with RequireJS
21. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
General Information
How To Use RequireJS
Math Functions
Figure 8: Math Functions example illustrates use of RequireJS
Minh Hoang TO Modularize JavaScript with RequireJS
22. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
General Information
How To Use RequireJS
Module Resolution
For each module name appears in array parameter, RequireJS looks up
associated module object
FOUND:
Assign module object to corresponding parameter of callback function
NOT FOUND:
Generate script block loading JavaScript file named ${module name}.js
Looks up dependencies of AMD module declared in ${module name}.js and
invoke factory method
Put return object into a map structure with key ${module name}
Assign return object to corresponding parameter of callback function of
require block
Minh Hoang TO Modularize JavaScript with RequireJS
23. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
General Information
How To Use RequireJS
RequireJS Configuration Variable
Provide flexible mapping between AMD module and URL of JavaScript
resource containing module definition
Figure 9: Configuration variable in case squareAMD and fourthPowerAMD module definitions are
declared in /js/square_amd.js and /js/fourthPower_amd.js
Minh Hoang TO Modularize JavaScript with RequireJS
24. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
General Information
How To Use RequireJS
Math Functions - Firebug View
Figure 10: Firebug shows that script blocks loading module are added programmatically
Minh Hoang TO Modularize JavaScript with RequireJS
25.
26. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Legacy JavaScript
New JavaScript
Achievements
Extensions
Serviceplus - main.js
Content varies with application (DN, DI, Expressen, . . .)
/main.js?appId=name_of_requested_application
Average size: ≥ 300KB
Common structure: jQuery + jQuery Plugins + business code of application
→ Better JavaScript code organization:
Serviceplus provides jQuery, jQuery Plugins as AMD modules
Business code part of main.js is moved into callback function of require
block
Minh Hoang TO Modularize JavaScript with RequireJS
27. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Legacy JavaScript
New JavaScript
Achievements
Extensions
Serviceplus - AMD Modules
Serviceplus provides popular JavaScript libraries in form of AMD modules:
jQuery
jQuery UI
Other jQuery Plugins
Minh Hoang TO Modularize JavaScript with RequireJS
28. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Legacy JavaScript
New JavaScript
Achievements
Extensions
Serviceplus - jQuery
jQuery module = Minified jQuery wrapped in define block
Figure 11: jQuery AMD module, jQuery.noConflict() is used to avoid conflict with other jQuery
versions
Minh Hoang TO Modularize JavaScript with RequireJS
29. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Legacy JavaScript
New JavaScript
Achievements
Extensions
Serviceplus - jQuery UI
jQuery UI module = Minified jQuery UI wrapped in define block
Figure 12: jQuery UI AMD moduleMinh Hoang TO Modularize JavaScript with RequireJS
30. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Legacy JavaScript
New JavaScript
Achievements
Extensions
Serviceplus - RequireJS Configuration Variable
Declares mapping between Serviceplus AMD modules and URLs of
JavaScript resources
Merged to RequireJS library to save one HTTP request
Minh Hoang TO Modularize JavaScript with RequireJS
31. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Legacy JavaScript
New JavaScript
Achievements
Extensions
Serviceplus - New main.js Structure
New main.js = Business code part of main.js wrapped in require block
Figure 13: main.js of an application using jQuery and jQuery UI
Minh Hoang TO Modularize JavaScript with RequireJS
32. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Legacy JavaScript
New JavaScript
Achievements
Extensions
Faster Login Page
http://account.qa.newsplus.se/login?appId=dagensnyheter.se
↓
↓
Minh Hoang TO Modularize JavaScript with RequireJS
33. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Legacy JavaScript
New JavaScript
Achievements
Extensions
PageSpeed Scores
Figure 14: PageSpeed scores of http://account.qa.newsplus.se/?appId=dagensnyheter.se
Minh Hoang TO Modularize JavaScript with RequireJS
34. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Legacy JavaScript
New JavaScript
Achievements
Extensions
PageSpeed Suggestion
Figure 15: No significant issue on JavaScript resource from PageSpeed suggestions
Minh Hoang TO Modularize JavaScript with RequireJS
35. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Legacy JavaScript
New JavaScript
Achievements
Extensions
Firebug Timeline
Figure 16: Firebug report on JavaScript resource loading
DOMContentLoaded time: 1.88s
Big JavaScript resources jquery, jquery-ui and jquery-custom are loaded in
parallel
Minh Hoang TO Modularize JavaScript with RequireJS
36. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Legacy JavaScript
New JavaScript
Achievements
Extensions
WebPageTest Result
Figure 17: WebPageTest result shows parallel load of large JavaScript resources and sharp reduction
on DOMContentLoaded time
Minh Hoang TO Modularize JavaScript with RequireJS
37. Performance Problem
Problem Analysis
JavaScript Code Organizing
RequireJS Library
RequireJS Integration
Legacy JavaScript
New JavaScript
Achievements
Extensions
Extensions
Refine Serviceplus AMD modules
Extend relevant server-side functionalities
Minh Hoang TO Modularize JavaScript with RequireJS