Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[rfc][skip-ci] Screenshot Mode Service #93496

Merged
merged 16 commits into from
Apr 14, 2021
Merged
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 152 additions & 0 deletions rfcs/text/0009_screenshot_mode_service.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
- Start Date: 2020-03-02
- RFC PR: (leave this empty)
- Kibana Issue: (leave this empty)

# Summary
tsullivan marked this conversation as resolved.
Show resolved Hide resolved

Applications should be aware when their UI is rendered for purposes of
capturing a screenshot. This ability would improve the quality of the Kibana
Reporting feature for a few reasons:
- Fewer objects in the headless browser memory since interactive code doesn't run
- Fewer Reporting bugs in releases since App teams have more ownership and
control over the reportability of their UI

Currently, the applications that support screenshot reports are:
- Dashboard
- Visualize Editor
- Canvas

**Screenshot mode service**

Applications in Kibana should be aware of when their rendering is for a human
user using the page interactively, and when it's not. At a high level, the application
can support that awareness through a customized URL for screenshot reports. Canvas
demonstrates a great implementation of this today. However, Canvas has dependencies
on other UI plugins, and can not control how they render or what type of network requests
they send. Those plugins, and lower-level plugins that run on every page, do not have
a way to control themselves when the page is rendering for taking a screenshot.

This RFC proposes a Screenshot Mode Service as a low-level plugin that allows
other plugins (UI code) to make choices when the page is rendering for a screenshot.

In most cases, the information coming from this service would help the UI code
decide what should **not** be loaded: for example, the NewsFeed component and
Telemetry code should not load itself when the page is rendering for
screenshots.

More background on how Reporting currently works, including the lifecycle of
creating a PNG report, is here: https://github.com/elastic/kibana/issues/59396

# Basic example

When Kibana loads initially, there is a Newsfeed component in the UI that
checks internally cached records to see if it must fetch the Elastic News
Service for newer items. When the Screenshot Mode Service is implemented, the
Newsfeed component has a source of information to check on whether or not it
should load in the Kibana UI. If it can avoid loading, it avoids an unnecessary
HTTP round trip, which weigh heavily on performance.
ppisljar marked this conversation as resolved.
Show resolved Hide resolved

# Motivation

Kibana Reporting is a commercial feature in Elastic and is highly capable of
loading the application pages and converting them into a screenshot for PNG or
PDF export. However, the way it works has downsides with performance,
maintainability, and expanding it as a tool that can power higher-level
features. The solution to those downsides is to have Kibana pages themselves
become more capable at presenting themselves for screenshot capture reports.
With the Screenshot Mode Service available, Reporting could drop the
task that it currently has which hurt performance: wasted rendering that is
replaced with custom styles that make the page "reportable."

The technical advantage of having such as service also leads to making Kibana
application pages "printable", in the sense that sending the page to a printer
for a hard copy results in something more meaningful and specialized for paper
than today's Kibana can guarantee. This isn't a big concern for Kibana since
there isn't the expectation to improve printing Kibana, but that technical
direction is appropriate for improving PDF report generation.

# Detailed design

The Screenshot Mode Service is a callable API available as dependency for
Kibana applications.
tsullivan marked this conversation as resolved.
Show resolved Hide resolved

A method of the API tells the Application whether or not it should render
itself to optimize for non-interactivity.

In a future phase, the API might also tell the application more about the
report, such as PDF page dimensions, or special layout types (print layout,
etc).

## Interface
The `setupDeps.screenshotMode` object has a single purpose: tell the app if it
tsullivan marked this conversation as resolved.
Show resolved Hide resolved
should render in an optimized way for screenshot capture:

```
interface IScreenshotModeServiceSetup {
isScreenshotMode: () => boolean;
}
```

Internally, this object is constructed from a class that refers to information
sent via a custom proprietary header:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we add a possibility of enabling this thru url parameter ? (for easier testing)


```
interface HeaderData {
'X-Screenshot-Mode': true
}

class ScreenshotModeServiceSetup implements IScreenshotModeServiceSetup {
constructor(rawData: HeaderData) {}
public isScreenshotMode (): boolean {}
}
```

This works because the headless browser that opens the page can inject custom
headers into the request. Teams can test how their app renders when loaded with
this header using a new configuration setting, or a web debugging proxy, or
some other tool that is TBD.

# Alternatives

- Print media query CSS
If applications UIs supported printability using `@media print`, and Kibana
tsullivan marked this conversation as resolved.
Show resolved Hide resolved
Reporting uses `page.print()` to capture the PDF, it would be easy for application
developers to test, and prevent bugs showing up in the report.

However, this proposal only provides high-level customization over visual rendering, which the
application already has if it uses a customized URL for rendering the layout for screenshots. It
has a performance downside, as well: the headless browser still has to render the entire
page as a "normal" render before we can call `page.print()`. No one sees the
results of that initial render, so it is the same amount of wasted rendering cycles
during report generation that we have today.

# Adoption strategy
tsullivan marked this conversation as resolved.
Show resolved Hide resolved

Using this service doesn't mean that anything needs to be replaced or thrown away. It's an add on
that any plugin or even application can use to add conditionals that previously weren't possible.
The Reporting Services team should create an example in a developer example plugin on how to build
a UI that is aware of Screenshot Mode Service. From there, the team would work on updating
whichever code that would benefit from this the most, which we know from analyzing debugging logs
of a report job. The team would work across teams to get it accepted by the owners.

# How we teach this

The Reporting Services team will continue to analyze debug logs of reporting jobs to find if there
is UI code running during a report job that could be optimized by this service. The team would
reach out to the code owners and determine if it makes sense to use this service to improve
screenshot performance of their code.

# Further examples

- Applications can also use screenshot context to customize the way they load.
An example is Toast Notifications: by default they auto-dismiss themselves
after 30 seconds or so. That makes sense when there is a human there to
notice the message, read it and remember it. But if the page is loaded for
capturing a screenshot, the toast notifications should never disappear. The
message in the toast needs to be part of the screenshot for its message to
mean anything, so it should not force the screenshot capture tool to race
against the toast timeout window.
- Avoid collection and sending of telemetry from the browser when page is
loaded for screenshot capture.
tsullivan marked this conversation as resolved.
Show resolved Hide resolved
- Turn off autocomplete features and auto-refresh features that weigh on
performance for screenshot capture.