---
title: Lazy versus eager component loading
slug: '295'
canonical_url: https://docs.coveo.com/en/295/
collection: javascript-search-framework
source_format: adoc
---
# Lazy versus eager component loading
[jsui-new Coveo JavaScript Search Framework v2.4094.8]
If you're implementing a very simple search page using only a fraction of the Coveo JavaScript Search Framework components, you will legitimately expect this page to load faster than a more complex one.
Since the [July 2017 release (v2.2900.23)](https://docs.coveo.com/en/373#july-2017-release-v2290023) of the Coveo JavaScript Search Framework, there are two different ways to load components in a search page: _lazy_ and _eager_ component loading.
While lazy component loading is conceptually more complex than eager component loading, using the former way in a simple implementation can result in linear performance gains during the search page loading process.
These performance gains are especially noticeable on less powerful machines, such as mobile devices.
## Eager component loading
Eager component loading sequentially loads the code of the entire framework before the initialization process of the search page, regardless of whether the page needs the totality of this code or not.
Before the [July 2017 release (v2.2900.23)](https://docs.coveo.com/en/373#july-2017-release-v2290023), this was the only way to load components in the Coveo JavaScript Search Framework.
In the best-case scenario (that is, when a search page uses every component of the framework), this straightforward approach performs as well as lazy component loading.
However, eager component loading can never perform better than lazy component loading.
To use eager component loading in your search page, reference the `CoveoJsSearch` script (not the `CoveoJsSearch.Lazy` script).
**Example**
You can reference the script from your own server:
```xml
[ ... ]
[ ... ]
```
You can also reference the script from the release of your choice (from version `1.2537` on) through the Coveo CDN (see [JavaScript Search Framework CDN links](https://docs.coveo.com/en/2075/)):
```xml
[ ... ]
[ ... ]
```
## Lazy component loading
Lazy component loading makes your search page download only the code of the components it actually requires to work.
Moreover, lazy loading downloads the code of any given component only once.
Consequently, having many instances of a component (such as `Facet`) in a search page has no effect on its initial load time.
Being asynchronous in nature, lazy component loading adds a layer of complexity to a search page.
However, it can also result in linear performance increases for simple search pages.
**Example**
Suppose you implement a very basic search page such as this one:
```xml
```
Eager component loading would download the entire Coveo JavaScript Search Framework code (60+ components) before initialization, even though the search page clearly has no need for most of this code.
Lazy component loading would first scan the page for Coveo components.
It would then only download the code which the `SearchInterface`, `Searchbox`, `ResultList`, and `ResultLink` components require.
This could result in substantial performance improvements, especially for users with slow Internet connections, or less powerful machines, such as mobile devices.
To use lazy component loading in your search page, reference the `CoveoJsSearch.Lazy` script (not the `CoveoJsSearch` script).
**Example**
You can reference the script from your own server:
```xml
[ ... ]
[ ... ]
```
You can also reference the script from the release of your choice (from version 2.2900 on) through the Coveo CDN (see [JavaScript Search Framework CDN links](https://docs.coveo.com/en/2075/)):
```xml
[ ... ]
[ ... ]
```
### Interacting with lazy components
The eager component loading initialization process is synchronous.
This means that once the `Coveo.init` call is made, you can write code that interacts with your search page component instances right away, since all components are necessarily instantiated by then.
When you use lazy component loading in your search page, however, the initialization process is asynchronous.
The page starts by downloading the necessary component code "chunks" as separate threads during the `init` call.
These threads might very well still be ongoing by the time the `init` call is through.
Consequently, you must wait for a component promise to resolve before interacting with an instance of this component.
**Example**
Consider the following markup:
```xml
```
Suppose you only want to collapse the Facet instance whose data-id is yearFacet after the DOM content of the page finishes loading.
If you're using eager component loading in your search page, you could do this right after the `init` call:
```javascript
document.addEventListener('DOMContentLoaded, function() {
[ ... ]
Coveo.init("#search");
// This works consistently with eager component loading.
Coveo.get(Coveo.$$(document).find(".CoveoFacet[data-id='yearFacet']")).collapse();
[ ... ]
)};
```
However, if you're using lazy component loading in your search page, doing so will likely produce an error message such as:
```text
Uncaught TypeError: Cannot read property 'collapse' of undefined
```
The explanation is simple: since the lazy loading initialization process is asynchronous, the `Facet` component might not yet be instantiated when you call its `collapse` method right after the `init` call.
Therefore, you have to wait for the component promise to resolve to make it work.
The `Coveo.load` top-level function allows you to conveniently do so:
```javascript
document.addEventListener('DOMContentLoaded, function() {
[ ... ]
// This works consistently with lazy component loading.
Coveo.load("Facet").then(function(Facet) {
Coveo.get(Coveo.$$(document).find(".CoveoFacet[data-id='yearFacet']")).collapse();
});
[ ... ]
)};
```
### Registering a lazy component
To work on a custom version of an existing component, make sure the lazy component loading process recognizes it.
When you extend an existing component, make sure the necessary code is available first.
This means you have to wait for the "parent" component promise to resolve before you can register a "child" component implementation.
To do so, you should use the `Coveo.LazyInitialization.registerLazyComponent` method.
This method takes two arguments: the ID of the component you want to register, and a function that returns the component implementation when its prerequisite promise resolves.
**Example**
Suppose you want to register a custom `Searchbox` as a lazy component.
You could do so in TypeScript:
```typescript
export interface ICustomSearchboxOptions extends ISearchboxOptions {
title? : string;
size? : number;
isCollapsed? : boolean
};
export function lazyCustomSearchbox() {
// Wait for the 'Searchbox' promise to resolve, then return the 'CustomSearchbox' implementation.
return Coveo.load('Searchbox').then((Searchbox) => {
class CustomSearchbox extends Searchbox {
static ID = 'CustomSearchbox';
static options ICustomSearchboxOptions = _.extend({}, {
title : ComponentOptions.buildStringOption(),
size : ComponentOptions.buildNumberOption({ min : 0 }),
isCollapsed : ComponentOptions.buildBooleanOption({ defaultValue : false })
};
constructor(public element: HTMLElement, public options?: ICustomComponentOptions, bindings?: IComponentBindings) {
super(element, ComponentOptions.initComponentOptions(element, CustomSearchbox, options), bindings);
};
};
Coveo.Initialization.registerAutoCreateComponent(CustomSearchbox);
return CustomSearchbox;
});
};
// Register the 'CustomSearchbox' lazy component using the previously defined function.
Coveo.LazyInitialization.registerLazyComponent('CustomSearchbox', lazyCustomSearchbox);
```
Or, you could achieve the same result in JavaScript:
```javascript
function lazyCustomSearchbox() {
// Wait for the 'Searchbox' promise to resolve, then return the 'CustomSearchbox' implementation.
return Coveo.load('Searchbox').then(function(Searchbox) {
var CustomSearchbox = (function(_super) {
__extends(CustomSearchbox, _super);
function CustomSearchbox(element, options, bindings) {
_super.call(this, element, ComponentOptions.initComponentOptions(element, CustomSearchbox, options), bindings);
this.element = element;
this.options = options;
this.bindings = bindings;
}
CustomSearchbox.ID = 'CustomSearchbox';
CustomSearchbox.options = _extend({}, {
title : ComponentOptions.buildStringOption(),
size : ComponentOptions.buildNumberOption({ min : 0 }),
isCollapsed : ComponentOptions.buildBooleanOption({ defaultValue : false })
}, Coveo.Searchbox.options);
return CustomSearchbox;
}(Searchbox));
Coveo.Initialization.registerAutoCreateComponent(CustomSearchbox);
return CustomSearchbox;
});
}
// Register the 'CustomSearchbox' lazy component using the previously defined function.
Coveo.LazyInitialization.registerLazyComponent('CustomSearchbox', lazyCustomSearchbox);
```
### Fixing code chunks loading path issues
[jsui-new Coveo JavaScript Search Framework v2.4094.8]
In some setups, the framework can't automatically detect the path from which to load the code.
When this issue occurs, the following error appears in the browser console:
`+Cannot load chunk for [ ...
] You may need to add the coveo-script class on the script tag that includes the Coveo framework.+`
As stated in the error message, add the CSS class `coveo-script` on the HTML script element that includes the Coveo framework.
```xml
```
You must do this if the script tag that includes the Coveo script is added dynamically to your page and to support IE11.
This error can also occur when using IE11 and when any script in the page is added dynamically.
> **Note**
>
> In older versions, you will get this error message instead:
>
> `+Cannot load chunk for [ ...
> ] You may need to configure the paths of the resources using Coveo.configureRessourceRoot.
> Current path is [ ...
> ].+`
>
> As stated in the error message, you should use the `Coveo.configureRessourceRoot` function to configure the correct path.
> The path given as a string argument should have a trailing slash (`/`).
> The path can be absolute or relative to the page from which the Coveo script is included.
>
> [example]
> .Example
Suppose your search page has the following directory tree:
* lib
** JSUI
*** CoveoJsSearch.Lazy.min.js
* page - index.html
Depending on the type of path you want to use:
* **Absolute path**: `Coveo.configureRessourceRoot('/lib/JSUI/')`
* **Relative path**: `Coveo.configureRessourceRoot('../lib/JSUI/')`
##### ====