UI Plugins Lazy Loading

To improve the interaction time for the user, there is a mechanism that allows
to use lazy loading for plugins in MediaCentral Cloud | UX.

To apply lazy loading to your plugin, describe your plugin properly in package.json.

Features

The plugin’s package.json contains an avid section that provides information about the UI plugin dependencies, format, registration, etc.

Add the features property to describe the plugin’s exported and required features and which features are extended by the plugin.

This data will be used to build a dependency tree for each application.
Lazy loading uses the application as starting point of its algorithm.

Example: The plugin provides an app my-app and requires some-api defined in another plugin:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"avid": {
"format": "amd",
"main": "index.js",
"alias": "alias",
"features": {
"provides": [
{
"apps": [
{
"name": "my-app"
}
]
}
],
"requires": [
{
"some-api": "*"
}
]
}
}
}

provides

To guarantee that plugins that require features provided by your plugin are loaded with your plugin at the same time, describe all features exported from your plugin as avid features.

Example:
index.js

1
2
3
4
5
6
7
export const avid = [{
name: 'my-app',
provides: ['appViews'],
create: () => {
//
}
}]

package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"avid": {
"format": "amd",
"main": "index.js",
"alias": "my-app-alias-f5bf272966436ea6c1e3bcf83dcaf6",
"features": {
"provides": [
{
"appViews": [
{
"name": "my-view"
}
]
}
]
}
}
}

You can omit the plugin export description if features are supposed to be private (features that should not be extended
or reused by other plugins).

For example, if there is a view that is used only by your app in the same plugin and you do not allow adding actions
to your view or using this view in another plugin, you can omit the view description in the provides section.

Providing Applications

The application description must contain data about the menu icon and additional configuration.

Note: Since icons are shown and apps can be opened with a loading indicator before source loading is completed,
it is important to add an application description to the features section.

Properties to specify:

  • config

    • rightZone
    • title
    • allowedContext
    • preload
  • menuIcon

    • group
    • orderInGroup
    • gradient: feature.menuIcon.gradient,
    • icon
    • visible

Do not specify inspectorConfig in your package.json. It will be applied after application is fully loaded.

Note: Starting with v2020.4, the property title is added to config.
This property is an object with key-value pairs
where key matches one of the supported languages and value is the localized title.

Example:

"title": {
    "en": "Browse",
    "ru": "Обзор"
}

Note: Starting with v2020.4, the property preload is added to config.

Default: true

This property is used to postpone plugin loading to the moment when it is actually in use.
If you know that your plugins shouldn’t be loaded on MediaCentral Cloud | UX initial loading, you should set preload to false.

Use AV.internal.getPackageJsonMetaData (see below) to receive the app description.

Example:

"features": {
            "provides": {
                "apps": [{
                    "name": "browse",
                    "config": {
                        "id": "browse",
                        "dockable": true,
                        "inspector": false,
                        "title": {
                            "en": "Browse",
                            "ru": "Обзор"
                        },
                        "allowedContext": "none"
                    },
                    "menuIcon": {
                        "group": 100,
                        "orderInGroup": 200,
                        "gradient": ["var(--gradients-gradient01_start)", "var(--gradients-gradient01_end)"],
                        "icon": "data:image/svg+xml;charset=utf8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 24 24' enable-background='new 0 0 24 24' xml:space='preserve'%3E %3Cg%3E %3Cg%3E %3Cpath d='M12,7l-2-2H4v2v1v11h16V7H12z M19,18H5V8h8h6V18z'/%3E %3C/g%3E %3C/g%3E %3C/svg%3E"
                    }
                }],
                ... 

requires

Specify all your dependencies in the requires property.
To guarantee that your plugin is loaded with all its dependencies, describe the requires section of your features in avid exports and also hidden dependencies, such as views that are used in the application layout configuration.

index.js

1
2
3
4
5
6
7
8
export const avid = [{
name: 'my-app',
requires: {'asset-editor-api': '1'},
provides: ['appViews'],
create: () => {
//
}
}]

app.js

1
2
3
4
5
6
7
...
getLayoutConfig() {
return {
type: 'my-view-from-another-plugin',
};
}
...

package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
"avid": {
"format": "amd",
"main": "index.js",
"alias": "my-app-alias-f5bf272966436ea6c1e3bcf83dcaf6",
"features": {
"provides": [
{
"apps": [
{
"name": "my-app"
}
]
}
],
"requires": [
{
"assetor-editor-api": "1"
},
{
"appViews": [
{
"name": "my-view-from-another-plugin"
}
]
}
]
}
}
}

extends

Specify all features that are extended by features provided by your plugin.

If the plugin provides an action bound to a view that is contained in another plugin, add the extends property:

Example:

1
2
3
4
5
6
7
8
9
10
export default {
places: ['contextMenu', 'viewMenu'],
filter: 'others-plugin-view',
defaults: {
index: 500,
},
menuModelProvider: () => [
{ actionId: 'my-action' },
]
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
"avid": {
"format": "amd",
"main": "index.js",
"alias": "avid-ui-user-settings-43f5bf272966436ea6c1e3bcf83dcaf6",
"features": {
"provides": [
{
"actions": [
{
"name": "my-action"
}
],
"actionBindings": [
{
"name": "my-action-bindings"
}
]
}
],
"extends": [
{
"appViews": [{ "name": "others-plugin-view" }]
}
]
}
}
}

Helpers

Validating package.json

To validate that your plugin’s package.json is correct, use plugin-package.schema.json.
Numerous IDEs allow to specify the schema file to validate your JSON files.

Getting the Raw package.json Features Metadata

Note: This feature is only for getting prepared raw data.
You must check and analyze the data before including it in your plugin’s package.json.

When your application is loaded, open the browser developer tools,
then the “Console“ tab and call the AV.internal.getPackageJsonMetaData method.

Note: If your application is an admin app, you need to be logged in as an administrator.

AV.internal.getPackageJsonMetaData(pluginName, toString)
  • pluginName: String
    • Plugin name.
  • toString: Boolean
    • (optional) False to allow returning an object, true to allow returning a string (defaults to true).

Tip: If in doubt regarding the plugin name, check the path from where your plugin is loaded.
See the following example for the Browse app:

/plugins/core-app/plugins/avid-mcux-browse/index.js

In this case, the pluginName is avid-mcux-browse.

1
AV.internal.getPackageJsonMetaData('avid-mcux-browse', false);

Result example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
{
"features": {
"provides": {
"appViews": [{
"name": "app-name"
}],
"actions": [{
"name": "action.name"
}],
"apps": [{
"name": "app",
"config": {
"id": "app",
"title": {
"en": "Browse"
},
"allowedContext": {
"excludeTypes": "folder-item",
"mimeType": "text/x.avid.location-item-list"
}
},
"menuIcon": {
"group": 100,
"orderInGroup": 200,
"gradient": ["#fff", "#fff"],
"icon": "icon in base 64"
}
}]
},
"requires": [{
"attributeFormatter": "1"
}],
"extends": {
"appViews": [{
"name": "app-view-name"
}]
}
}
}

Each application can have specific ‘features’.
When a property is undefined, you can remove it from the result (like “hideInspector” in the example above).

After getting this data, compare it with your avid feature configuration
and add it to your package.json file (see the examples above in this article).

If the result is a string (toString = true), you can convert it to a JSON object with any
online converter. For example: jsbeautifier

Caution: This is raw data that needs to be checked before using.
Pay attention to the requires block, because not all required features might be included here.

Checking the Size of Loaded Plugins

As described above, lazy loading uses the application as starting point of its algorithm.
You can check which plugins should be loaded for each app and the size of the plugins by using the following developer utility in runtime:

AV.internal.getPluginsListForApp(appId)

Example:

AV.internal.getPluginsListForApp('avid-user-settings-app')
AV.internal.getPluginsListForApp('browse')

Use this method after you open and see the application on the screen.

Note: This is not a public API, but a utility method that is used only for informational purpose. It can be removed or changed in the future.