Bug 1704528 - migrate first section performance docs r=firefox-source-docs-reviewers,ahal

Differential Revision: https://phabricator.services.mozilla.com/D111864
This commit is contained in:
Kim Moir 2021-04-19 15:33:19 +00:00
Родитель b2ba954d3b
Коммит e928155e9b
12 изменённых файлов: 479 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,89 @@
# Benchmarking
## Debug Builds
Debug builds (\--enable-debug) and non-optimized builds
(\--disable-optimize) are *much* slower. Any performance metrics
gathered by such builds are largely unrelated to what would be found in
a release browser.
## Rust optimization level
Local optimized builds are [compiled with rust optimization level 1 by
default](https://groups.google.com/forum/#!topic/mozilla.dev.platform/pN9O5EB_1q4),
unlike Nightly builds, which use rust optimization level 2. This setting
reduces build times significantly but comes with a serious hit to
runtime performance for any rust code ([for example stylo and
webrender](https://groups.google.com/d/msg/mozilla.dev.platform/pN9O5EB_1q4/ooXNuqMECAAJ)).
Add the following to your
[mozconfig](/setup/configuring_build_options.html#using-a-mozconfig-configuration-file)
in order to build with level 2:
``` {.notranslate}
ac_add_options RUSTC_OPT_LEVEL=2
```
## GC Poisoning
Many Firefox builds have a diagnostic tool that causes crashes to happen
sooner and produce much more actionable information, but also slow down
regular usage substantially. In particular, \"GC poisoning\" is used in
all debug builds, and in optimized Nightly builds (but not opt Developer
Edition or Beta builds). The poisoning can be disabled by setting the
environment variable
``` {.notranslate}
JSGC_DISABLE_POISONING=1
```
before starting the browser.
## Async Stacks
Async stacks no longer impact performance since **Firefox 78**, as
{{bug(1601179)}} limits async stack capturing to when DevTools is
opened.
Another option that is on by default in non-release builds is the
preference javascript.options.asyncstack, which provides better
debugging information to developers. Set it to false to match a release
build. (This may be disabled for many situations in the future. See
{{bug(1280819)}}.
## Accelerated Graphics
Especially on Linux, accelerated graphics can sometimes lead to severe
performance problems even if things look ok visually. Normally you would
want to leave acceleration enabled while profiling, but on Linux you may
wish to disable accelerated graphics (Preferences -\> Advanced -\>
General -\> Use hardware acceleration when available).
## Flash Plugin
If you are profiling real websites, you should disable the Adobe Flash
plugin so you are testing Firefox code and not Flash jank problems. In
about:addons \> Plugins, set Shockwave Flash to \"Never Activate\".
## Timer Precision
Firefox reduces the precision of the Performance APIs and other clock
and timer APIs accessible to Web Content. They are currently reduce to a
multiple of 2ms; which is controlled by the privacy.reduceTimerPrecision
about:config flag.
The exact value of the precision is controlled by the
privacy.resistFingerprinting.reduceTimerPrecision.microseconds
about:config flag.
## Profiling tools
Currently the Gecko Profiler has limitations in the UI for inverted call
stack top function analysis which is very useful for finding heavy
functions that call into a whole bunch of code. Currently such functions
may be easy to miss looking at a profile, so feel free to *also* use
your favorite native profiler. It also lacks features such as
instruction level profiling which can be helpful in low level profiling,
or finding the hot loop inside a large function, etc. Some example tools
include Instruments on OSX (part of XCode), [RotateRight
Zoom](http://www.rotateright.com/) on Linux (uses perf underneath), and
Intel VTune on Windows or Linux.

Просмотреть файл

@ -0,0 +1,43 @@
# GPU Performance
Doing performance work with GPUs is harder than with CPUs because of the
asynchronous and massively parallel architecture.
## Tools
PIX - Can do timing of Direct3D calls. Works reasonably well with
Firefox. See also [Debugging With
PIX](/en/Debugging_With_PIX "en/Debugging With PIX").
NVIDIA PerfHUD - Last I checked required a special build to be used.
NVIDIA Parallel Nsight - Haven\'t tried.
AMD GPU ShaderAnalyzer - Will compile a shader and show the machine code
and give static pipeline estimations. Not that useful for Firefox
because all of our shaders are pretty simple.
AMD GPU PerfStudio - I had trouble getting this to work, and can\'t
remember whether I actually did or not.
[Intel Graphics Performance Analyzers](http://software.intel.com/en-us/articles/intel-gpa/ "http://software.intel.com/en-us/articles/intel-gpa/")
- Haven\'t tried.
[APITrace](https://github.com/apitrace/apitrace "https://github.com/apitrace/apitrace")
- Open source, works OK.
[PVRTrace](http://www.imgtec.com/powervr/insider/pvrtrace.asp "http://www.imgtec.com/powervr/insider/pvrtrace.asp")
- Doesn\'t seem to emit traces on android/Nexus S. Looks like it\'s
designed for X11-based linux-ARM devices, OMAP3 is mentioned a lot in
the docs \...
## Guides
[Accurately Profiling Direct3D API Calls (Direct3D
9)](http://msdn.microsoft.com/en-us/library/bb172234%28v=vs.85%29.aspx "http://msdn.microsoft.com/en-us/library/bb172234(v=vs.85).aspx")
Suggests avoiding normal profilers like xperf and instead measuring the
time to flush the command buffer.
[OS X - Best Practices for Working with Texture
Data](http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_texturedata/opengl_texturedata.html "http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_texturedata/opengl_texturedata.html")
- Sort of old, but still useful.

Просмотреть файл

@ -0,0 +1,24 @@
# Automated performance testing and sheriffing
We have several test harnesses that test Firefox for various performance
characteristics (page load time, startup time, etc.). We also generate
some metrics as part of the build process (like installer size) that are
interesting to track over time. Currently we aggregate this information
in the [Perfherder web
application](https://wiki.mozilla.org/Auto-tools/Projects/Perfherder)
where performance sheriffs watch for significant regressions, filing
bugs as appropriate.
Current list of automated systems we are tracking (at least to some
degree):
- [Talos](https://wiki.mozilla.org/TestEngineering/Performance/Talos): The main
performance system, run on virtually every check-in to an
integration branch
- [build_metrics](/setup/configuring_build_options.html):
A grab bag of performance metrics generated by the build system
- [AreWeFastYet](https://arewefastyet.com/): A generic JavaScript and
Web benchmarking system
tool
- [Platform microbenchmarks](platform_microbenchmarks/platform_microbenchmarks.md)
- [Build Metrics](build_metrics/build_metrics.md)

Просмотреть файл

@ -0,0 +1,31 @@
# Build Metrics
**Build Metrics** is a catch-all term for performance measures that are
generated by the Firefox build system and tracked by Perfherder.
### num_constructors
Number of static constructors found by the compiler in the Firefox C++
codebase. Lower is better. Static constructors are undesirable because
their initialization imposes an unavoidable time penalty every time
Firefox is started.
### installer size
Size in bytes of the Firefox installer. Lower is better here, especially
on space-restricted platforms like Android.
### build times
Amount of time it takes to build Firefox in automation on a specific
platform / configuration. Lower is better.
### compiler warnings
Number of compiler warnings detected during a build. Lower is better.
Due to the way the build system works, compiler warnings are not
consistently detected. So the value may fluctuate from build to build
even if the number of compiler warnings didn\'t actually change. Since
Perfherder alerts are calculated based on the mean value of a range, a
regression may be reported as a fractional value.

Двоичные данные
docs/performance/img/EJCrt4N.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 324 KiB

Двоичные данные
docs/performance/img/PerfDotHTMLRedLines.PNG Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 8.2 KiB

Двоичные данные
docs/performance/img/reportingperf1.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 10 KiB

Двоичные данные
docs/performance/img/reportingperf2.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 27 KiB

Двоичные данные
docs/performance/img/reportingperf3.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 20 KiB

Просмотреть файл

@ -0,0 +1,21 @@
# Platform microbenchmarks
Platform microbenchmarks benchmarks specific low-level operations used
by the gecko platform. If a test regresses, it could result in the
degradation in the performance of some user-visible feature.
The list of tests and their descriptions is currently incomplete. If
something is missing, please search for it in the gecko source and
update this page (or ask the original author to do so, if you're still
not sure).
## String tests
* PerfStripWhitespace
* PerfCompressWhitespace
* PerfStripCharsWhitespace
* PerfStripCRLF
* PerfStripCharsCRLF
These tests measure the amount of time it takes to perform a large
number of operations on low-level strings.

Просмотреть файл

@ -0,0 +1,94 @@
# Reporting a Performance Problem
This article will guide you in reporting a performance problem using the
built-in Gecko Profiler tool.
## Enabling the Profiler toolbar button
These steps only work in Firefox 75+.
1. Visit [https://profiler.firefox.com/](https://profiler.firefox.com/)
2. Click on *Enable Profiler Menu Button*
3. The profiler toolbar button will show up in the top right of the URL
bar as a small stopwatch icon.
![image1](img/reportingperf1.png)
4. You can right-click on the button and remove it from the toolbar
when you're done with it.
## Using the Profiler
When enabled, the profiler toolbar button is not recording by default.
Recording can be done by clicking on the toolbar icon to open its panel.
Make sure to choose an appropriate setting for the recording (if you\'re
not sure, choose Firefox Platform), and then choosing **Start
Recording**. The toolbar icon turns blue when it is recording.
The profiler uses a fixed size buffer to store sample data. When it runs
out of space in its buffer, it discards old entries so you may want to
increase the buffer size if you find you are unable to capture the
profile quickly enough after you notice a performance problem. If you
choose Custom Settings (and then clicking Edit Settings) for the
profiler, you can adjust the size of the buffer (presently defaults to
90 MB) and the time interval between data collection (presently defaults
to 1 ms). Note that increasing the buffer size uses more memory and can
make capturing a profile take longer.
![image2](img/reportingperf2.png)
Using the keyboard shortcuts is often more convenient than using the
mouse to interact with the UI:
* Ctrl+Shift+1 - Start/Stop the profiler
* Ctrl+Shift+2 - Take a profile and launch the viewer to view it
## Capturing and sharing a profile
1. While the profiler is recording, reproduce the performance problem.
If possible let the problem manifest itself for 5-10 seconds.
2. Press **Ctrl+Shift+2** or click on the profiler toolbar icon in the
top right and select **Capture**. Try to do this within a few
seconds from reproducing the performance problem as only the last
few seconds are recorded. If the timeline has a large red block
it's a good sign. ![Jank markers appearing in the Perf.html profile analysis tool.](img/PerfDotHTMLRedLines.png)
3. The data will open in a new tab. Wait until the \"Symbolicating call
stacks\" notification disappears before sharing the profile.
4. There will be a button in the top right labeled **Publish** which
will allow you to upload this profile and once completed will write
out a link. Before uploading, the publish button asks you what data
you'd like to publish to our servers.
5. Note that while it\'s possible to strip profiles of potentially
privacy sensitive information, the less information a profile
contains, *the harder it is to analyze and turn into actionable
data.*
6. Once uploaded, copy permalink URL to your clipboard by right
clicking and [add the profile URL to a bug](https://bugzilla.mozilla.org/enter_bug.cgi?product=Core&component=Performance)
for your performance problem and/or send it to the appropriate
person. Try to give some context about what you were doing when the
performance problem arose such as the URL you were viewing and what
actions were you doing (ex. scrolling on gmail.com).
![image3](img/reportingperf3.png)
## Viewing addon performance in GeckoView
Sometimes an addon or more are slowing down Firefox. These addons might
be using the extension API in ways that were not meant to. You can see
which of these addons are causing problems by adding the
**moz-extension** filter.
![moz-extension filter print screen](img/EJCrt4N.png)
Make sure you are selecting the process that is using up the CPU since
all of the processes are shown. You might have a content process using
up the CPU and not the main one.
Make sure you are doing whatever it is that slows down Firefox while
recording the profile. For example you might have one addon that slows down page load
and another one that slows down tab switch.
Your first reflex once you find what addon is slowing down the profile
might be to disable it and search for alternatives. Before you do this,
please share the performance profile with the addon authors through a
bug report. Gecko profiler allows you to share a link with the profile.

Просмотреть файл

@ -0,0 +1,177 @@
# Scroll-linked effects
The definition of a scroll-linked effect is an effect implemented on a
webpage where something changes based on the scroll position, for
example updating a positioning property with the aim of producing a
parallax scrolling effect. This article discusses scroll-linked effects,
their effect on performance, related tools, and possible mitigation
techniques.
## Scrolling effects explained
Often scrolling effects are implemented by listening for the `scroll`
event and then updating elements on the page in some way (usually the
CSS
[`position`](/en-US/docs/Web/CSS/position "The position CSS property sets how an element is positioned in a document. The top, right, bottom, and left properties determine the final location of positioned elements.")
or
[`transform`](/en-US/docs/Web/CSS/transform "The transform CSS property lets you rotate, scale, skew, or translate an element. It modifies the coordinate space of the CSS visual formatting model.")
property.) You can find a sampling of such effects at [CSS Scroll API:
Use
Cases](https://github.com/RByers/css-houdini-drafts/blob/master/css-scroll-api/UseCases.md).
These effects work well in browsers where the scrolling is done
synchronously on the browser\'s main thread. However, most browsers now
support some sort of asynchronous scrolling in order to provide a
consistent 60 frames per second experience to the user. In the
asynchronous scrolling model, the visual scroll position is updated in
the compositor thread and is visible to the user before the `scroll`
event is updated in the DOM and fired on the main thread. This means
that the effects implemented will lag a little bit behind what the user
sees the scroll position to be. This can cause the effect to be laggy,
janky, or jittery --- in short, something we want to avoid.
Below are a couple of examples of effects that would not work well with
asynchronous scrolling, along with equivalent versions that would work
well:
### Example 1: Sticky positioning
Here is an implementation of a sticky-positioning effect, where the
\"toolbar\" div will stick to the top of the screen as you scroll down.
``` {.brush: .html}
<body style="height: 5000px" onscroll="document.getElementById('toolbar').style.top = Math.max(100, window.scrollY) + 'px'">
<div id="toolbar" style="position: absolute; top: 100px; width: 100px; height: 20px; background-color: green"></div>
</body>
```
This implementation of sticky positioning relies on the scroll event
listener to reposition the \"toolbar\" div. As the scroll event listener
runs in the JavaScript on the browser\'s main thread, it will be
asynchronous relative to the user-visible scrolling. Therefore, with
asynchronous scrolling, the event handler will be delayed relative to
the user-visible scroll, and so the div will not stay visually fixed as
intended. Instead, it will move with the user\'s scrolling, and then
\"snap\" back into position when the scroll event handler runs. This
constant moving and snapping will result in a jittery visual effect. One
way to implement this without the scroll event listener is to use the
CSS property designed for this purpose:
``` {.brush: .html}
<body style="height: 5000px">
<div id="toolbar" style="position: sticky; top: 0px; margin-top: 100px; width: 100px; height: 20px; background-color: green"></div>
</body>
```
This version works well with asynchronous scrolling because position of
the \"toolbar\" div is updated by the browser as the user scrolls.
### Example 2: Scroll snapping
Below is an implementation of scroll snapping, where the scroll position
snaps to a particular destination when the user\'s scrolling stops near
that destination.
``` {.brush: .html}
<body style="height: 5000px">
<script>
function snap(destination) {
if (Math.abs(destination - window.scrollY) < 3) {
scrollTo(window.scrollX, destination);
} else if (Math.abs(destination - window.scrollY) < 200) {
scrollTo(window.scrollX, window.scrollY + ((destination - window.scrollY) / 2));
setTimeout(snap, 20, destination);
}
}
var timeoutId = null;
addEventListener("scroll", function() {
if (timeoutId) clearTimeout(timeoutId);
timeoutId = setTimeout(snap, 200, parseInt(document.getElementById('snaptarget').style.top));
}, true);
</script>
<div id="snaptarget" class="snaptarget" style="position: relative; top: 200px; width: 100%; height: 200px; background-color: green"></div>
</body>
```
In this example, there is a scroll event listener which detects if the
scroll position is within 200 pixels of the top of the \"snaptarget\"
div. If it is, then it triggers an animation to \"snap\" the scroll
position to the top of the div. As this animation is driven by
JavaScript on the browser\'s main thread, it can be interrupted by other
JavaScript running in other tabs or other windows. Therefore, the
animation can end up looking janky and not as smooth as intended.
Instead, using the CSS snap-points property will allow the browser to
run the animation asynchronously, providing a smooth visual effect to
the user.
``` {.brush: .html}
<body style="height: 5000px">
<style>
body, /* blink currently has bug that requires declaration on `body` */
html {
scroll-snap-type: y proximity;
}
.snaptarget {
scroll-snap-align: start;
position: relative;
top: 200px;
height: 200px;
background-color: green;
}
</style>
<div class="snaptarget"></div>
</body>
```
This version can work smoothly in the browser even if there is
slow-running Javascript on the browser\'s main thread.
### Other effects
In many cases, scroll-linked effects can be reimplemented using CSS and
made to run on the compositor thread. However, in some cases the current
APIs offered by the browser do not allow this. In all cases, however,
Firefox will display a warning to the developer console (starting in
version 46) if it detects the presence of a scroll-linked effect on a
page. Pages that use scrolling effects without listening for scroll
events in JavaScript will not get this warning. See the [Asynchronous
scrolling in Firefox](https://staktrace.com/spout/entry.php?id=834) blog
post for some more examples of effects that can be implemented using CSS
to avoid jank.
## Future improvements
Going forward, we would like to support more effects in the compositor.
In order to do so, we need you (yes, you!) to tell us more about the
kinds of scroll-linked effects you are trying to implement, so that we
can find good ways to support them in the compositor. Currently there
are a few proposals for APIs that would allow such effects, and they all
have their advantages and disadvantages. The proposals currently under
consideration are:
- [Web Animations](https://w3c.github.io/web-animations/): A new API
for precisely controlling web animations in JavaScript, with an
[additional
proposal](https://wiki.mozilla.org/Platform/Layout/Extended_Timelines)
to map scroll position to time and use that as a timeline for the
animation.
- [CompositorWorker](https://docs.google.com/document/d/18GGuTRGnafai17PDWjCHHAvFRsCfYUDYsi720sVPkws/edit?pli=1#heading=h.iy9r1phg1ux4):
Allows JavaScript to be run on the compositor thread in small
chunks, provided it doesn\'t cause the framerate to drop.
- [Scroll
Customization](https://docs.google.com/document/d/1VnvAqeWFG9JFZfgG5evBqrLGDZYRE5w6G5jEDORekPY/edit?pli=1):
Introduces a new API for content to dictate how a scroll delta is
applied and consumed. As of this writing, Mozilla does not plan to
support this proposal, but it is included for completeness.
### Call to action
If you have thoughts or opinions on:
- Any of the above proposals in the context of scroll-linked effects.
- Scroll-linked effects you are trying to implement.
- Any other related issues or ideas.
Please get in touch with us! You can join the discussion on the
[public-houdini](https://lists.w3.org/Archives/Public/public-houdini/)
mailing list.