本页内容

QML 磁盘缓存

为了实现最佳性能,QML 文档会在构建过程中预先编译,或者在运行时编译后进行缓存。本页介绍了这两种策略以及如何配置缓存行为。

预编译

您应使用qt_add_qml_module定义 QML 模块,以确保 Qt Quick Compiler 会预先处理您的 QML 和 JavaScript 文件。这可确保在运行时获得最佳性能。

该 Qt Quick Compiler 会为每个函数和绑定生成字节码。QML引擎中的QML解释器和即时(JIT)编译器均可使用该字节码。此外, Qt Quick Compiler 还会为合适的函数和绑定生成本机代码。本机代码可直接执行,其性能优于解释或即时编译字节码。随后,字节码和本机代码都会被编译到应用程序二进制文件中。

预编译的一大优势在于,QML文档中的语法错误会在应用程序编译时被检测到,而不是在运行时加载文件时才被发现。

使用 CMake

当使用 CMake 配合qt_add_qml_module 时,QML 文件会自动进行预编译。建议尽可能从资源文件系统加载 QML 文档,以确保 QML 引擎能够找到已预编译的代码。

使用 qmake

使用qmake 时,您可以在项目文件中指定 `CONFIG += qtquickcompiler ` 来启用预编译。 Qt Creator 该工具提供了一项设置,允许将此指令传递给 qmake 命令行。默认情况下,该功能在发布版和性能优化版构建中处于启用状态。

使用 qmake 时,必须按特定方式组织项目:

  • 所有 QML 文档(包括 JavaScript 文件)都必须通过Qt 的资源系统作为资源包含进来。
  • 您的应用程序必须通过qrc:/// URL 方案加载 QML 文档。

请注意,qmake无法像 Qt Quick Compiler 。因此,生成的编译结果中包含的原生代码会较少。

运行时磁盘缓存

如果在运行时找不到预编译的代码,或者无法使用该代码,QML 引擎会即时将 QML 文档编译成字节码表示形式。QML 引擎不会在每次加载同一文档时都重新编译,而是将编译后的字节码缓存起来。 缓存过程是自动进行的:每次加载已更改的 QML 文档时,缓存都会自动重建。

缓存文件格式与位置

缓存文件使用以下扩展名:

  • .qmlc 针对已编译的 QML 文档
  • .jsc 用于导入的 JavaScript 文件
  • .mjsc 用于 ECMAScript 模块

缓存文件位于系统缓存目录下的一个名为qmlcache 的子目录中,该目录由QStandardPaths::CacheLocation 指定。

内存效率

在符合 POSIX 标准的操作系统上,缓存文件通过mmap() 系统调用加载;在 Windows 上则通过CreateFileMapping() 加载。这种内存映射方法可显著节省内存。此外,当多个应用程序使用同一个 QML 文档时,代码所需的内存会在应用程序进程之间共享,从而进一步降低内存开销。

缓存验证

只有当满足以下所有条件时,才会加载缓存文件和预编译代码:

  • Qt 版本未发生变更
  • 原始文件中的源代码未发生变化
  • QML 调试器未运行
  • AOT 代码的验证成功

请注意,QML_FORCE_DISK_CACHE (见下文)可以覆盖 QML 调试器条件。其他环境变量不会影响这些验证条件。

对预编译生成的本机代码的验证

由 Qt Quick Compiler 生成的原生代码内置了一些假设。如果代码的执行条件与编译时的条件不同,使用该代码可能会存在安全隐患。因此,会利用随代码存储的元数据在运行时对原生代码进行验证。如果验证通过,代码将按正常方式执行。 如果验证失败,执行将静默回退为解释字节码。此验证每文件仅执行一次,即在代码首次加载时进行,并整体批准或拒绝该 QML 文件中的所有函数和绑定。

您可以自定义 AOT 代码的验证:

  • 若要禁用运行时验证,请设置QV4_SKIP_AOT_VALIDATION 环境变量。这样可以避免因执行验证而产生的小额开销。
    QV4_SKIP_AOT_VALIDATION=1 ./myQmlApp
  • 若要确保运行时验证成功,请设置QV4_FAIL_ON_INVALID_AOT 环境变量。如果验证失败,程序将终止。例如,这可确保编译后的函数确实作为本机代码执行。
    QV4_FAIL_ON_INVALID_AOT=1 ./myQmlApp
  • 若要完全禁用该功能并防止 Qt Quick Compiler 生成元数据和验证逻辑,请将 `NO_GENERATE_AOT_VALIDATION ` 作为参数传递给 `qt_add_qml_module`。
    qt_add_qml_module(... NO_GENERATE_AOT_VALIDATION)

配置

您可以使用环境变量QML_DISK_CACHE 来微调缓存行为,该变量接受以逗号分隔的选项列表。例如:

QML_DISK_CACHE=aot,qmlc-read

可用的选项如下:

选项描述
aot-native加载预先编译的编译单元,并允许执行其中发现的任何本机代码。
aot-bytecode加载预先编译好的编译单元,并允许对其中发现的字节码进行解释和即时编译。
aotaot-native,aot-bytecode 的简写形式。
qmlc-read从主机文件系统加载 QML 和 JavaScript 文件的任何缓存编译单元,并允许对其中包含的字节码进行解释和即时编译。
qmlc-write在动态编译 QML 或 JavaScript 文件后,创建一个缓存文件。当再次请求同一文档时,可加载该缓存文件。
qmlcqmlc-read,qmlc-write 的简写形式。

此外,您还可以使用以下环境变量:

环境变量描述
QML_DISABLE_DISK_CACHE禁用磁盘缓存,并强制对所有 QML 和 JavaScript 文件从源代码重新编译。QML_DISABLE_DISK_CACHE 会覆盖QML_DISK_CACHE 。
QML_FORCE_DISK_CACHE即使在调试 QML 时也启用磁盘缓存。在此模式下无法使用 JavaScript 调试器。例如,程序可能无法在断点处暂停。不过,您仍然可以使用 QML 检查器来探索对象层次结构。QML_FORCE_DISK_CACHE 会覆盖QML_DISABLE_DISK_CACHE 和QML_DISK_CACHE 。
QML_DISK_CACHE_PATH指定一个自定义位置来存储缓存文件,而不是使用默认位置。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.