Skip to main content

optimize-web

Optimizes Unity WebGL and WebGPU builds for smaller downloads, faster loading, and smoother browser performance. Use when asked to shrink a web build, speed up its load, or fix stutter, memory or battery problems in the browser.

来源信息

仓库
Unity-Technologies/skills
最近来源活动
2026年10月22日 18:20
检测到的 SKILL.md 语言
英语
星标
1,148
分支
66

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

文件资源管理器
4 个文件

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
optimize-web
description
Optimizes Unity WebGL and WebGPU builds for smaller downloads, faster loading, and smoother browser performance. Use when asked to shrink a web build, speed up its load, or fix stutter, memory or battery problems in the browser.
Audit and apply the Player Settings, compression, stripping, and server setup that make a Unity Web build smaller and faster. ## Important - Use the unity cli (`unity command --format json`) and the `unity-cli` skill for each step. Use `unity-pipeline` too when it is available. - Before making changes, establish a baseline of the current behavior so you can tell whether a later result is actually caused by your change. - Create a restore point you can roll back to if your changes fail. - Do only what's asked. Don't change unrelated assets or files. - If the changes affect runtime behavior, add `Debug.Log` lines that will prove the actual scene behaviour (not just your changes) is now working - you'll read these when you enter Play mode to validate later. For example, log a GameObject's Transform scale if your fix is meant to make sure it changes size. - Avoid long explanations. ## Performance Notes - Take your time to do this thoroughly. - Quality is more important than speed. ## Full topic map Before you go forward with a workflow or diagnosis: 1. Open and read the [documentation page(s)](#full-topic-map) that cover the specific subject related to what you intend to do or fix and check if you've missed anything. 2. Name the file(s) you read in your response. This is because your training knowledge about Unity might be out of date, incorrect, or for the wrong Unity version. If the Editor install folder has a `Data/Documentation` folder (eg `...Unity/Hub/Editor/6000.6.0b2/Editor/Data/Documentation`), read the html files from the `<editor-install>/Editor/Data/Documentation/en/Manual` folder. Otherwise the docs pages are online at `https://docs.unity.com/en-us/engine/<VERSION>/manual/`. For the packages this skill uses (`com.unity.cloud.ktx`, `com.unity.addressables`, `com.unity.web.stripping-tool`), the docs pages are local markdown conversions of the Unity Manual, stored at `<project-folder>/Library/PackageCache/<package-name>@*/`. Read only the .md files in that specific `PackageCache` subfolder. You must not look at non-.md files, or look outside at other Library or PackageCache folders, otherwise it takes too much time. If that folder has no `.md` files, use `https://docs.unity3d.com/Packages/<package-name>@<VERSION>/manual/` instead. Prefer `WebFetch` over `WebSearch` — faster and lands on the exact reference. Only fetch what you need. Replace `<VERSION>` with the following before fetching: - **docs.unity3d.com**: The Unity version, eg `6000.6` - **Package on docs.unity3d.com**: The package version, eg `@6.6` or `@2.0`. Check the package version if unsure. - **docs.unity.com**: The Unity version, eg `6000.6` Read the Unity major.minor from `ProjectSettings/ProjectVersion.txt` (for example `6000.0` from `6000.0.58f1`, because the full build number gives a 404), and each package's major.minor from `Packages/packages-lock.json`. - [Recommended Player settings to optimize your Web build](https://docs.unity.com/en-us/engine/<VERSION>/manual/platform-specific/webgl/building-distribution/web-optimization/player.md) — local `web-optimization-player.html`: release values for compression, stripping, exceptions and memory. - [Use C# code to enable optimization settings](https://docs.unity.com/en-us/engine/<VERSION>/manual/platform-specific/webgl/building-distribution/web-optimization/c-sharp.md) — local `web-optimization-c-sharp.html`: editor script that applies the recommended settings in one step. - [Remove unused resources from your Web build](https://docs.unity.com/en-us/engine/<VERSION>/manual/platform-specific/webgl/building-distribution/web-optimization/remove-resources.md) — local `web-optimization-remove-resources.html`: removing unused packages and stripping shader variants. - [Distribution size and code stripping](https://docs.unity.com/en-us/engine/<VERSION>/manual/platform-specific/webgl/building-distribution/distributionsize-codestripping.md) — local `webgl-distributionsize-codestripping.html`: what drives Web build size and how stripping works. - [Deploy a Web application](https://docs.unity.com/en-us/engine/<VERSION>/manual/platform-specific/webgl/building-distribution/deploying.md) — local `webgl-deploying.html`: server compression headers, MIME types and Decompression Fallback. - [Memory in Unity Web](https://docs.unity.com/en-us/engine/<VERSION>/manual/platform-specific/webgl/develop/memory.md) — local `webgl-memory.html`: Wasm heap size, memory growth and browser memory limits. ### API reference The API is `UnityEditor.PlayerSettings`, `UnityEditor.PlayerSettings.WebGL` and `UnityEditor.WebGL.UserBuildSettings`, part of the Unity Engine. It is versioned by Unity version, so check the project's Unity version before relying on a specific class or method. 1. Use the `unity-cli` skill to check the project's Unity version. 2. If the Editor install folder has a `Data/Documentation` folder (e.g. `.../Unity/Hub/Editor/6000.6.0b2/Editor/Data/Documentation`), grep the html files in the `en/ScriptReference` folder inside, and skip the remaining steps. 3. Otherwise, fetch and cache `https://docs.unity3d.com/<VERSION>/Documentation/ScriptReference/xrefmap.yml` (replace `<VERSION>` with the Unity version, e.g. `6000.3`). This file lists every public API member's fully qualified name as a `uid` (e.g. `uid: 'UnityEngine.Rigidbody.AddForce(UnityEngine.Vector3)'`). 4. Grep the yml file locally for a class or method instead of refetching per lookup. The file is large (about 6 MB), so don't read the whole file. 5. Convert the `uid` to a markdown page: remove the parameters in brackets, lowercase it, replace `.` with `/`, and add `.md`. Then fetch `https://docs.unity.com/en-us/engine/<VERSION>/script-reference/<converted uid>`. For example, `UnityEngine.Rigidbody.AddForce(UnityEngine.Vector3)` => `https://docs.unity.com/en-us/engine/6000.3/script-reference/unityengine/rigidbody/addforce.md`. All overloads are on the same page. - Constructors use `ctor` (e.g. `unityengine/vector3/ctor.md`), and indexers use `item` (e.g. `unityengine/vector3/item.md`). - For operators, fetch the class page (e.g. `unityengine/vector3.md`) and follow its link. - Links inside the pages start with `/engine/`. Add `https://docs.unity.com/en-us` before them. - If the page doesn't exist for that Unity version, use the `href` in the `xrefmap.yml` entry instead (e.g. `href: 'Rigidbody.AddForce.html'` => `https://docs.unity3d.com/6000.3/Documentation/ScriptReference/Rigidbody.AddForce.html`). Always use the docs for the project's Unity version rather than relying on training knowledge, since APIs are frequently marked obsolete between versions. The KTX API (`KtxUnity`) is part of the `com.unity.cloud.ktx` package. It is versioned by package version, not Unity version, so check the project's installed package version before relying on a specific class or method. 1. Read the installed package version from `Packages/packages-lock.json`. 2. Fetch and cache `https://docs.unity3d.com/Packages/com.unity.cloud.ktx@<version>/xrefmap.yml` (replace `<version>` with the installed package version, e.g. `3.4`). This file maps every public API member's fully qualified name to its docs page `href`. 3. Grep the yml file locally for a class or method instead of refetching per lookup. Don't read the whole file. ## Procedure 1. Get the project context: the Unity version from `ProjectSettings/ProjectVersion.txt`, and the versions of the packages you need (`com.unity.cloud.ktx`, `com.unity.addressables`, `com.unity.web.stripping-tool`) from `Packages/packages-lock.json`. If there's no project, assume Unity `6000.0`. For any package not listed in `packages-lock.json`, assume the latest version in that package's documentation. Preserve every version you do find — only default the values that are actually missing. Name each assumption in your report and carry on. If the user hasn't said what to optimize and there's no project to read, ask what they want to improve. 2. Read the docs pages that cover the task, from the [Full topic map](#full-topic-map). 3. Set up `eval` as described in [Running C# in the Editor](#running-c-in-the-editor). If no Editor is reachable or `eval` is missing, say so, skip to step 5, then go straight to step 9. Mark build validation and runtime checks as unperformed in your report, and base your recommendations on the user's request and the docs from step 2. 4. Run [0. Pre-Flight](#0-pre-flight) and [1. Assess Current State](#1-assess-current-state). Their results are your baseline. 5. Match the request to a row in [2. Understand Request](#2-understand-request). 6. Create a restore point, then apply the changes from [3. Web Build Optimization Workflow](#3-web-build-optimization-workflow). If a symptom matches [5. Troubleshooting](#5-troubleshooting), follow that entry. 7. Run [4. Validation](#4-validation): rerun the Pre-Flight snippet and compare the values with your baseline. 8. Do the checks in [Final step](#final-step). 9. Give the [Final report](#final-report). ## Running C# in the Editor Every step below that reads or writes a Player Setting runs inside a live Editor through the Unity CLI. **The `unity-cli` skill owns getting you there** — installing the CLI, confirming a connected Editor, adding the project's `com.unity.pipeline` package, telling a genuinely absent Editor apart from one stuck in Safe Mode, and discovering the Editor's command catalog. Follow it first; don't re-derive any of it here. Two things it can't know for you: - **You need `eval` in particular**, not just a reachable Editor. Confirm it appears in the catalog. Its presence depends on the Pipeline package version, not on the CLI, so a healthy install can still lack it — if it's missing, say so and skip the steps that read or write settings. - **You can read Player Settings from `ProjectSettings/ProjectSettings.asset` in a pinch, but do not write them that way.** The serialized names don't match the API names, several of these settings are per-build-target, and a hand-edited value silently disagrees with what the build actually uses. An unreachable Editor is a stop for the write steps. Run C# with `unity command eval --code '<snippet>'`. `unity command` defaults to a 30 second timeout. ### Passing C# to `eval` `eval` compiles a **statement block, not a file**, so write the code without `using` directives and with fully qualified types. If the code doesn't compile, look up the error here: | Error | Cause | Fix | | --- | --- | --- | | `CS0210` | A `using` directive, such as `using UnityEditor;`, which the compiler reads as a resource-disposal statement | Remove the directive and qualify the types | | `CS0246` | An unqualified type, such as `PlayerSettings` | Use the full name, such as `UnityEditor.PlayerSettings` | | `CS0104` | A bare `Object`, which is ambiguous with `object` | Use `UnityEngine.Object` | ### Reading the settings this skill audits One call returns the whole Pre-Flight picture. Verified against Unity 6000.5.7f1: ```csharp var target = UnityEditor.Build.NamedBuildTarget.WebGL; var w = new System.Collections.Generic.List<string>(); w.Add($"activeBuildTarget={UnityEditor.EditorUserBuildSettings.activeBuildTarget}"); w.Add($"compressionFormat={UnityEditor.PlayerSettings.WebGL.compressionFormat}"); w.Add($"decompressionFallback={UnityEditor.PlayerSettings.WebGL.decompressionFallback}"); w.Add($"stripEngineCode={UnityEditor.PlayerSettings.stripEngineCode}"); w.Add($"managedStrippingLevel={UnityEditor.PlayerSettings.GetManagedStrippingLevel(target)}"); w.Add($"il2cppCodeGeneration={UnityEditor.PlayerSettings.GetIl2CppCodeGeneration(target)}"); w.Add($"apiCompatibilityLevel={UnityEditor.PlayerSettings.GetApiCompatibilityLevel(target)}"); w.Add($"exceptionSupport={UnityEditor.PlayerSettings.WebGL.exceptionSupport}"); w.Add($"debugSymbolMode={UnityEditor.PlayerSettings.WebGL.debugSymbolMode}"); w.Add($"dataCaching={UnityEditor.PlayerSettings.WebGL.dataCaching}"); w.Add($"wasm2023={UnityEditor.PlayerSettings.WebGL.wasm2023}"); w.Add($"initialMemorySize={UnityEditor.PlayerSettings.WebGL.initialMemorySize}"); w.Add($"maximumMemorySize={UnityEditor.PlayerSettings.WebGL.maximumMemorySize}"); w.Add($"memoryGrowthMode={UnityEditor.PlayerSettings.WebGL.memoryGrowthMode}"); w.Add($"targetFrameRate={UnityEngine.Application.targetFrameRate}"); w.Add($"vSyncCount={UnityEngine.QualitySettings.vSyncCount}"); return string.Join("\n", w); ``` **Three API names to get right**, because the obvious spellings do not exist and fail to compile: | Setting | Correct form | Does NOT exist | |---|---|---| | Managed stripping level | `PlayerSettings.GetManagedStrippingLevel(NamedBuildTarget.WebGL)` | `PlayerSettings.managedStrippingLevel` | | Wasm code optimization | `UnityEditor.WebGL.UserBuildSettings.codeOptimization` | `PlayerSettings.WebGL.codeOptimization`, `PlayerSettings.WebGL.optimizationLevel` | | IL2CPP code generation | `PlayerSettings.GetIl2CppCodeGeneration(NamedBuildTarget.WebGL)` | a bare property | `UserBuildSettings` lives in the WebGL build-support module, so it only resolves when that module is installed. Read it in a separate call from the rest, and treat a resolution failure as "the Web module isn't installed" rather than as a bad snippet. **`codeOptimization` is the one setting here that does not live in the project file.** It persists to `Library/EditorUserBuildSettings.asset`, and `Library/` is gitignored by every standard Unity `.gitignore`, so this value is per-machine and does not travel: teammates and CI do not inherit it. Two consequences. Read it back through the API and do not look for it in `ProjectSettings/ProjectSettings.asset` — it is absent there even on a successful apply, so its absence is not a failure. And if the release build runs in CI, apply it there as a build step rather than assuming the repository carries it. ### Applying the settings Most of the writes in this skill are a single batch, and [scripts/WebOptimizer.cs](scripts/WebOptimizer.cs) already is that batch. It declares a class with a `[MenuItem]`, so it is a **project file, not `eval` input** — a class declaration cannot be flattened into a statement block. Save it under `Assets/Editor/`, let Unity compile, then invoke it in one line: ```csharp UnityEditor.EditorApplication.ExecuteMenuItem("Tools/Apply Web Release Settings"); ``` Keep its `using` directives; they are correct in a file. For one-off changes — a single quality level, a frame-rate flip — an inline `eval` statement is fine. ### Verify from disk, not from the objects you just wrote **Applying a setting and reading it back in the same session proves nothing.** Player Settings are in-memory objects until something saves them, so every read-back returns the value you just assigned whether or not it ever reached `ProjectSettings/ProjectSettings.asset`. A run that skips the save reports success, and when the Editor session ends the whole change is gone. This was observed, not theorised: a run applied everything, read back Brotli / High / None, said it was done, and the file on disk never changed. So after any write: 1. **Save.** `UnityEditor.AssetDatabase.SaveAssets()`. `WebOptimizer.cs` now does this itself; an inline `eval` write has to do it explicitly. 2. **Read the values back and report them.** Not "applied successfully" but the actual values, so the user can see what is stored. `WebOptimizer.cs` logs all nine. 3. **For anything per-build-target, name the target you read.** Several of these settings exist once per target, so a value can be correct for one target and unset for the one being built. The same trap exists on the file-editing route in reverse: a hand-edited `ProjectSettings.asset` reads back fine while the running Editor and the build still use the old value. Verifying after a save and a reimport is what catches both. **Do not try to reproduce this in batch mode.** A batch Editor invoked with `-quit` saves settings on exit, so an unsaved write persists anyway and the run looks correct. Both a saving and a non-saving version of the script pass under `-quit`. The bug only appears in a live Editor session, which is where it was found. Concluding from a green batch run that the save is unnecessary is the wrong conclusion from a test that cannot see the defect. ## 0. Pre-Flight 1. **Confirm Web build target:** Read, with the Pre-Flight snippet above, `EditorUserBuildSettings.activeBuildTarget` — must be `WebGL`; if not, warn the user. 2. **Read compression and stripping settings:** Read `compressionFormat`, `decompressionFallback`, `stripEngineCode` and the managed stripping level with the Pre-Flight snippet above. Note the stripping level is `PlayerSettings.GetManagedStrippingLevel(NamedBuildTarget.WebGL)` — there is no `PlayerSettings.managedStrippingLevel` property. 3. **Read exception and optimization settings:** Read `PlayerSettings.WebGL.exceptionSupport` from the Pre-Flight snippet above. For the wasm code optimization level use `UnityEditor.WebGL.UserBuildSettings.codeOptimization` — the `PlayerSettings.WebGL.codeOptimization` and `optimizationLevel` spellings do not exist and will not compile. 4. **Read frame rate settings:** Read, with the Pre-Flight snippet above, `Application.targetFrameRate` and `QualitySettings.vSyncCount`. 5. **Read additional player settings:** Read, with the Pre-Flight snippet above, `PlayerSettings.WebGL.dataCaching`, `PlayerSettings.WebGL.debugSymbolMode`, `PlayerSettings.WebGL.maximumMemorySize`, and `PlayerSettings.GetApiCompatibilityLevel`. 6. Proceed only after you've confirmed the compression, stripping, frame rate, and player settings. ## 1. Assess Current State 1. **Check Build Report:** Instruct the user to open `Window > General > Build Report` after a build and identify the largest asset and code size contributors. 2. **Verify server configuration:** Ask the user to confirm whether the hosting server sends `Content-Encoding: br` (Brotli) or `Content-Encoding: gzip` headers, and whether `Content-Type: application/wasm` is set for `.wasm` files.
在 GitHub 查看
这个 SKILL.md 很大,SkillsMP 这里只预览前一段内容。 在 GitHub 查看