了解如何改进 Expo 应用和网站的生产 JavaScript 包大小。
不同平台的打包包性能有所不同。例如,Web 浏览器不支持预编译字节码,因此 JavaScript 包大小对于提高启动时间和性能非常重要。打包包越小,下载和解析的速度就越快。
¥Bundle performance varies for different platforms. For example, web browsers don't support precompiled bytecode, so the JavaScript bundle size is important for improving startup time and performance. The smaller the bundle, the faster it can be downloaded and parsed.
¥Analyzing bundle size with Atlas
仅适用于 SDK 51 及以上版本。
¥Available only for SDK 51 and above.
项目中使用的库会影响生产 JavaScript 包的大小。从 Expo SDK 51 开始,你可以使用 Expo Atlas 可视化生产包并确定哪些库对包大小有贡献。
¥The libraries used in a project influence the size of the production JavaScript bundle. Starting from Expo SDK 51, you can use Expo Atlas to visualize the production bundle and identify which libraries contribute to the bundle size.
npx expo start
结合使用¥Using Atlas with npx expo start
你可以将 Expo Atlas 与本地开发服务器一起使用。此方法允许 Atlas 在你更改项目中的任何代码时进行更新。
¥You can use Expo Atlas with the local development server. This method allows Atlas to update whenever you change any code in your project.
在 Android、iOS 和/或 Web 上使用本地开发服务器运行你的应用后,你可以使用 shift + m 通过 开发工具插件菜单 打开 Atlas。
¥Once your app is running using the local development server on Android, iOS, and/or web, you can open Atlas through the dev tools plugin menu using shift + m.
# Start the local development server with Atlas
-
EXPO_UNSTABLE_ATLAS=true npx expo start
¥Changing development mode to production
默认情况下,Expo 在 开发模式 中启动本地开发服务器。开发模式禁用了 使用 React Native 测试库进行查询 中启用的一些优化。你还可以在生产模式下启动本地开发服务器,以更准确地表示生产包大小:
¥By default, Expo starts the local development server in development mode. Development mode disables some optimizations that are enabled in production mode. You can also start the local development server in production mode to get a more accurate representation of the production bundle size:
# Run the local development server in production mode
-
EXPO_UNSTABLE_ATLAS=true npx expo start --no-dev
npx expo export
结合使用¥Using Atlas with npx expo export
你还可以在为你的应用或 EAS 更新生成生产包时使用 Expo Atlas。Atlas 在导出期间会生成一个 .expo/atlas.jsonl 文件,你可以在不访问项目的情况下共享和打开该文件。
¥You can also use Expo Atlas when generating a production bundle for your app or EAS Update. Atlas generates a .expo/atlas.jsonl file during export, which you can share and open without having access to the project.
# Export your app for all platforms
-
EXPO_UNSTABLE_ATLAS=true npx expo export
# Open the generated Atlas file
-
npx expo-atlas .expo/atlas.jsonl
你还可以使用 --platform
选项指定要分析的平台。Atlas 将仅收集导出平台的数据。
¥You can also specify the platforms you want to analyze using the --platform
option. Atlas will gather the data for the exported platforms only.
¥Analyzing transformed modules
在 Atlas 中,你可以按住 ⌘ Cmd 并单击图形节点以查看转换后的模块详细信息。此功能可帮助你了解 Babel 如何转换模块、它导入了哪些模块以及哪些模块导入了它。这可用于在依赖图中跟踪模块的来源。
¥Inside Atlas, you can hold ⌘ Cmd and click on a graph node to see the transformed module details. This feature helps you understand how a module is transformed by Babel, which modules it imports, and which modules imported it. This can be used to trace the origin of a module across the dependency graph.
¥Analyzing bundle size with source-map-explorer
适用于 SDK 50 及以下版本的替代方法。
¥Alternative method for SDK 50 and below.
如果你使用的是 SDK 50 或更低版本,则可以使用 source-map-explorer 包来可视化和分析生产 JavaScript 包。
¥If you are using SDK 50 or below, you can use the source-map-explorer package to visualize and analyze the production JavaScript bundle.
1
要使用 Source Map Explorer,请运行以下命令来安装它:
¥To use source map explorer, run the following command to install it:
-
npm i --save-dev source-map-explorer
2
将脚本添加到 package.json 来运行它。你可能需要根据你使用的平台或 SDK 调整输入路径。为简洁起见,以下示例假设项目是 Expo SDK 50 并且不使用 Expo Router server
输出。
¥Add a script to package.json to run it. You might have to adjust the input path depending on the platform or SDK you are using. For brevity, the following example assumes the project is Expo SDK 50 and does not use Expo Router server
output.
{
"scripts": {
"analyze:web": "source-map-explorer 'dist/_expo/static/js/web/*.js' 'dist/_expo/static/js/web/*.js.map'",
"analyze:ios": "source-map-explorer 'dist/_expo/static/js/ios/*.js' 'dist/_expo/static/js/ios/*.js.map'",
"analyze:android": "source-map-explorer 'dist/_expo/static/js/android/*.js' 'dist/_expo/static/js/android/*.js.map'"
}
}
如果你使用适用于 Web 的 SDK 50 server
输出,则使用以下命令来映射 Web 包:
¥If you are using the SDK 50 server
output for web, then use the following to map web bundles:
-
npx source-map-explorer 'dist/client/_expo/static/js/web/*.js' 'dist/client/_expo/static/js/web/*.js.map'
Web 包输出到 dist/client 子目录,以防止将服务器代码暴露给客户端。
¥Web bundles are output to the dist/client subdirectory to prevent exposing server code to the client.
3
导出你的生产 JavaScript 包并包含 --source-maps
标志,以便源映射资源管理器可以读取源映射:
¥Export your production JavaScript bundle and include the --source-maps
flag so that the source map explorer can read the source maps:
-
npx expo export --source-maps --platform web
# Native apps using Hermes can disable bytecode for analyzing the JavaScript bundle.
-
npx expo export --source-maps --platform ios --no-bytecode
此命令在输出中显示 JavaScript 包和源映射路径。在下一步中,你将把这些路径传递给源地图资源管理器。
¥This command shows the JavaScript bundle and source map paths in the output. In the next step, you will pass these paths to the source map explorer.
避免将源地图发布到生产环境,因为它们可能会导致安全问题和性能问题(浏览器将下载大型地图)。
¥Avoid publishing source maps to production as they can cause both security issues and performance issues (a browser will download the large maps).
4
运行脚本来分析你的包:
¥Run the script to analyze your bundle:
-
npm run analyze:web
运行此命令时,你可能会看到以下错误:
¥On running this command, you might see the following error:
You must provide the URL of lib/mappings.wasm by calling SourceMapConsumer.initialize({ 'lib/mappings.wasm': ... }) before using SourceMapConsumer
这可能是由于 Node.js 18 及更高版本中的 已知问题 in source-map-explorer
造成的。要解决此问题,请在运行分析脚本之前设置环境变量 NODE_OPTIONS=--no-experimental-fetch
。
¥This is probably due to a known issue in source-map-explorer
in Node.js 18 and above. To resolve this, set the environment variable NODE_OPTIONS=--no-experimental-fetch
before running the analyze script.
你可能会遇到诸如 Unable to map 809/13787 bytes (5.87%)
之类的警告。发生这种情况是因为源映射通常排除打包程序运行时定义(例如,__d(() => {}, [])
)。该值是一致的,无需担心。
¥You might encounter a warning such as Unable to map 809/13787 bytes (5.87%)
. This occurs because source maps often exclude bundler runtime definitions (for example, __d(() => {}, [])
). This value is consistent and not a reason for concern.
¥Lighthouse
Lighthouse 是查看网站速度、可访问性和性能的好方法。你可以使用 Chrome 中的“审核”选项卡或使用 灯塔 CLI。
¥Lighthouse is a great way to see how fast, accessible, and performant your website is. You can test your project with the Audit tab in Chrome, or with the Lighthouse CLI.
使用 npx expo export -p web
创建生产版本并为其提供服务(使用 npx serve dist
、生产部署或自定义服务器)后,使用托管站点的 URL 运行 Lighthouse。
¥After creating a production build with npx expo export -p web
and serving it (using either npx serve dist
, or production deployment, or custom server), run Lighthouse with the URL your site is hosted at.
# Install the lighthouse CLI
-
npm install -g lighthouse
# Run the lighthouse CLI for your site
-
npx lighthouse <url> --view