README.txt 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. Core Library
  2. ============
  3. This module changes the Drupal core aggregation mecanism process. It greatly
  4. reduces I/O and aggregated number of files, and improves chances of client
  5. cache hit, therefore while it produces bigger aggregated files, it reduces
  6. greatly the bandwidth utilization while users browse.
  7. This is achieved by bypassing the dynamic CSS and JS inclusion. Instead of
  8. including and aggregating only needed files on a per-page basis, it learns
  9. files being used site-wide while user browse, then is able to produce larger
  10. therefore more revelant files that aggregate all those atomic files whether
  11. or not they are being used on the page.
  12. Over time, the number of aggregated files reduce to achieve a stable state
  13. where all site JS files are being aggregated in one file only, and all site
  14. CSS are being aggretated in only two files (libraries into one side, theme
  15. files into another, can be more if there are browser-specific files).
  16. Once the files are stable, site administrator can then enable the full bypass
  17. mode, which will only uses the actual saved state and won't ever do any more
  18. I/O for CSS and JS inclusion, based on the cached state.
  19. On production sites that do not changes nor update their module often, the
  20. performance boost is significant because no dynamic inclusion is being done
  21. anymore (therefore no I/O are made at all), as the bandwidth consumption is
  22. greatly reduced (because clients will cache these files at first hit and won't
  23. download them on the server after that).
  24. This module produces really a few side-effects, depeing on the theme coding
  25. mainly. We bypass core mecanism, but keep sanefully files weighting which will
  26. avoid most potential conflicts.
  27. Motivation
  28. ----------
  29. Drupal 7 does an hard and heavy work about JS and CSS aggregation. It is able
  30. to separate aggregated files into multiple groups. This is a good thing for
  31. lazzy site admins, the first reason is by doing finer groups, those per-group
  32. aggregated files will have greater chances of getting static file hits.
  33. Therefore, there is a main disadvantage: because groups are hardcoded, even on
  34. a site where the files does not change on a per-page basis, the site will ever
  35. aggregate at least 3 JS files, and 3 CSS files, which is not quite elegant.
  36. On larger scale sites, site admin would want to bypass this ugly aggregation
  37. style which would cause something like 4 to even a lot more useless HTTP
  38. requests, on almost each client hit because aggregated files will be differnt
  39. on a per-page basis.
  40. The ideal case would be to have only one sitewide JS file, as only one sitewide
  41. CSS file. This won't happen because:
  42. - JS are split between libraries and Drupal locale translations.
  43. - CSS are split between libraries and theme files (we do that, for a good
  44. reason).
  45. So, our ideal case will be to have only two sitewide files of each.
  46. Original goal and methodology
  47. -----------------------------
  48. This module intend to allow site administrators to manually set which files
  49. among all core libraries and module specific files should be aggregated as
  50. core immutable libraries.
  51. This is not true anymore because of the learning mecanism, which will be
  52. enabled per default. Therefore, the suicidal tendencies of site admins tell
  53. me that some of them will still use the manual UI in order to build their own
  54. aggregation rules. In fact, the module has been built for this, and this is
  55. a totally legal, moreover totally legitimate thing to do.
  56. When using this manual mode, each one of the selected JS file candidate for
  57. sitewide aggregation will be considered as a library and will be forced to
  58. get to the JS_LIBRARY group. by doing this we open the door to file weight
  59. conflict between group, thus, we have an override mecanism that will consider
  60. each group as a weight addition and will pragmatically add an indescent weight
  61. factor to files that core does not expose itself as a library. This will help
  62. keeping things in order.
  63. JS minification HOWTO
  64. ---------------------
  65. This module can use the JSMin library PHP port in order to minify JS files.
  66. Right now, we won't use any other contrib module in order to remain dependency
  67. agnostic. This is important because this module has one and only one simple
  68. goal, and it shouldn't rely on any other module that add extensive execution
  69. overhead.
  70. All is about performances, and also leaving the choice for the site admin to
  71. do what he want to do.
  72. So, we don't use any library handling module, sorry, it may change, but right
  73. now the only good way of making it work is by adding the jsmin.php file into
  74. this folder:
  75. sites/all/libraries/jsmin/
  76. You can download it there:
  77. https://github.com/rgrove/jsmin-php/
  78. Once you downloaded it, you can enable minification on the Core Library module
  79. configuration page, and the form won't revert the option automatically anymore.
  80. We do not provide this library because its licence may conflict with the GPL
  81. one, sorry about that, but you are on your own for downloading it.
  82. Potential known side effect with CSS
  83. ------------------------------------
  84. CSS files are not processed the same way, because administration screens and
  85. frontend pages won't have the same theme, we can't merge groups else we would
  86. totally break the aggregation benefit of having only one large file. Solution
  87. is a bit ugly, but will work on most sites: we pragmatically override the
  88. CSS_DEFAULT group and add module specific CSS into the CSS_SYSTEM group, using
  89. the same weight alteration mecanism as we use for JS.
  90. The side effect of this (there is always one) is that Drupal, per default, will
  91. put CSS_DEFAULT files after CSS_THEME theme specific files. We reverse order
  92. and set the CSS_DEFAULT into the CSS_SYSTEM which break this behavior. This can
  93. lead to CSS directive conflicts for theme that mess up with module specific CSS
  94. files. Because of this statement, the CSS group merge remains optional.
  95. But it seems we are lucky! Because theme CSS files are ordered before the module
  96. specifics, it happens that theme developers are forced to do proper CSS override
  97. using CSS directive specialization instead of relying onto order, which make our
  98. reverse algorithm to almost always work as-is with well coded themes.
  99. Auto-configuration
  100. ------------------
  101. This module provide a learning mode. Three different profiles are provided for
  102. this learning mode, they are described in administration section. These modes
  103. all works quite the same:
  104. 1. At JS or CSS alteration time, unknown files that should be displayed
  105. on page are found.
  106. 2. Once all these files have been found, the manual variable is populated with
  107. the new files, and saved.
  108. 3. Then, the alteration goes, also using new file found for override, thus
  109. aggregating them the first time.
  110. 4. When a new page is hit, chances that a new file is found is naturally
  111. lowered, the more users browse, the faster you'll reach a state where your
  112. Drupal site naturally aggregates all the files in one and only one file.
  113. Once the configuration actually fits you (you have to do some profiling on your
  114. own for that) you can then switch back to manual or bypass mode in order for
  115. the learning process to stop. The module will still continue to force file
  116. aggregation, using the earlier learnt files.
  117. You can always go back, enable the UI module again and customize the automated
  118. configuration on your own then.
  119. Bypass mode
  120. -----------
  121. When the configuration is OK, site admin should switch to full bypass mode.
  122. This particular mode alter the 'styles' and 'scripts' element types element
  123. info, and forces it to be rendered with our own functions.
  124. When creating CSS aggregated files using the bypass mode, the CSS grouping
  125. mode will gracefully be set to 'dual' mode. This ensures that in case one
  126. or more themes are enabled, there will always be only one included in the
  127. page and will avoid CSS conflicts between themes.
  128. This also ensures that each theme will have its own aggregated CSS file that
  129. won't never be modified anymore until the admin switches back to another mode.
  130. Once the bypass mode is set, aggregated files are generated only once using
  131. the current learnt files state. Those files, once aggregated, won't regenerate
  132. themselves if the files are being manually deleted on the system, so if it
  133. happens, an specific button on the administration page will allow you to force
  134. the module to rebuild these.
  135. Bypass mode and drupal_add_TYPE()
  136. ---------------------------------
  137. When using bypass mode, the hook_library_TYPE_alter() hooks will still be used
  138. during page construction, this ensures the files' weights to be the right one,
  139. we don't store the weight and we won't.
  140. These functions may still do some file_exists() I/O that we should definitely
  141. get rid off. This will be a future challenge.
  142. Because drupal_add_TYPE() function will still be run whatever we do (we can't
  143. take over module's code dynamically), why not use their result anyway?
  144. UI and stat collection systems (Core Library Advanced UI module)
  145. ----------------------------------------------------------------
  146. When in manual mode, aggregation rules can be built over administrative file
  147. listings. We can get a list of system known libraries quite easily and expose
  148. it to the site admin.
  149. Nevertheless we have problems with modules' arbitrary set files, that the
  150. system itself can't guess before those files are being processed at least
  151. once.
  152. We put in place a statistics collection system (which has really heavy and
  153. indencent performance impact) that allows developers to play with a development
  154. site and let the system discover files while browsing. Once all files (the only
  155. thing the developer can do is hope that all files have been processed at least
  156. once) have been discovered, another configuration screen is populated with what
  157. we call the 'orphan files'. Those files are displayed side by side with number
  158. of hits for each one of them.
  159. This 'orphan' screen can then help decide which files the site admin would want
  160. to force being processed and aggregated site wide.
  161. Future
  162. ------
  163. We intend to add a JS minification mecanism to enfore files to get through more
  164. than aggregation, but also minification. This will save up a bit of bandwidth.
  165. Some badly coded JS files won't pass through the minification and will cause
  166. errors on client side, so we will make this mecanism site wide optional, at
  167. first, then per file optional then.