- Qt 6.11
- Qt Qml
- Advanced QML Topics
- The QML Disk Cache
- Qt 6.11.2 Reference Documentation

Advanced QML Topics ◦ Configuring the JavaScript Engine

# The QML Disk Cache

To achieve optimal performance, QML documents are either pre-compiled ahead of time during the build process or cached after compilation at runtime. This page describes both strategies and how to configure the caching behavior.

## Ahead-of-Time Compilation

You should define your QML modules using qt_add_qml_module that makes sure the Qt Quick Compiler processes your QML and JavaScript files ahead of time. This guarantees optimum performance at run time.

The Qt Quick Compiler generates byte code for each function and binding. This byte code can be used by the QML interpreter and the Just-in-Time (JIT) compiler in the QML engine. In addition, the Qt Quick Compiler generates native code for suitable functions and bindings. The native code is executed directly, which results in better performance than interpreting or just-in-time compiling byte code. Both byte code and native code are then compiled into your application binary.

One benefit of ahead-of-time compilation is that syntax errors in your QML documents are detected at application compile-time instead of at run-time when the file is loaded.

### With CMake

When using CMake with qt_add_qml_module, QML files are automatically compiled ahead of time. You should load your QML documents from the resource file system where possible. This ensures the QML engine can find the code compiled ahead of time.

### With qmake

When using qmake, you can enable ahead-of-time compilation by specifying `CONFIG += qtquickcompiler` in your project file. Qt Creator has a setting that allows passing this directive to the qmake command line. By default, it is enabled for release and profile builds.

When using qmake, you must organize your project in a specific way:

- All QML documents (including JavaScript files) must be included as resources via Qt's Resource system.
- Your application must load the QML documents via the `qrc:///` URL scheme.

Note that qmake cannot pass as much information to the Qt Quick Compiler as CMake. Therefore, the compilation will contain less native code.

## Runtime Disk Caching

If no pre-compiled code is found at run time, or if the code cannot be used, the QML engine compiles QML documents into a byte code representation on the fly. Instead of re-compiling the same document each time it is loaded, the QML engine caches the compiled byte code. The caching process is automatic: each time you load a changed QML document, the cache is automatically re-created.

### Cache File Format and Location

Cache files use the following extensions:

- `.qmlc` for compiled QML documents
- `.jsc` for imported JavaScript files
- `.mjsc` for ECMAScript modules

Cache files are located in a subdirectory named `qmlcache` of the system's cache directory, as denoted by QStandardPaths::CacheLocation.

### Memory Efficiency

Cache files are loaded via the `mmap()` system call on POSIX-compliant operating systems or `CreateFileMapping()` on Windows. This memory-mapping approach results in significant memory savings. In addition, when multiple applications use the same QML document, the memory needed for the code is shared between application processes, further reducing memory overhead.

## Cache Validation

Cache files and ahead-of-time compiled code are only loaded if all of the following conditions are met:

- The Qt version has not changed
- The source code in the original file has not changed
- The QML debugger is not running

Note that `QML_FORCE_DISK_CACHE` (see below) can override the QML debugger condition. The other environment variables do not influence these validation conditions.

### Validation of ahead of time generated native code

The native code generated by the Qt Quick Compiler has some assumptions built in. If the conditions in which the code is executed differ from those in which it was compiled, the code may be unsafe to use. Therefore, the native code is validated at runtime using metadata stored alongside it. If this validation passes, the code is executed as normal. If it fails, the execution silently falls back to interpreting the bytecode instead. This validation happens once per file, the first time the code is loaded, and either approves or rejects all functions and bindings in that QML file as a whole.

You can customize the validation of AOT code:

- To disable the validation at runtime, set the `QV4_SKIP_AOT_VALIDATION` environment variable. This allows you to avoid paying the small overhead of performing the validation.

       QV4_SKIP_AOT_VALIDATION=1 ./myQmlApp

- To ensure that validation succeeds at runtime, set the `QV4_FAIL_ON_INVALID_AOT` environment variable. If validation fails, the program is terminated. This allows you to make sure compiled functions are indeed executed as native code, for example.

       QV4_FAIL_ON_INVALID_AOT=1 ./myQmlApp

- To disable the feature completely and prevent the Qt Quick Compiler from generating the metadata and validation logic, pass `NO_GENERATE_AOT_VALIDATION` to qt_add_qml_module.

       qt_add_qml_module(... NO_GENERATE_AOT_VALIDATION)

## Configuration

You can fine-tune caching behavior using the environment variable `QML_DISK_CACHE`, which takes a comma-separated list of options. For example:

     QML_DISK_CACHE=aot,qmlc-read

The available options are as follows:

Option | Description
--- | ---
aot-native | Load the compilation units compiled ahead of time and allow execution of any native code found in them.
aot-bytecode | Load the compilation units compiled ahead of time and allow interpretation and just-in-time compilation of byte code found in them.
aot | Shorthand for `aot-native,aot-bytecode`.
qmlc-read | Load any cached compilation units for QML and JavaScript files from the host file system and allow interpretation and just-in-time compilation of byte code found in them.
qmlc-write | When compiling a QML or JavaScript file on the fly, create a cache file afterward. The cache file can be loaded when the same document is requested again.
qmlc | Shorthand for `qmlc-read,qmlc-write`.

Furthermore, you can use the following environment variables:

Environment Variable | Description
--- | ---
`QML_DISABLE_DISK_CACHE` | Disables the disk cache and forces re-compilation from source for all QML and JavaScript files. `QML_DISABLE_DISK_CACHE` overrides `QML_DISK_CACHE`.
`QML_FORCE_DISK_CACHE` | Enables the disk cache even when debugging QML. You cannot use the JavaScript debugger this way. It may fail to stop at breakpoints, for example. You can still use the QML inspector to explore the object hierarchy, though. `QML_FORCE_DISK_CACHE` overrides `QML_DISABLE_DISK_CACHE` and `QML_DISK_CACHE`.
`QML_DISK_CACHE_PATH` | Specifies a custom location where the cache files shall be stored instead of using the default location.

Advanced QML Topics ◦ Configuring the JavaScript Engine