Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
31b95691
Commit
31b95691
authored
Dec 08, 2020
by
Russell Dickenson
Committed by
Amy Qualls
Dec 08, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove future tense from the Front End guide's Performance section
parent
d1b77d04
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
29 additions
and
29 deletions
+29
-29
doc/development/fe_guide/performance.md
doc/development/fe_guide/performance.md
+29
-29
No files found.
doc/development/fe_guide/performance.md
View file @
31b95691
...
@@ -18,29 +18,29 @@ When writing code for realtime features we have to keep a couple of things in mi
...
@@ -18,29 +18,29 @@ When writing code for realtime features we have to keep a couple of things in mi
Thus, we must strike a balance between sending requests and the feeling of realtime.
Thus, we must strike a balance between sending requests and the feeling of realtime.
Use the following rules when creating realtime solutions.
Use the following rules when creating realtime solutions.
1.
The server
will tell
you how much to poll by sending
`Poll-Interval`
in the header.
1.
The server
tells
you how much to poll by sending
`Poll-Interval`
in the header.
Use that as your polling interval. This
way it is
[
easy for
system administrators to change the
Use that as your polling interval. This
enables
system administrators to change the
polling rate
](
../../administration/polling.md
)
.
[
polling rate
](
../../administration/polling.md
)
.
A
`Poll-Interval: -1`
means you should disable polling, and this must be implemented.
A
`Poll-Interval: -1`
means you should disable polling, and this must be implemented.
1.
A response with HTTP status different from 2XX should disable polling as well.
1.
A response with HTTP status different from 2XX should disable polling as well.
1.
Use a common library for polling.
1.
Use a common library for polling.
1.
Poll on active tabs only. Please use
[
Visibility
](
https://github.com/ai/visibilityjs
)
.
1.
Poll on active tabs only. Please use
[
Visibility
](
https://github.com/ai/visibilityjs
)
.
1.
Use regular polling intervals, do not use backoff polling, or jitter, as the interval
will be
1.
Use regular polling intervals, do not use backoff polling, or jitter, as the interval
is
controlled by the server.
controlled by the server.
1.
The backend code
will most likely
be using etags. You do not and should not check for status
1.
The backend code
is likely to
be using etags. You do not and should not check for status
`304 Not Modified`
. The browser
will transform
it for you.
`304 Not Modified`
. The browser
transforms
it for you.
### Lazy Loading Images
### Lazy Loading Images
To improve the time to first render we are using lazy loading for images. This works by setting
To improve the time to first render we are using lazy loading for images. This works by setting
the actual image source on the
`data-src`
attribute. After the HTML is rendered and JavaScript is loaded,
the actual image source on the
`data-src`
attribute. After the HTML is rendered and JavaScript is loaded,
the value of
`data-src`
will be
moved to
`src`
automatically if the image is in the current viewport.
the value of
`data-src`
is
moved to
`src`
automatically if the image is in the current viewport.
-
Prepare images in HTML for lazy loading by renaming the
`src`
attribute to
`data-src`
AND adding the class
`lazy`
.
-
Prepare images in HTML for lazy loading by renaming the
`src`
attribute to
`data-src`
AND adding the class
`lazy`
.
-
If you are using the Rails
`image_tag`
helper, all images
will b
e lazy-loaded by default unless
`lazy: false`
is provided.
-
If you are using the Rails
`image_tag`
helper, all images
ar
e lazy-loaded by default unless
`lazy: false`
is provided.
If you are asynchronously adding content which contains lazy images then you need to call the function
If you are asynchronously adding content which contains lazy images then you need to call the function
`gl.lazyLoader.searchLazyImages()`
which
will search for lazy images and load
them if needed.
`gl.lazyLoader.searchLazyImages()`
which
searches for lazy images and loads
them if needed.
But in general it should be handled automatically through a
`MutationObserver`
in the lazy loading function.
But in general it should be handled automatically through a
`MutationObserver`
in the lazy loading function.
### Animations
### Animations
...
@@ -56,7 +56,7 @@ properties once, and handle the actual animation with transforms.
...
@@ -56,7 +56,7 @@ properties once, and handle the actual animation with transforms.
### Universal code
### Universal code
Code that is contained
within
`main.js`
and
`commons/index.js`
are
loaded and
Code that is contained
in
`main.js`
and
`commons/index.js`
is
loaded and
run on _all_ pages.
**DO NOT ADD**
anything to these files unless it is truly
run on _all_ pages.
**DO NOT ADD**
anything to these files unless it is truly
needed _everywhere_. These bundles include ubiquitous libraries like
`vue`
,
needed _everywhere_. These bundles include ubiquitous libraries like
`vue`
,
`axios`
, and
`jQuery`
, as well as code for the main navigation and sidebar.
`axios`
, and
`jQuery`
, as well as code for the main navigation and sidebar.
...
@@ -66,26 +66,26 @@ code footprint.
...
@@ -66,26 +66,26 @@ code footprint.
### Page-specific JavaScript
### Page-specific JavaScript
Webpack has been configured to automatically generate entry point bundles based
Webpack has been configured to automatically generate entry point bundles based
on the file structure
with
in
`app/assets/javascripts/pages/*`
. The directories
on the file structure in
`app/assets/javascripts/pages/*`
. The directories
with
in the
`pages`
directory correspond to Rails controllers and actions. These
in the
`pages`
directory correspond to Rails controllers and actions. These
auto-generated bundles
will b
e automatically included on the corresponding
auto-generated bundles
ar
e automatically included on the corresponding
pages.
pages.
For example, if you were to visit
<https://gitlab.com/gitlab-org/gitlab/-/issues>
,
For example, if you were to visit
<https://gitlab.com/gitlab-org/gitlab/-/issues>
,
you would be accessing the
`app/controllers/projects/issues_controller.rb`
you would be accessing the
`app/controllers/projects/issues_controller.rb`
controller with the
`index`
action. If a corresponding file exists at
controller with the
`index`
action. If a corresponding file exists at
`pages/projects/issues/index/index.js`
, it
will be
compiled into a webpack
`pages/projects/issues/index/index.js`
, it
is
compiled into a webpack
bundle and included on the page.
bundle and included on the page.
Previously, GitLab encouraged the use of
Previously, GitLab encouraged the use of
`content_for :page_specific_javascripts`
with
in HAML files, along with
`content_for :page_specific_javascripts`
in HAML files, along with
manually generated webpack bundles. However under this new system you should
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.
not ever need to manually add an entry point to the
`webpack.config.js`
file.
NOTE:
NOTE:
If you are unsure what controller and action corresponds to a given page, you
If you are unsure what controller and action corresponds to a given page, you
can find this out by inspecting
`document.body.dataset.page`
with
in your
can find this out by inspecting
`document.body.dataset.page`
in your
browser's developer console while on any page
with
in GitLab.
browser's developer console while on any page in GitLab.
#### Important Considerations
#### Important Considerations
...
@@ -97,7 +97,7 @@ browser's developer console while on any page within GitLab.
...
@@ -97,7 +97,7 @@ browser's developer console while on any page within GitLab.
instantiate, and nothing else.
instantiate, and nothing else.
-
**`DOMContentLoaded` should not be used:**
-
**`DOMContentLoaded` should not be used:**
All
of GitLab's
JavaScript files are added with the
`defer`
attribute.
All
GitLab
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
)
,
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
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
been parsed, but before firing
`DOMContentLoaded`
". Since the document is already
...
@@ -150,21 +150,21 @@ browser's developer console while on any page within GitLab.
...
@@ -150,21 +150,21 @@ browser's developer console while on any page within GitLab.
-
**Supporting Module Placement:**
-
**Supporting Module Placement:**
-
If a class or a module is _specific to a particular route_, try to locate
-
If a class or a module is _specific to a particular route_, try to locate
it close to the entry point i
t will be
used. For instance, if
it close to the entry point i
n which it is
used. For instance, if
`my_widget.js`
is only imported
with
in
`pages/widget/show/index.js`
, you
`my_widget.js`
is only imported in
`pages/widget/show/index.js`
, you
should place the module at
`pages/widget/show/my_widget.js`
and import it
should place the module at
`pages/widget/show/my_widget.js`
and import it
with a relative path (
e.g.
`import initMyWidget from './my_widget';`
).
with a relative path (
for example,
`import initMyWidget from './my_widget';`
).
-
If a class or module is _used by multiple routes_, place it
with
in a
-
If a class or module is _used by multiple routes_, place it in a
shared directory at the closest common parent directory for the entry
shared directory at the closest common parent directory for the entry
points that import it. For example, if
`my_widget.js`
is imported
with
in
points that import it. For example, if
`my_widget.js`
is imported in
both
`pages/widget/show/index.js`
and
`pages/widget/run/index.js`
, then
both
`pages/widget/show/index.js`
and
`pages/widget/run/index.js`
, then
place the module at
`pages/widget/shared/my_widget.js`
and import it with
place the module at
`pages/widget/shared/my_widget.js`
and import it with
a relative path if possible (
e.g.
`../shared/my_widget`
).
a relative path if possible (
for example,
`../shared/my_widget`
).
-
**Enterprise Edition Caveats:**
-
**Enterprise Edition Caveats:**
For GitLab Enterprise Edition, page-specific entry points
will
override their
For GitLab Enterprise Edition, page-specific entry points override their
Community Edition counterparts with the same name, so if
Community Edition counterparts with the same name, so if
`ee/app/assets/javascripts/pages/foo/bar/index.js`
exists, it
will take
`ee/app/assets/javascripts/pages/foo/bar/index.js`
exists, it
takes
precedence over
`app/assets/javascripts/pages/foo/bar/index.js`
. If you want
precedence over
`app/assets/javascripts/pages/foo/bar/index.js`
. If you want
to minimize duplicate code, you can import one entry point from the other.
to minimize duplicate code, you can import one entry point from the other.
This is not done automatically to allow for flexibility in overriding
This is not done automatically to allow for flexibility in overriding
...
@@ -172,10 +172,10 @@ browser's developer console while on any page within GitLab.
...
@@ -172,10 +172,10 @@ browser's developer console while on any page within GitLab.
### Code Splitting
### Code Splitting
For any code that does not need to be run immediately upon page load, (
e.g.
For any code that does not need to be run immediately upon page load, (
for example,
modals, dropdowns, and other behaviors that can be lazy-loaded), you can split
modals, dropdowns, and other behaviors that can be lazy-loaded), you can split
your module into asynchronous chunks with dynamic import statements. These
your module into asynchronous chunks with dynamic import statements. These
imports return a Promise which
will be resolved once
the script has loaded:
imports return a Promise which
is resolved after
the script has loaded:
```
javascript
```
javascript
import
(
/* webpackChunkName: 'emoji' */
'
~/emoji
'
)
import
(
/* webpackChunkName: 'emoji' */
'
~/emoji
'
)
...
@@ -184,7 +184,7 @@ import(/* webpackChunkName: 'emoji' */ '~/emoji')
...
@@ -184,7 +184,7 @@ import(/* webpackChunkName: 'emoji' */ '~/emoji')
```
```
Please try to use
`webpackChunkName`
when generating these dynamic imports as
Please try to use
`webpackChunkName`
when generating these dynamic imports as
it
will provide
a deterministic filename for the chunk which can then be cached
it
provides
a deterministic filename for the chunk which can then be cached
the browser across GitLab versions.
the browser across GitLab versions.
More information is available in
[
webpack's code splitting documentation
](
https://webpack.js.org/guides/code-splitting/#dynamic-imports
)
.
More information is available in
[
webpack's code splitting documentation
](
https://webpack.js.org/guides/code-splitting/#dynamic-imports
)
.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment