8406fe857046d93d859aee4be3d8d7de7608b573
[GitHub/WoltLab/woltlab.github.io.git] / docs / javascript / general-usage.md
1 # General JavaScript Usage
2
3 ## The History of the Legacy API
4
5 The WoltLab Suite 3.0 [introduced a new API](new-api_writing-a-module.md) based on AMD-Modules
6 with ES5-JavaScript that was designed with high performance and visible dependencies
7 in mind. This was a fundamental change in comparison to [the legacy API](legacy-api.md)
8 that was build many years before while jQuery was still a thing and we had to deal
9 with ancient browsers such as Internet Explorer 9 that felt short in both CSS and
10 JavaScript capabilities.
11
12 Fast forward a few years, the old API is still around and most important, it is
13 actively being used by some components that have not been rewritten yet. This
14 has been done to preserve the backwards-compatibility and to avoid the
15 significant amount of work that it requires to rewrite a component. The components
16 invoked on page initialization have all been rewritten to use the modern API, but
17 some deferred objects that are invoked later during the page runtime may still
18 use the old API.
19
20 However, the legacy API is deprecated and you should not rely on it for new
21 components at all. It slowly but steadily gets replaced up until a point where its
22 last bits are finally removed from the code base.
23
24 ## Embedding JavaScript inside Templates
25
26 The `<script>`-tags are extracted and moved during template processing, eventually
27 placing them at the very end of the body element while preserving their order of
28 appearance.
29
30 This behavior is controlled through the `data-relocate="true"` attribute on the `<script>`
31 which is mandatory for almost all scripts, mostly because their dependencies (such
32 as jQuery) are moved to the bottom anyway.
33
34 ```html
35 <script data-relocate="true">
36 $(function() {
37 // Code that uses jQuery (Legacy API)
38 });
39 </script>
40
41 <!-- or -->
42
43 <script data-relocate="true">
44 require(["Some", "Dependencies"], function(Some, Dependencies) {
45 // Modern API
46 });
47 </script>
48 ```
49
50 ## Including External JavaScript Files
51
52 The AMD-Modules used in the new API are automatically recognized and lazy-loaded
53 on demand, so unless you have a rather large and pre-compiled code-base, there
54 is nothing else to worry about.
55
56 ### Debug-Variants and Cache-Buster
57
58 Your JavaScript files may change over time and you would want the users' browsers
59 to always load and use the latest version of your files. This can be achieved by
60 appending the special `LAST_UPDATE_TIME` constant to your file path. It contains
61 the unix timestamp of the last time any package was installed, updated or removed
62 and thus avoid outdated caches by relying on a unique value, without invalidating
63 the cache more often that it needs to be.
64
65 ```html
66 <script data-relocate="true" src="{@$__wcf->getPath('app')}js/App.js?t={@LAST_UPDATE_TIME}"></script>
67 ```
68
69 For small scripts you can simply serve the full, non-minified version to the user
70 at all times, the differences in size and execution speed are insignificant and
71 are very unlikely to offer any benefits. They might even yield a worse performance,
72 because you'll have to include them statically in the template, even if the code
73 is never called.
74
75 However, if you're including a minified build in your app or plugin, you should
76 include a switch to load the uncompressed version in the debug mode, while serving
77 the minified and optimized file to the average visitor. You should use the
78 `ENABLE_DEBUG_MODE` constant to decide which version should be loaded.
79
80 ```html
81 <script data-relocate="true" src="{@$__wcf->getPath('app')}js/App{if !ENABLE_DEBUG_MODE}.min{/if}.js?t={@LAST_UPDATE_TIME}"></script>
82 ```
83
84 ### The Accelerated Guest View ("Tiny Builds")
85
86 !!! info "You can learn more on the [Accelerated Guest View](../migration/wsc30/javascript.md) in the migration docs."
87
88 The "Accelerated Guest View" was introduced in WoltLab Suite 3.1 and aims to
89 decrease page size and to improve responsiveness by enabling a read-only mode
90 for visitors. If you are providing a separate compiled build for this mode, you'll
91 need to include yet another switch to serve the right version to the visitor.
92
93 ```html
94 <script data-relocate="true" src="{@$__wcf->getPath('app')}js/App{if !ENABLE_DEBUG_MODE}{if VISITOR_USE_TINY_BUILD}.tiny{/if}.min{/if}.js?t={@LAST_UPDATE_TIME}"></script>
95 ```
96
97 ### The `{js}` Template Plugin
98
99 The `{js}` template plugin exists solely to provide a much easier and less error-prone
100 method to include external JavaScript files.
101
102 ```html
103 {js application='app' file='App' hasTiny=true}
104 ```
105
106 The `hasTiny` attribute is optional, you can set it to `false` or just omit it
107 entirely if you do not provide a tiny build for your file.