diff options
Diffstat (limited to 'doc/development/fe_guide/performance.md')
-rw-r--r-- | doc/development/fe_guide/performance.md | 63 |
1 files changed, 53 insertions, 10 deletions
diff --git a/doc/development/fe_guide/performance.md b/doc/development/fe_guide/performance.md index 5d2b699c40d..de9a9f5cb14 100644 --- a/doc/development/fe_guide/performance.md +++ b/doc/development/fe_guide/performance.md @@ -1,3 +1,9 @@ +--- +stage: none +group: unassigned +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers +--- + # Performance ## Best Practices @@ -71,9 +77,8 @@ controller with the `index` action. If a corresponding file exists at `pages/projects/issues/index/index.js`, it will be compiled into a webpack bundle and included on the page. -NOTE: **Note:** -Previously we had encouraged the use of -`content_for :page_specific_javascripts` within haml files, along with +Previously, GitLab encouraged the use of +`content_for :page_specific_javascripts` within HAML files, along with manually generated webpack bundles. However under this new system you should not ever need to manually add an entry point to the `webpack.config.js` file. @@ -91,17 +96,55 @@ browser's developer console while on any page within GitLab. modules outside of the entry point script. Just import, read the DOM, instantiate, and nothing else. -- **Entry Points May Be Asynchronous:** - _DO NOT ASSUME_ that the DOM has been fully loaded and available when an - entry point script is run. If you require that some code be run after the - DOM has loaded, you should attach an event handler to the `DOMContentLoaded` - event with: +- **`DOMContentLoaded` should not be used:** + All of GitLab's JavaScript files are added with the `defer` attribute. + According to the [Mozilla documentation](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-defer), + this implies that "the script is meant to be executed after the document has + been parsed, but before firing `DOMContentLoaded`". Since the document is already + parsed, `DOMContentLoaded` is not needed to bootstrap applications because all + the DOM nodes are already at our disposal. + +- **JavaScript that relies on CSS for calculations should use [`waitForCSSLoaded()`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/assets/javascripts/helpers/startup_css_helper.js#L34):** + GitLab uses [Startup.css](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38052) + to improve page performance. This can cause issues if JavaScript relies on CSS + for calculations. To fix this the JavaScript can be wrapped in the + [`waitForCSSLoaded()`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/assets/javascripts/helpers/startup_css_helper.js#L34) + helper function. ```javascript import initMyWidget from './my_widget'; + import { waitForCSSLoaded } from '~/helpers/startup_css_helper'; - document.addEventListener('DOMContentLoaded', () => { - initMyWidget(); + waitForCSSLoaded(initMyWidget); + ``` + + Note that `waitForCSSLoaded()` methods supports receiving the action in different ways: + + - With a callback: + + ```javascript + waitForCSSLoaded(action) + ``` + + - With `then()`: + + ```javascript + waitForCSSLoaded().then(action); + ``` + + - With `await` followed by `action`: + + ```javascript + await waitForCSSLoaded; + action(); + ``` + + For example, see how we use this in [app/assets/javascripts/pages/projects/graphs/charts/index.js](https://gitlab.com/gitlab-org/gitlab/-/commit/5e90885d6afd4497002df55bf015b338efcfc3c5#02e81de37f5b1716a3ef3222fa7f7edf22c40969_9_8): + + ```javascript + waitForCSSLoaded(() => { + const languagesContainer = document.getElementById('js-languages-chart'); + //... }); ``` |