Skip to content

Commit

Permalink
Merge branch 'master' of github.com:elastic/kibana into reporting/add…
Browse files Browse the repository at this point in the history
…-link-to-kibana-app

* 'master' of github.com:elastic/kibana: (61 commits)
  [Logs UI] Fix alert previews for thresholds of `0` (elastic#111150)
  [Archive Migration][Partial] discover apps-discover (elastic#110437)
  [APM] Set start date of APM ML job to -4 weeks (elastic#111375)
  [ML] APM Latency Correlations: Code consolidation. (elastic#110790)
  [Discover] Fix indices permission for multiline test (elastic#111284)
  [Detection Rules] Add 7.15 rules (elastic#111464)
  [Security Solution][Endpoint][Host Isolation] Hide isolate host option in alert details rather than disabling (elastic#111064)
  React version of angular license view (elastic#111317)
  [APM] Fix link in readme (elastic#111362)
  [Security Solution] add agent field to generator (elastic#111428)
  [Dashboard] Retain Tags on Quicksave (elastic#111015)
  Reorder App Search ingestion methods (elastic#111361)
  Port performance docs to new docs system. (elastic#111063)
  [Security Solution][RAC] Fixes updatedAt loading bug (elastic#111010)
  [sample data] update web log geo.src field to match country code of geo.coordinates (elastic#110885)
  [Security solution] [Endpoint] Fix bad artifact migration (elastic#111294)
  Fix copy typo. (elastic#111203)
  [build] Remove empty optimize directory (elastic#111393)
  [Maps] fix term join not updating when editing right field (elastic#111030)
  [Fleet] Set default settings in component template instead of the index template (elastic#111197)
  ...

# Conflicts:
#	x-pack/plugins/reporting/public/management/__snapshots__/report_listing.test.tsx.snap
#	x-pack/plugins/reporting/public/management/report_listing.test.tsx
  • Loading branch information
jloleysens committed Sep 8, 2021
2 parents 99ad93c + 77e25be commit 47aa554
Show file tree
Hide file tree
Showing 464 changed files with 6,674 additions and 4,897 deletions.
106 changes: 106 additions & 0 deletions dev_docs/key_concepts/performance.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
id: kibDevPerformance
slug: /kibana-dev-docs/performance
title: Performance
summary: Performance tips for Kibana development.
date: 2021-09-02
tags: ['kibana', 'onboarding', 'dev', 'performance']
---

## Keep Kibana fast

*tl;dr*: Load as much code lazily as possible. Everyone loves snappy
applications with a responsive UI and hates spinners. Users deserve the
best experience whether they run Kibana locally or
in the cloud, regardless of their hardware and environment.

There are 2 main aspects of the perceived speed of an application: loading time
and responsiveness to user actions. Kibana loads and bootstraps *all*
the plugins whenever a user lands on any page. It means that
every new application affects the overall _loading performance_, as plugin code is
loaded _eagerly_ to initialize the plugin and provide plugin API to dependent
plugins.

However, it’s usually not necessary that the whole plugin code should be loaded
and initialized at once. The plugin could keep on loading code covering API functionality
on Kibana bootstrap, but load UI related code lazily on-demand, when an
application page or management section is mounted.
Always prefer to import UI root components lazily when possible (such as in `mount`
handlers). Even if their size may seem negligible, they are likely using
some heavy-weight libraries that will also be removed from the initial
plugin bundle, therefore, reducing its size by a significant amount.

```ts
import type { Plugin, CoreSetup, AppMountParameters } from 'kibana/public';
export class MyPlugin implements Plugin<MyPluginSetup> {
setup(core: CoreSetup, plugins: SetupDeps) {
core.application.register({
id: 'app',
title: 'My app',
async mount(params: AppMountParameters) {
const { mountApp } = await import('./app/mount_app');
return mountApp(await core.getStartServices(), params);
},
});
plugins.management.sections.section.kibana.registerApp({
id: 'app',
title: 'My app',
order: 1,
async mount(params) {
const { mountManagementSection } = await import('./app/mount_management_section');
return mountManagementSection(coreSetup, params);
},
});
return {
doSomething() {},
};
}
}
```

### Understanding plugin bundle size

Kibana Platform plugins are pre-built with `@kbn/optimizer`
and distributed as package artifacts. This means that it is no
longer necessary for us to include the `optimizer` in the
distributable version of Kibana Every plugin artifact contains all
plugin dependencies required to run the plugin, except some
stateful dependencies shared across plugin bundles via
`@kbn/ui-shared-deps`. This means that plugin artifacts _tend to
be larger_ than they were in the legacy platform. To understand the
current size of your plugin artifact, run `@kbn/optimizer` with:

```bash
node scripts/build_kibana_platform_plugins.js --dist --profile --focus=my_plugin
```

and check the output in the `target` sub-folder of your plugin folder:

```bash
ls -lh plugins/my_plugin/target/public/
# output
# an async chunk loaded on demand
... 262K 0.plugin.js
# eagerly loaded chunk
... 50K my_plugin.plugin.js
```

You might see at least one js bundle - `my_plugin.plugin.js`. This is
the _only_ artifact loaded by Kibana during bootstrap in the
browser. The rule of thumb is to keep its size as small as possible.
Other lazily loaded parts of your plugin will be present in the same folder as
separate chunks under `{number}.myplugin.js` names. If you want to
investigate what your plugin bundle consists of, you need to run
`@kbn/optimizer` with `--profile` flag to generate a
[webpack stats file](https://webpack.js.org/api/stats/).

```bash
node scripts/build_kibana_platform_plugins.js --dist --no-examples --profile
```

Many OSS tools allow you to analyze the generated stats file:

* [An official tool](https://webpack.github.io/analyse/#modules) from
Webpack authors
* [webpack-visualizer](https://chrisbateman.github.io/webpack-visualizer/)
* [webpack-bundle-analyzer](https://github.com/webpack-contrib/webpack-bundle-analyzer)
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-public](./kibana-plugin-core-public.md) &gt; [ChromeStart](./kibana-plugin-core-public.chromestart.md) &gt; [hasHeaderBanner$](./kibana-plugin-core-public.chromestart.hasheaderbanner_.md)

## ChromeStart.hasHeaderBanner$() method

Get an observable of the current header banner presence state.

<b>Signature:</b>

```typescript
hasHeaderBanner$(): Observable<boolean>;
```
<b>Returns:</b>

`Observable<boolean>`

Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ core.chrome.setHelpExtension(elem => {
| [getHelpExtension$()](./kibana-plugin-core-public.chromestart.gethelpextension_.md) | Get an observable of the current custom help conttent |
| [getIsNavDrawerLocked$()](./kibana-plugin-core-public.chromestart.getisnavdrawerlocked_.md) | Get an observable of the current locked state of the nav drawer. |
| [getIsVisible$()](./kibana-plugin-core-public.chromestart.getisvisible_.md) | Get an observable of the current visibility state of the chrome. |
| [hasHeaderBanner$()](./kibana-plugin-core-public.chromestart.hasheaderbanner_.md) | Get an observable of the current header banner presence state. |
| [setBadge(badge)](./kibana-plugin-core-public.chromestart.setbadge.md) | Override the current badge |
| [setBreadcrumbs(newBreadcrumbs)](./kibana-plugin-core-public.chromestart.setbreadcrumbs.md) | Override the current set of breadcrumbs |
| [setBreadcrumbsAppendExtension(breadcrumbsAppendExtension)](./kibana-plugin-core-public.chromestart.setbreadcrumbsappendextension.md) | Mount an element next to the last breadcrumb |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ readonly links: {
readonly apm: {
readonly kibanaSettings: string;
readonly supportedServiceMaps: string;
readonly customLinks: string;
readonly droppedTransactionSpans: string;
readonly upgrading: string;
readonly metaData: string;
};
readonly canvas: {
Expand Down

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/maps/maps-getting-started.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ and lighter shades will symbolize countries with less traffic.

. In **Statistics source**, set:
** **Index pattern** to **kibana_sample_data_logs**
** **Join field** to **geo.src**
** **Join field** to **geo.dest**

. Click **Add layer**.

. In **Layer settings**, set:

** **Name** to `Total Requests by Country`
** **Name** to `Total Requests by Destination`
** **Opacity** to 50%

. Add a Tooltip field:
Expand Down
4 changes: 2 additions & 2 deletions packages/kbn-optimizer/limits.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pageLoadAssetSize:
indexPatternManagement: 28222
indexPatternEditor: 25000
infra: 184320
fleet: 465774
fleet: 250000
ingestPipelines: 58003
inputControlVis: 172675
inspector: 148711
Expand Down Expand Up @@ -112,7 +112,7 @@ pageLoadAssetSize:
expressionImage: 19288
expressionMetric: 22238
expressionShape: 34008
interactiveSetup: 70000
interactiveSetup: 80000
expressionTagcloud: 27505
expressions: 239290
securitySolution: 231753
2 changes: 2 additions & 0 deletions src/core/public/chrome/chrome_service.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const createStartContractMock = () => {
getCustomNavLink$: jest.fn(),
setCustomNavLink: jest.fn(),
setHeaderBanner: jest.fn(),
hasHeaderBanner$: jest.fn(),
getBodyClasses$: jest.fn(),
};
startContract.navLinks.getAll.mockReturnValue([]);
Expand All @@ -65,6 +66,7 @@ const createStartContractMock = () => {
startContract.getHelpExtension$.mockReturnValue(new BehaviorSubject(undefined));
startContract.getIsNavDrawerLocked$.mockReturnValue(new BehaviorSubject(false));
startContract.getBodyClasses$.mockReturnValue(new BehaviorSubject([]));
startContract.hasHeaderBanner$.mockReturnValue(new BehaviorSubject(false));
return startContract;
};

Expand Down
13 changes: 13 additions & 0 deletions src/core/public/chrome/chrome_service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,19 @@ describe('start', () => {
});
});

describe('header banner', () => {
it('updates/emits the state of the header banner', async () => {
const { chrome, service } = await start();
const promise = chrome.hasHeaderBanner$().pipe(toArray()).toPromise();

chrome.setHeaderBanner({ content: () => () => undefined });
chrome.setHeaderBanner(undefined);
service.stop();

await expect(promise).resolves.toEqual([false, true, false]);
});
});

describe('erase chrome fields', () => {
it('while switching an app', async () => {
const startDeps = defaultStartDeps([new FakeApp('alpha')]);
Expand Down
7 changes: 7 additions & 0 deletions src/core/public/chrome/chrome_service.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,13 @@ export class ChromeService {
headerBanner$.next(headerBanner);
},

hasHeaderBanner$: () => {
return headerBanner$.pipe(
takeUntil(this.stop$),
map((banner) => Boolean(banner))
);
},

getBodyClasses$: () => bodyClasses$.pipe(takeUntil(this.stop$)),
};
}
Expand Down
5 changes: 5 additions & 0 deletions src/core/public/chrome/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,11 @@ export interface ChromeStart {
* @remarks Using `undefined` when invoking this API will remove the banner.
*/
setHeaderBanner(headerBanner?: ChromeUserBanner): void;

/**
* Get an observable of the current header banner presence state.
*/
hasHeaderBanner$(): Observable<boolean>;
}

/** @internal */
Expand Down
6 changes: 6 additions & 0 deletions src/core/public/doc_links/doc_links_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ export class DocLinksService {
apm: {
kibanaSettings: `${KIBANA_DOCS}apm-settings-in-kibana.html`,
supportedServiceMaps: `${KIBANA_DOCS}service-maps.html#service-maps-supported`,
customLinks: `${KIBANA_DOCS}custom-links.html`,
droppedTransactionSpans: `${APM_DOCS}get-started/${DOC_LINK_VERSION}/transaction-spans.html#dropped-spans`,
upgrading: `${APM_DOCS}server/${DOC_LINK_VERSION}/upgrading.html`,
metaData: `${APM_DOCS}get-started/${DOC_LINK_VERSION}/metadata.html`,
},
canvas: {
Expand Down Expand Up @@ -460,6 +463,9 @@ export interface DocLinksStart {
readonly apm: {
readonly kibanaSettings: string;
readonly supportedServiceMaps: string;
readonly customLinks: string;
readonly droppedTransactionSpans: string;
readonly upgrading: string;
readonly metaData: string;
};
readonly canvas: {
Expand Down
4 changes: 4 additions & 0 deletions src/core/public/public.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ export interface ChromeStart {
getHelpExtension$(): Observable<ChromeHelpExtension | undefined>;
getIsNavDrawerLocked$(): Observable<boolean>;
getIsVisible$(): Observable<boolean>;
hasHeaderBanner$(): Observable<boolean>;
navControls: ChromeNavControls;
navLinks: ChromeNavLinks;
recentlyAccessed: ChromeRecentlyAccessed;
Expand Down Expand Up @@ -476,6 +477,9 @@ export interface DocLinksStart {
readonly apm: {
readonly kibanaSettings: string;
readonly supportedServiceMaps: string;
readonly customLinks: string;
readonly droppedTransactionSpans: string;
readonly upgrading: string;
readonly metaData: string;
};
readonly canvas: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ describe('migration v2', () => {
await root.setup();
await expect(root.start()).resolves.toBeTruthy();

await new Promise((resolve) => setTimeout(resolve, 1000));
// After plugins start, some saved objects are deleted/recreated, so we
// wait a bit for the count to settle.
await new Promise((resolve) => setTimeout(resolve, 5000));

const esClient: ElasticsearchClient = esServer.es.getClient();
const migratedIndexResponse = await esClient.count({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@

import { retryAsync } from './retry_async';

// FLAKY: https://github.com/elastic/kibana/issues/110970
describe.skip('retry', () => {
describe('retry', () => {
it('retries throwing functions until they succeed', async () => {
let i = 0;
await expect(
Expand Down Expand Up @@ -53,6 +52,8 @@ describe.skip('retry', () => {
},
{ retryAttempts: 3, retryDelayMs: 100 }
);
expect(Date.now() - now).toBeGreaterThanOrEqual(200);
// Would expect it to take 200ms but seems like timing inaccuracies
// sometimes causes the duration to be measured as 199ms
expect(Date.now() - now).toBeGreaterThanOrEqual(199);
});
});
2 changes: 0 additions & 2 deletions src/core/server/saved_objects/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import { registerUpdateRoute } from './update';
import { registerBulkGetRoute } from './bulk_get';
import { registerBulkCreateRoute } from './bulk_create';
import { registerBulkUpdateRoute } from './bulk_update';
import { registerLogLegacyImportRoute } from './log_legacy_import';
import { registerExportRoute } from './export';
import { registerImportRoute } from './import';
import { registerResolveImportErrorsRoute } from './resolve_import_errors';
Expand Down Expand Up @@ -50,7 +49,6 @@ export function registerRoutes({
registerBulkGetRoute(router, { coreUsageData });
registerBulkCreateRoute(router, { coreUsageData });
registerBulkUpdateRoute(router, { coreUsageData });
registerLogLegacyImportRoute(router, logger);
registerExportRoute(router, { config, coreUsageData });
registerImportRoute(router, { config, coreUsageData });
registerResolveImportErrorsRoute(router, { config, coreUsageData });
Expand Down

This file was deleted.

23 changes: 0 additions & 23 deletions src/core/server/saved_objects/routes/log_legacy_import.ts

This file was deleted.

Loading

0 comments on commit 47aa554

Please sign in to comment.