[{"content":"什么是 Hugo？ Hugo 是一个用 Go 语言编写的开源静态网站生成器，以其极快的构建速度和简洁的使用方式而闻名。无论你是想建立个人博客、文档网站还是企业官网，Hugo 都能提供强大的支持。\nHugo 的核心优势 1. 闪电般的构建速度 Hugo 以其惊人的构建速度著称。即使网站包含数千个页面，也能在毫秒级完成构建。这得益于 Go 语言的高效性能。\n2. 零依赖部署 Hugo 生成的是纯静态 HTML 文件，无需数据库、服务器端脚本或复杂的部署流程。只需上传文件到任何 Web 服务器即可。\n3. 灵活的主题系统 Hugo 拥有丰富的主题库，你可以轻松选择喜欢的主题，或者自己开发定制主题。\n4. 强大的内容管理 支持 Markdown 格式编写内容，内置分类、标签、日期等元数据管理功能。\n快速开始 安装 Hugo # macOS (使用 Homebrew) brew install hugo # Windows (使用 Chocolatey) choco install hugo # Linux sudo apt-get install hugo 创建新网站 hugo new site my-website cd my-website 添加主题 git clone https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod 创建第一篇文章 hugo new posts/my-first-post.md 本地预览 hugo server -D 然后在浏览器中访问 http://localhost:1313/ 查看你的网站。\nHugo 的文件结构 my-website/ ├── archetypes/ # 文章模板 ├── content/ # 网站内容（Markdown 文件） ├── layouts/ # 自定义布局模板 ├── static/ # 静态文件（CSS、JS、图片等） ├── themes/ # 主题目录 ├── config.toml # 网站配置文件 └── public/ # 生成的静态网站（构建后） 多语言支持 Hugo 原生支持多语言网站。在 config.toml 中配置：\n[languages] [languages.zh] languageName = \u0026#34;中文\u0026#34; weight = 1 [languages.en] languageName = \u0026#34;English\u0026#34; weight = 2 然后创建对应的内容文件：\ncontent/blog/_index.md - 中文版本 content/blog/_index.en.md - 英文版本 部署到 GitHub Pages 1. 创建 GitHub 仓库 创建名为 username.github.io 的仓库。\n2. 配置 GitHub Actions 在 .github/workflows/hugo.yml 中配置自动构建和部署。\n3. 推送代码 git add . git commit -m \u0026#34;Initial commit\u0026#34; git push origin main GitHub Actions 会自动构建你的网站并部署到 GitHub Pages。\n常用命令 命令 说明 hugo new 创建新文章 hugo server 启动本地开发服务器 hugo 构建网站（生成 public 文件夹） hugo --minify 构建并压缩输出 总结 Hugo 是构建现代静态网站的绝佳选择。它的高性能、简洁的工作流和强大的功能使其成为开发者和内容创作者的首选。无论你是技术爱好者还是非技术用户，Hugo 都能帮助你快速建立专业的网站。\n如果你想了解更多关于 Hugo 的信息，可以访问 Hugo 官方网站。\n相关资源：\nHugo 官方文档 PaperMod 主题 Hugo 社区论坛 ","permalink":"https://magicbude.github.io/blog/hugo-introduction/","summary":"\u003ch2 id=\"什么是-hugo\"\u003e什么是 Hugo？\u003c/h2\u003e\n\u003cp\u003eHugo 是一个用 Go 语言编写的开源静态网站生成器，以其极快的构建速度和简洁的使用方式而闻名。无论你是想建立个人博客、文档网站还是企业官网，Hugo 都能提供强大的支持。\u003c/p\u003e\n\u003ch2 id=\"hugo-的核心优势\"\u003eHugo 的核心优势\u003c/h2\u003e\n\u003ch3 id=\"1-闪电般的构建速度\"\u003e1. \u003cstrong\u003e闪电般的构建速度\u003c/strong\u003e\u003c/h3\u003e\n\u003cp\u003eHugo 以其惊人的构建速度著称。即使网站包含数千个页面，也能在毫秒级完成构建。这得益于 Go 语言的高效性能。\u003c/p\u003e\n\u003ch3 id=\"2-零依赖部署\"\u003e2. \u003cstrong\u003e零依赖部署\u003c/strong\u003e\u003c/h3\u003e\n\u003cp\u003eHugo 生成的是纯静态 HTML 文件，无需数据库、服务器端脚本或复杂的部署流程。只需上传文件到任何 Web 服务器即可。\u003c/p\u003e\n\u003ch3 id=\"3-灵活的主题系统\"\u003e3. \u003cstrong\u003e灵活的主题系统\u003c/strong\u003e\u003c/h3\u003e\n\u003cp\u003eHugo 拥有丰富的主题库，你可以轻松选择喜欢的主题，或者自己开发定制主题。\u003c/p\u003e\n\u003ch3 id=\"4-强大的内容管理\"\u003e4. \u003cstrong\u003e强大的内容管理\u003c/strong\u003e\u003c/h3\u003e\n\u003cp\u003e支持 Markdown 格式编写内容，内置分类、标签、日期等元数据管理功能。\u003c/p\u003e\n\u003ch2 id=\"快速开始\"\u003e快速开始\u003c/h2\u003e\n\u003ch3 id=\"安装-hugo\"\u003e安装 Hugo\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# macOS (使用 Homebrew)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ebrew install hugo\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Windows (使用 Chocolatey)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echoco install hugo\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Linux\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo apt-get install hugo\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"创建新网站\"\u003e创建新网站\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ehugo new site my-website\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e my-website\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"添加主题\"\u003e添加主题\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit clone https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"创建第一篇文章\"\u003e创建第一篇文章\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ehugo new posts/my-first-post.md\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"本地预览\"\u003e本地预览\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ehugo server -D\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e然后在浏览器中访问 \u003ccode\u003ehttp://localhost:1313/\u003c/code\u003e 查看你的网站。\u003c/p\u003e","title":"Hugo 静态网站生成器完全指南"},{"content":"什么是 PaperMod？ PaperMod 是一个为 Hugo 设计的极简主题，以其简洁的设计、快速的加载速度和丰富的功能配置而受欢迎。它提供了现代化的外观，同时保持了高性能和易用性。\n为什么选择 PaperMod？ 1. 极简设计 PaperMod 采用极简主义设计理念，页面清爽，专注于内容展示。没有多余的装饰，让读者专注于你的文章。\n2. 高性能 主题经过优化，加载速度快，SEO 友好。生成的网站在 Google PageSpeed Insights 上通常能获得高分。\n3. 丰富的功能 深色/浅色主题切换 多语言支持 内置搜索功能 社交媒体分享 代码高亮 响应式设计 4. 易于定制 通过简单的配置和 CSS 覆盖，可以轻松自定义主题外观。\n安装 PaperMod 方法 1：使用 Git Submodule（推荐） git submodule add --depth=1 https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod git submodule update --init --recursive 方法 2：直接克隆 git clone https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod 基础配置 1. 在 hugo.yaml 中启用主题 theme: PaperMod 2. 配置基本参数 params: title: \u0026#34;Your Site Title\u0026#34; description: \u0026#34;Site description\u0026#34; author: \u0026#34;Your Name\u0026#34; # 主题相关 defaultTheme: auto # auto/dark/light disableThemeToggle: false # 文章显示选项 ShowReadingTime: true ShowShareButtons: true ShowPostNavLinks: true ShowBreadCrumbs: true 主要功能配置 1. 首页配置 使用 profileMode 配置首页显示个人信息：\nparams: profileMode: enabled: true title: \u0026#34;Hello 👋\u0026#34; subtitle: \u0026#34;Welcome to my website\u0026#34; imageUrl: \u0026#34;/images/avatar.png\u0026#34; imageTitle: \u0026#34;Profile Image\u0026#34; buttons: - name: Blog url: /blog/ - name: Tools url: /toolbox/ 2. 菜单配置 menu: main: - name: Blog url: /blog/ weight: 1 - name: Toolbox url: /toolbox/ weight: 2 - name: About url: /about/ weight: 3 3. 多语言支持 languages: zh: languageName: \u0026#34;中文\u0026#34; weight: 1 menu: main: - name: 博客 url: /blog/ weight: 1 en: languageName: \u0026#34;English\u0026#34; weight: 2 menu: main: - name: Blog url: /blog/ weight: 1 自定义样式 1. 创建自定义 CSS 在 assets/css/extended/ 目录下创建 CSS 文件（如 custom.css）：\n/* 自定义颜色 */ :root { --primary-color: #007bff; --secondary-color: #6c757d; } /* 自定义字体 */ body { font-family: \u0026#39;Segoe UI\u0026#39;, Tahoma, Geneva, Verdana, sans-serif; } /* 自定义卡片样式 */ .post-card { border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } 2. 覆盖主题模板 在 layouts/ 目录下创建与主题相同的目录结构来覆盖模板：\nlayouts/ ├── partials/ │ └── header.html ├── _default/ │ └── single.html └── ... 常用前置元数据 --- title: \u0026#34;文章标题\u0026#34; date: 2025-12-12 description: \u0026#34;文章描述\u0026#34; tags: [\u0026#34;标签1\u0026#34;, \u0026#34;标签2\u0026#34;] categories: [\u0026#34;分类\u0026#34;] author: \u0026#34;作者名\u0026#34; draft: false --- 优化建议 1. 性能优化 启用 Hugo 的压缩功能 优化图片大小和格式 使用 CDN 加速静态资源 2. SEO 优化 为每篇文章添加合适的描述 使用有意义的标签和分类 启用 sitemap 和 robots.txt 3. 用户体验 使用清晰的导航结构 添加面包屑导航 提供搜索功能 支持深色模式 常见问题 Q: 如何修改主题颜色？ A: 在自定义 CSS 中覆盖 CSS 变量：\n:root { --primary: #007bff; --secondary: #6c757d; } Q: 如何添加自定义字体？ A: 在 assets/css/extended/ 中添加字体导入：\n@import url(\u0026#39;https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;700\u0026amp;display=swap\u0026#39;); body { font-family: \u0026#39;Noto Sans SC\u0026#39;, sans-serif; } Q: 如何禁用某些功能？ A: 在 hugo.yaml 中设置相应参数为 false：\nparams: ShowReadingTime: false ShowShareButtons: false ShowBreadCrumbs: false 总结 PaperMod 是一个功能强大且易于定制的 Hugo 主题。通过合理的配置和自定义，你可以创建一个既美观又高效的个人网站。\n无论你是想建立个人博客、作品集还是文档网站，PaperMod 都能提供良好的基础。\n相关资源：\nPaperMod 官方仓库 PaperMod 文档 Hugo 官方文档 ","permalink":"https://magicbude.github.io/blog/papermod-guide/","summary":"\u003ch2 id=\"什么是-papermod\"\u003e什么是 PaperMod？\u003c/h2\u003e\n\u003cp\u003ePaperMod 是一个为 Hugo 设计的极简主题，以其简洁的设计、快速的加载速度和丰富的功能配置而受欢迎。它提供了现代化的外观，同时保持了高性能和易用性。\u003c/p\u003e\n\u003ch2 id=\"为什么选择-papermod\"\u003e为什么选择 PaperMod？\u003c/h2\u003e\n\u003ch3 id=\"1-极简设计\"\u003e1. \u003cstrong\u003e极简设计\u003c/strong\u003e\u003c/h3\u003e\n\u003cp\u003ePaperMod 采用极简主义设计理念，页面清爽，专注于内容展示。没有多余的装饰，让读者专注于你的文章。\u003c/p\u003e\n\u003ch3 id=\"2-高性能\"\u003e2. \u003cstrong\u003e高性能\u003c/strong\u003e\u003c/h3\u003e\n\u003cp\u003e主题经过优化，加载速度快，SEO 友好。生成的网站在 Google PageSpeed Insights 上通常能获得高分。\u003c/p\u003e\n\u003ch3 id=\"3-丰富的功能\"\u003e3. \u003cstrong\u003e丰富的功能\u003c/strong\u003e\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e深色/浅色主题切换\u003c/li\u003e\n\u003cli\u003e多语言支持\u003c/li\u003e\n\u003cli\u003e内置搜索功能\u003c/li\u003e\n\u003cli\u003e社交媒体分享\u003c/li\u003e\n\u003cli\u003e代码高亮\u003c/li\u003e\n\u003cli\u003e响应式设计\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"4-易于定制\"\u003e4. \u003cstrong\u003e易于定制\u003c/strong\u003e\u003c/h3\u003e\n\u003cp\u003e通过简单的配置和 CSS 覆盖，可以轻松自定义主题外观。\u003c/p\u003e\n\u003ch2 id=\"安装-papermod\"\u003e安装 PaperMod\u003c/h2\u003e\n\u003ch3 id=\"方法-1使用-git-submodule推荐\"\u003e方法 1：使用 Git Submodule（推荐）\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit submodule add --depth\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit submodule update --init --recursive\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"方法-2直接克隆\"\u003e方法 2：直接克隆\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit clone https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"基础配置\"\u003e基础配置\u003c/h2\u003e\n\u003ch3 id=\"1-在-hugoyaml-中启用主题\"\u003e1. 在 \u003ccode\u003ehugo.yaml\u003c/code\u003e 中启用主题\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-yaml\" data-lang=\"yaml\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003etheme\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"l\"\u003ePaperMod\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"2-配置基本参数\"\u003e2. 配置基本参数\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-yaml\" data-lang=\"yaml\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003eparams\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;Your Site Title\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003edescription\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;Site description\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003eauthor\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;Your Name\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"c\"\u003e# 主题相关\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003edefaultTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"l\"\u003eauto \u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c\"\u003e# auto/dark/light\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003edisableThemeToggle\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"c\"\u003e# 文章显示选项\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003eShowReadingTime\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003eShowShareButtons\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003eShowPostNavLinks\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003eShowBreadCrumbs\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"主要功能配置\"\u003e主要功能配置\u003c/h2\u003e\n\u003ch3 id=\"1-首页配置\"\u003e1. 首页配置\u003c/h3\u003e\n\u003cp\u003e使用 \u003ccode\u003eprofileMode\u003c/code\u003e 配置首页显示个人信息：\u003c/p\u003e","title":"PaperMod 主题完全使用指南"},{"content":"什么是 Markdown？ Markdown 是一种轻量级的标记语言，用简单的符号来格式化文本。它易学易用，广泛应用于博客、文档、README 文件等场景。\n基础语法回顾 标题 # 一级标题 ## 二级标题 ### 三级标题 #### 四级标题 ##### 五级标题 ###### 六级标题 强调 *斜体* 或 _斜体_ **粗体** 或 __粗体__ ***粗斜体*** 或 ___粗斜体___ ~~删除线~~ 列表 无序列表：\n- 项目 1 - 项目 2 - 子项目 2.1 - 子项目 2.2 - 项目 3 有序列表：\n1. 第一项 2. 第二项 3. 第三项 链接和图片 [链接文本](https://example.com) [链接文本](https://example.com \u0026#34;链接标题\u0026#34;) ![图片描述](image.jpg) ![图片描述](image.jpg \u0026#34;图片标题\u0026#34;) 高级技巧 1. 代码块 行内代码：\n使用 `code` 表示行内代码 代码块：\n```python def hello_world(): print(\u0026#34;Hello, World!\u0026#34;) ``` 支持的语言高亮包括：python、javascript、java、c++、bash 等。\n2. 表格 | 列1 | 列2 | 列3 | |-----|-----|-----| | 数据1 | 数据2 | 数据3 | | 数据4 | 数据5 | 数据6 | 对齐方式：\n| 左对齐 | 居中 | 右对齐 | |:------|:----:|-------:| | 左 | 中 | 右 | 3. 引用 \u0026gt; 这是一个引用 \u0026gt; 可以有多行 \u0026gt; \u0026gt; \u0026gt; 嵌套引用 4. 分割线 --- *** ___ 5. 列表中的代码块 1. 第一步 ```python code here ``` 2. 第二步 ```javascript code here ``` 6. 脚注 这是一个脚注[^1] [^1]: 脚注内容 最佳实践 1. 结构清晰 使用合适的标题层级（不要跳级） 每个部分用标题分隔 逻辑递进，循序渐进 # 主标题 ## 第一部分 ### 小节 1 ### 小节 2 ## 第二部分 ### 小节 3 2. 代码示例完整 提供可运行的代码示例，包括导入和完整的上下文：\n❌ 不好的做法： ```python result = function(data) ``` ✅ 好的做法： ```python from module import function data = [1, 2, 3] result = function(data) print(result) ``` 3. 使用列表组织信息 ❌ 不好的做法： 这个功能有三个优点：速度快、易于使用、功能强大。 ✅ 好的做法： 这个功能有三个优点： - 速度快 - 易于使用 - 功能强大 4. 链接使用规范 ❌ 不好的做法： 更多信息请点击[这里](https://example.com) ✅ 好的做法： 更多信息请查看[官方文档](https://example.com) 5. 图片优化 ❌ 不好的做法： ![](image.jpg) ✅ 好的做法： ![网站首页截图](images/homepage.jpg \u0026#34;首页展示\u0026#34;) 6. 使用引用强调重点 \u0026gt; **注意：** 这是一个重要提示 \u0026gt; \u0026gt; 具体内容说明 7. 代码块语言标注 ❌ 不好的做法： ``` code here ``` ✅ 好的做法： ```python code here ``` 常见错误 1. 标题层级混乱 ❌ 错误： # 标题 ### 小标题（跳过了二级） ✅ 正确： # 标题 ## 小标题 2. 列表缩进不一致 ❌ 错误： - 项目1 - 子项目1 - 子项目2（缩进不一致） ✅ 正确： - 项目1 - 子项目1 - 子项目2 3. 代码块前后没有空行 ❌ 错误： 这是说明 ```python code ``` 继续说明 ✅ 正确： 这是说明 ```python code ``` 继续说明 工具推荐 编辑器 VS Code - 强大的代码编辑器，Markdown 支持完善 Typora - 所见即所得的 Markdown 编辑器 Obsidian - 知识库管理工具，Markdown 支持优秀 Notion - 在线笔记工具，支持 Markdown 预览工具 Markdown Preview Enhanced - VS Code 扩展 Grip - 命令行工具，实时预览 Pandoc - 文档转换工具 总结 Markdown 的强大之处在于它的简洁性和灵活性。通过掌握基础语法和最佳实践，你可以写出清晰、专业的文档。\n记住这些要点：\n保持结构清晰 代码示例完整 链接描述准确 图片有说明 一致的格式风格 相关资源：\nMarkdown 官方语法 CommonMark 规范 GitHub Flavored Markdown ","permalink":"https://magicbude.github.io/blog/markdown-guide/","summary":"\u003ch2 id=\"什么是-markdown\"\u003e什么是 Markdown？\u003c/h2\u003e\n\u003cp\u003eMarkdown 是一种轻量级的标记语言，用简单的符号来格式化文本。它易学易用，广泛应用于博客、文档、README 文件等场景。\u003c/p\u003e\n\u003ch2 id=\"基础语法回顾\"\u003e基础语法回顾\u003c/h2\u003e\n\u003ch3 id=\"标题\"\u003e标题\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-markdown\" data-lang=\"markdown\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"gh\"\u003e# 一级标题\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"gh\"\u003e\u003c/span\u003e\u003cspan class=\"gu\"\u003e## 二级标题\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"gu\"\u003e### 三级标题\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"gu\"\u003e#### 四级标题\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"gu\"\u003e##### 五级标题\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"gu\"\u003e###### 六级标题\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"强调\"\u003e强调\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-markdown\" data-lang=\"markdown\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e*斜体* 或 \u003cspan class=\"ge\"\u003e_斜体_\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"gs\"\u003e**粗体**\u003c/span\u003e 或 \u003cspan class=\"gs\"\u003e__粗体__\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"ge\"\u003e**\u003c/span\u003e*粗斜体*** 或 \u003cspan class=\"gs\"\u003e___粗斜体___\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"gd\"\u003e~~删除线~~\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"列表\"\u003e列表\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003e无序列表：\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-markdown\" data-lang=\"markdown\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003e-\u003c/span\u003e 项目 1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003e-\u003c/span\u003e 项目 2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"k\"\u003e-\u003c/span\u003e 子项目 2.1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"k\"\u003e-\u003c/span\u003e 子项目 2.2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003e-\u003c/span\u003e 项目 3\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003cstrong\u003e有序列表：\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-markdown\" data-lang=\"markdown\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003e1.\u003c/span\u003e 第一项\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003e2.\u003c/span\u003e 第二项\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003e3.\u003c/span\u003e 第三项\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"链接和图片\"\u003e链接和图片\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-markdown\" data-lang=\"markdown\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e[\u003cspan class=\"nt\"\u003e链接文本\u003c/span\u003e](\u003cspan class=\"na\"\u003ehttps://example.com\u003c/span\u003e)\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e[\u003cspan class=\"nt\"\u003e链接文本\u003c/span\u003e](\u003cspan class=\"na\"\u003ehttps://example.com \u0026#34;链接标题\u0026#34;\u003c/span\u003e)\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e![\u003cspan class=\"nt\"\u003e图片描述\u003c/span\u003e](\u003cspan class=\"na\"\u003eimage.jpg\u003c/span\u003e)\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e![\u003cspan class=\"nt\"\u003e图片描述\u003c/span\u003e](\u003cspan class=\"na\"\u003eimage.jpg \u0026#34;图片标题\u0026#34;\u003c/span\u003e)\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"高级技巧\"\u003e高级技巧\u003c/h2\u003e\n\u003ch3 id=\"1-代码块\"\u003e1. 代码块\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003e行内代码：\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-markdown\" data-lang=\"markdown\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e使用 \u003cspan class=\"sb\"\u003e`code`\u003c/span\u003e 表示行内代码\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003cstrong\u003e代码块：\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-markdown\" data-lang=\"markdown\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e```python\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003edef\u003c/span\u003e \u003cspan class=\"nf\"\u003ehello_world\u003c/span\u003e\u003cspan class=\"p\"\u003e():\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;Hello, World!\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e```\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e支持的语言高亮包括：python、javascript、java、c++、bash 等。\u003c/p\u003e","title":"Markdown 写作技巧和最佳实践"},{"content":"什么是 Git？ Git 是一个分布式版本控制系统，用于跟踪文件的变化历史。它允许多个开发者协作开发项目，同时保持代码的完整性和可追溯性。\n什么是 GitHub？ GitHub 是一个基于 Git 的代码托管平台，提供了在线仓库、协作工具、CI/CD 等功能。它是全球最大的开源项目托管平台。\nGit 基础概念 仓库（Repository） 存储项目代码和历史记录的地方。分为本地仓库和远程仓库。\n分支（Branch） 独立的开发线。主分支通常是 main 或 master，可以创建其他分支进行特性开发。\n提交（Commit） 保存一次代码变化的快照，包含作者、时间和变化说明。\n推送（Push） 将本地提交上传到远程仓库。\n拉取（Pull） 从远程仓库下载最新代码到本地。\nGit 安装和配置 安装 Git Windows：\n# 使用 Chocolatey choco install git # 或从官网下载安装 # https://git-scm.com/ macOS：\n# 使用 Homebrew brew install git Linux：\n# Ubuntu/Debian sudo apt-get install git # CentOS/RHEL sudo yum install git 配置用户信息 # 设置用户名 git config --global user.name \u0026#34;Your Name\u0026#34; # 设置邮箱 git config --global user.email \u0026#34;your.email@example.com\u0026#34; # 查看配置 git config --list 常用 Git 命令 初始化和克隆 # 初始化本地仓库 git init # 克隆远程仓库 git clone https://github.com/username/repository.git 查看状态和历史 # 查看工作区状态 git status # 查看提交历史 git log # 查看简洁的提交历史 git log --oneline # 查看具体改动 git diff 添加和提交 # 添加文件到暂存区 git add filename # 添加所有改动 git add . # 提交改动 git commit -m \u0026#34;commit message\u0026#34; # 一步提交（仅限已跟踪的文件） git commit -am \u0026#34;commit message\u0026#34; 分支操作 # 查看本地分支 git branch # 查看所有分支 git branch -a # 创建新分支 git branch branch-name # 切换分支 git checkout branch-name # 创建并切换分支 git checkout -b branch-name # 删除分支 git branch -d branch-name # 合并分支 git merge branch-name 推送和拉取 # 推送到远程仓库 git push origin branch-name # 拉取远程更新 git pull origin branch-name # 获取远程更新（不合并） git fetch origin 撤销操作 # 撤销工作区改动 git checkout -- filename # 撤销暂存区改动 git reset HEAD filename # 撤销最后一次提交 git reset --soft HEAD~1 # 强制撤销（谨慎使用） git reset --hard HEAD~1 GitHub 工作流程 1. 创建仓库 登录 GitHub 点击 \u0026ldquo;New repository\u0026rdquo; 填写仓库名称和描述 选择公开或私有 初始化 README 文件（可选） 2. 克隆到本地 git clone https://github.com/username/repository.git cd repository 3. 创建特性分支 git checkout -b feature/new-feature 4. 进行开发 编辑文件，进行开发工作。\n5. 提交改动 git add . git commit -m \u0026#34;feat: 添加新功能\u0026#34; 6. 推送到 GitHub git push origin feature/new-feature 7. 创建 Pull Request 在 GitHub 上打开仓库 点击 \u0026ldquo;Pull requests\u0026rdquo; 标签 点击 \u0026ldquo;New pull request\u0026rdquo; 选择要合并的分支 填写 PR 描述 点击 \u0026ldquo;Create pull request\u0026rdquo; 8. 代码审查和合并 团队成员审查代码 讨论和改进 合并到主分支 最佳实践 1. 提交信息规范 # 格式：\u0026lt;type\u0026gt;(\u0026lt;scope\u0026gt;): \u0026lt;subject\u0026gt; # 例如： git commit -m \u0026#34;feat(auth): 添加登录功能\u0026#34; git commit -m \u0026#34;fix(bug): 修复用户列表显示错误\u0026#34; git commit -m \u0026#34;docs(readme): 更新安装说明\u0026#34; 常见类型：\nfeat - 新功能 fix - 修复 bug docs - 文档 style - 代码风格 refactor - 重构 perf - 性能优化 test - 测试 2. 分支命名规范 # 特性分支 feature/user-authentication # 修复分支 fix/login-bug # 文档分支 docs/api-documentation 3. 定期同步主分支 # 切换到主分支 git checkout main # 拉取最新更新 git pull origin main # 切换回特性分支 git checkout feature/my-feature # 合并主分支 git merge main 4. 避免直接在 main 分支上工作 始终在特性分支上开发 通过 Pull Request 合并代码 这样可以进行代码审查和测试 5. 定期清理分支 # 删除已合并的本地分支 git branch -d branch-name # 删除远程分支 git push origin --delete branch-name 常见问题 Q: 如何撤销已推送的提交？ A: 使用 git revert 创建一个新提交来撤销改动：\ngit revert commit-hash git push origin branch-name Q: 如何修改最后一次提交信息？ A: 使用 git commit --amend：\ngit commit --amend -m \u0026#34;new message\u0026#34; git push origin branch-name --force-with-lease Q: 如何解决合并冲突？ A:\n打开冲突文件 查找 \u0026lt;\u0026lt;\u0026lt;\u0026lt;\u0026lt;\u0026lt;\u0026lt;、=======、\u0026gt;\u0026gt;\u0026gt;\u0026gt;\u0026gt;\u0026gt;\u0026gt; 标记 手动编辑，保留需要的代码 删除冲突标记 提交合并 git add . git commit -m \u0026#34;Resolve merge conflict\u0026#34; Q: 如何查看某个文件的修改历史？ A:\n# 查看文件的提交历史 git log -- filename # 查看文件的具体改动 git log -p -- filename # 查看某行代码的修改者 git blame filename 总结 Git 和 GitHub 是现代开发的必备技能。通过掌握基本命令和工作流程，你可以：\n有效地管理代码版本 与团队协作开发 追踪代码变化历史 进行代码审查和质量控制 记住这些要点：\n经常提交，提交信息要清晰 使用分支进行特性开发 通过 Pull Request 进行代码审查 定期同步主分支 保持仓库的整洁 相关资源：\nGit 官方文档 GitHub 官方文档 Git 交互式学习 GitHub 技能 ","permalink":"https://magicbude.github.io/blog/git-github-guide/","summary":"\u003ch2 id=\"什么是-git\"\u003e什么是 Git？\u003c/h2\u003e\n\u003cp\u003eGit 是一个分布式版本控制系统，用于跟踪文件的变化历史。它允许多个开发者协作开发项目，同时保持代码的完整性和可追溯性。\u003c/p\u003e\n\u003ch2 id=\"什么是-github\"\u003e什么是 GitHub？\u003c/h2\u003e\n\u003cp\u003eGitHub 是一个基于 Git 的代码托管平台，提供了在线仓库、协作工具、CI/CD 等功能。它是全球最大的开源项目托管平台。\u003c/p\u003e\n\u003ch2 id=\"git-基础概念\"\u003eGit 基础概念\u003c/h2\u003e\n\u003ch3 id=\"仓库repository\"\u003e仓库（Repository）\u003c/h3\u003e\n\u003cp\u003e存储项目代码和历史记录的地方。分为本地仓库和远程仓库。\u003c/p\u003e\n\u003ch3 id=\"分支branch\"\u003e分支（Branch）\u003c/h3\u003e\n\u003cp\u003e独立的开发线。主分支通常是 \u003ccode\u003emain\u003c/code\u003e 或 \u003ccode\u003emaster\u003c/code\u003e，可以创建其他分支进行特性开发。\u003c/p\u003e\n\u003ch3 id=\"提交commit\"\u003e提交（Commit）\u003c/h3\u003e\n\u003cp\u003e保存一次代码变化的快照，包含作者、时间和变化说明。\u003c/p\u003e\n\u003ch3 id=\"推送push\"\u003e推送（Push）\u003c/h3\u003e\n\u003cp\u003e将本地提交上传到远程仓库。\u003c/p\u003e\n\u003ch3 id=\"拉取pull\"\u003e拉取（Pull）\u003c/h3\u003e\n\u003cp\u003e从远程仓库下载最新代码到本地。\u003c/p\u003e\n\u003ch2 id=\"git-安装和配置\"\u003eGit 安装和配置\u003c/h2\u003e\n\u003ch3 id=\"安装-git\"\u003e安装 Git\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003eWindows：\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 使用 Chocolatey\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echoco install git\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 或从官网下载安装\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# https://git-scm.com/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003cstrong\u003emacOS：\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 使用 Homebrew\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ebrew install git\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003cstrong\u003eLinux：\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Ubuntu/Debian\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo apt-get install git\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# CentOS/RHEL\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo yum install git\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"配置用户信息\"\u003e配置用户信息\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 设置用户名\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit config --global user.name \u003cspan class=\"s2\"\u003e\u0026#34;Your Name\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 设置邮箱\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit config --global user.email \u003cspan class=\"s2\"\u003e\u0026#34;your.email@example.com\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 查看配置\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit config --list\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"常用-git-命令\"\u003e常用 Git 命令\u003c/h2\u003e\n\u003ch3 id=\"初始化和克隆\"\u003e初始化和克隆\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 初始化本地仓库\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit init\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 克隆远程仓库\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit clone https://github.com/username/repository.git\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"查看状态和历史\"\u003e查看状态和历史\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 查看工作区状态\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit status\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 查看提交历史\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit log\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 查看简洁的提交历史\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit log --oneline\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 查看具体改动\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit diff\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"添加和提交\"\u003e添加和提交\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 添加文件到暂存区\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit add filename\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 添加所有改动\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit add .\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 提交改动\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit commit -m \u003cspan class=\"s2\"\u003e\u0026#34;commit message\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 一步提交（仅限已跟踪的文件）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit commit -am \u003cspan class=\"s2\"\u003e\u0026#34;commit message\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"分支操作\"\u003e分支操作\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 查看本地分支\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit branch\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 查看所有分支\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit branch -a\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 创建新分支\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit branch branch-name\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 切换分支\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit checkout branch-name\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 创建并切换分支\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit checkout -b branch-name\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 删除分支\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit branch -d branch-name\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 合并分支\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit merge branch-name\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"推送和拉取\"\u003e推送和拉取\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 推送到远程仓库\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit push origin branch-name\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 拉取远程更新\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit pull origin branch-name\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 获取远程更新（不合并）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit fetch origin\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"撤销操作\"\u003e撤销操作\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 撤销工作区改动\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit checkout -- filename\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 撤销暂存区改动\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit reset HEAD filename\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 撤销最后一次提交\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit reset --soft HEAD~1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 强制撤销（谨慎使用）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit reset --hard HEAD~1\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"github-工作流程\"\u003eGitHub 工作流程\u003c/h2\u003e\n\u003ch3 id=\"1-创建仓库\"\u003e1. 创建仓库\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e登录 GitHub\u003c/li\u003e\n\u003cli\u003e点击 \u0026ldquo;New repository\u0026rdquo;\u003c/li\u003e\n\u003cli\u003e填写仓库名称和描述\u003c/li\u003e\n\u003cli\u003e选择公开或私有\u003c/li\u003e\n\u003cli\u003e初始化 README 文件（可选）\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"2-克隆到本地\"\u003e2. 克隆到本地\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit clone https://github.com/username/repository.git\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e repository\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"3-创建特性分支\"\u003e3. 创建特性分支\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit checkout -b feature/new-feature\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"4-进行开发\"\u003e4. 进行开发\u003c/h3\u003e\n\u003cp\u003e编辑文件，进行开发工作。\u003c/p\u003e","title":"Git 和 GitHub 完全使用指南"},{"content":"什么是 VSCode？ Visual Studio Code（简称 VSCode）是由微软开发的免费、开源的代码编辑器。它以轻量级、功能强大和丰富的扩展生态而著称，是现代开发者的首选编辑器。\n为什么选择 VSCode？ 1. 轻量级和快速 相比 IDE，VSCode 启动快，占用资源少，即使在低配置电脑上也能流畅运行。\n2. 强大的扩展生态 拥有超过 50,000 个扩展，覆盖几乎所有编程语言和开发场景。\n3. 内置功能丰富 集成终端 Git 集成 调试器 代码智能提示 代码格式化 4. 跨平台支持 支持 Windows、macOS 和 Linux。\n必备快捷键 编辑快捷键 快捷键 功能 Ctrl+S 保存文件 Ctrl+Z 撤销 Ctrl+Y 重做 Ctrl+X 剪切 Ctrl+C 复制 Ctrl+V 粘贴 Ctrl+/ 注释/取消注释 Ctrl+Shift+K 删除整行 Alt+↑/↓ 上下移动行 Ctrl+D 选择相同单词 导航快捷键 快捷键 功能 Ctrl+P 快速打开文件 Ctrl+Shift+P 打开命令面板 Ctrl+G 跳转到指定行 Ctrl+F 查找 Ctrl+H 查找和替换 Ctrl+Shift+F 在文件中查找 Ctrl+` 打开/关闭终端 代码编辑快捷键 快捷键 功能 Ctrl+Space 触发代码补全 Ctrl+Shift+Space 触发参数提示 F2 重命名符号 Ctrl+K Ctrl+X 删除末尾空格 Ctrl+Shift+Enter 在上方插入行 Ctrl+Enter 在下方插入行 推荐扩展 1. Prettier - Code Formatter 自动格式化代码，保持代码风格一致。\n2. ESLint JavaScript 代码检查工具，帮助发现潜在问题。\n3. GitLens 增强 Git 功能，显示代码作者和提交信息。\n4. Thunder Client 轻量级 API 测试工具，无需离开编辑器。\n5. Markdown Preview Enhanced 增强 Markdown 预览功能。\n6. Chinese (Simplified) Language Pack 中文语言包（如果需要）。\n7. Peacock 为工作区着色，方便区分多个项目。\n8. Better Comments 为注释添加颜色和样式。\n高效工作流程 1. 使用工作区 创建工作区文件（.code-workspace）来管理多个项目。\n{ \u0026#34;folders\u0026#34;: [ { \u0026#34;path\u0026#34;: \u0026#34;project1\u0026#34; }, { \u0026#34;path\u0026#34;: \u0026#34;project2\u0026#34; } ], \u0026#34;settings\u0026#34;: { \u0026#34;editor.formatOnSave\u0026#34;: true } } 2. 配置用户设置 在 settings.json 中自定义编辑器行为：\n{ \u0026#34;editor.fontSize\u0026#34;: 14, \u0026#34;editor.tabSize\u0026#34;: 2, \u0026#34;editor.formatOnSave\u0026#34;: true, \u0026#34;editor.defaultFormatter\u0026#34;: \u0026#34;esbenp.prettier-vscode\u0026#34;, \u0026#34;files.autoSave\u0026#34;: \u0026#34;afterDelay\u0026#34;, \u0026#34;files.autoSaveDelay\u0026#34;: 1000 } 3. 使用代码片段 创建自定义代码片段加速开发。\n4. 配置调试器 为不同的项目配置调试器，快速定位问题。\n性能优化 1. 禁用不需要的扩展 定期检查扩展列表，禁用不使用的扩展。\n2. 使用轻量级主题 选择轻量级主题可以提升编辑器响应速度。\n3. 配置文件排除 在 settings.json 中排除不需要监听的文件：\n{ \u0026#34;files.exclude\u0026#34;: { \u0026#34;**/.git\u0026#34;: true, \u0026#34;**/node_modules\u0026#34;: true, \u0026#34;**/.DS_Store\u0026#34;: true } } 总结 VSCode 是一个功能强大且易于扩展的代码编辑器。通过掌握快捷键、安装合适的扩展和优化配置，你可以显著提升开发效率。\n记住这些要点：\n学习常用快捷键，提升编辑速度 选择适合自己的扩展，不要过度安装 定期优化配置，保持编辑器性能 探索新功能，不断提升技能 相关资源：\nVSCode 官方文档 VSCode 扩展市场 VSCode 快捷键参考 ","permalink":"https://magicbude.github.io/blog/vscode-tips/","summary":"\u003ch2 id=\"什么是-vscode\"\u003e什么是 VSCode？\u003c/h2\u003e\n\u003cp\u003eVisual Studio Code（简称 VSCode）是由微软开发的免费、开源的代码编辑器。它以轻量级、功能强大和丰富的扩展生态而著称，是现代开发者的首选编辑器。\u003c/p\u003e\n\u003ch2 id=\"为什么选择-vscode\"\u003e为什么选择 VSCode？\u003c/h2\u003e\n\u003ch3 id=\"1-轻量级和快速\"\u003e1. \u003cstrong\u003e轻量级和快速\u003c/strong\u003e\u003c/h3\u003e\n\u003cp\u003e相比 IDE，VSCode 启动快，占用资源少，即使在低配置电脑上也能流畅运行。\u003c/p\u003e\n\u003ch3 id=\"2-强大的扩展生态\"\u003e2. \u003cstrong\u003e强大的扩展生态\u003c/strong\u003e\u003c/h3\u003e\n\u003cp\u003e拥有超过 50,000 个扩展，覆盖几乎所有编程语言和开发场景。\u003c/p\u003e\n\u003ch3 id=\"3-内置功能丰富\"\u003e3. \u003cstrong\u003e内置功能丰富\u003c/strong\u003e\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e集成终端\u003c/li\u003e\n\u003cli\u003eGit 集成\u003c/li\u003e\n\u003cli\u003e调试器\u003c/li\u003e\n\u003cli\u003e代码智能提示\u003c/li\u003e\n\u003cli\u003e代码格式化\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"4-跨平台支持\"\u003e4. \u003cstrong\u003e跨平台支持\u003c/strong\u003e\u003c/h3\u003e\n\u003cp\u003e支持 Windows、macOS 和 Linux。\u003c/p\u003e\n\u003ch2 id=\"必备快捷键\"\u003e必备快捷键\u003c/h2\u003e\n\u003ch3 id=\"编辑快捷键\"\u003e编辑快捷键\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e快捷键\u003c/th\u003e\n          \u003cth\u003e功能\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+S\u003c/td\u003e\n          \u003ctd\u003e保存文件\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+Z\u003c/td\u003e\n          \u003ctd\u003e撤销\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+Y\u003c/td\u003e\n          \u003ctd\u003e重做\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+X\u003c/td\u003e\n          \u003ctd\u003e剪切\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+C\u003c/td\u003e\n          \u003ctd\u003e复制\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+V\u003c/td\u003e\n          \u003ctd\u003e粘贴\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+/\u003c/td\u003e\n          \u003ctd\u003e注释/取消注释\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+Shift+K\u003c/td\u003e\n          \u003ctd\u003e删除整行\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eAlt+↑/↓\u003c/td\u003e\n          \u003ctd\u003e上下移动行\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+D\u003c/td\u003e\n          \u003ctd\u003e选择相同单词\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"导航快捷键\"\u003e导航快捷键\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e快捷键\u003c/th\u003e\n          \u003cth\u003e功能\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+P\u003c/td\u003e\n          \u003ctd\u003e快速打开文件\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+Shift+P\u003c/td\u003e\n          \u003ctd\u003e打开命令面板\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+G\u003c/td\u003e\n          \u003ctd\u003e跳转到指定行\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+F\u003c/td\u003e\n          \u003ctd\u003e查找\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+H\u003c/td\u003e\n          \u003ctd\u003e查找和替换\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+Shift+F\u003c/td\u003e\n          \u003ctd\u003e在文件中查找\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+`\u003c/td\u003e\n          \u003ctd\u003e打开/关闭终端\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"代码编辑快捷键\"\u003e代码编辑快捷键\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e快捷键\u003c/th\u003e\n          \u003cth\u003e功能\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+Space\u003c/td\u003e\n          \u003ctd\u003e触发代码补全\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+Shift+Space\u003c/td\u003e\n          \u003ctd\u003e触发参数提示\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eF2\u003c/td\u003e\n          \u003ctd\u003e重命名符号\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+K Ctrl+X\u003c/td\u003e\n          \u003ctd\u003e删除末尾空格\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+Shift+Enter\u003c/td\u003e\n          \u003ctd\u003e在上方插入行\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCtrl+Enter\u003c/td\u003e\n          \u003ctd\u003e在下方插入行\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"推荐扩展\"\u003e推荐扩展\u003c/h2\u003e\n\u003ch3 id=\"1-prettier---code-formatter\"\u003e1. \u003cstrong\u003ePrettier - Code Formatter\u003c/strong\u003e\u003c/h3\u003e\n\u003cp\u003e自动格式化代码，保持代码风格一致。\u003c/p\u003e","title":"VSCode 高效开发技巧"},{"content":"什么是 Docker？ Docker 是一个开源的容器化平台，用于打包、分发和运行应用程序。它通过将应用程序及其依赖项打包到一个轻量级的容器中，确保应用在任何环境中都能一致地运行。\nDocker 的核心概念 镜像（Image） 镜像是一个轻量级的、独立的、可执行的软件包，包含运行应用所需的所有内容（代码、运行时、系统工具、库等）。\n容器（Container） 容器是镜像的运行实例。可以把镜像看作是类，容器就是对象。\n仓库（Repository） 存储镜像的地方。Docker Hub 是最大的公共镜像仓库。\nDockerfile 用于定义如何构建镜像的文本文件。\nDocker 安装 Windows 和 Mac 下载 Docker Desktop：https://www.docker.com/products/docker-desktop\nLinux（Ubuntu） # 更新包管理器 sudo apt-get update # 安装 Docker sudo apt-get install docker.io # 启动 Docker 服务 sudo systemctl start docker # 验证安装 docker --version 基础命令 镜像操作 # 拉取镜像 docker pull ubuntu:latest # 列出本地镜像 docker images # 删除镜像 docker rmi image_id # 搜索镜像 docker search nginx 容器操作 # 运行容器 docker run -d --name my-container ubuntu:latest # 列出运行中的容器 docker ps # 列出所有容器（包括已停止的） docker ps -a # 停止容器 docker stop container_id # 启动容器 docker start container_id # 删除容器 docker rm container_id # 查看容器日志 docker logs container_id # 进入容器 docker exec -it container_id /bin/bash 编写 Dockerfile # 使用基础镜像 FROM python:3.9-slim # 设置工作目录 WORKDIR /app # 复制文件 COPY . . # 安装依赖 RUN pip install -r requirements.txt # 暴露端口 EXPOSE 5000 # 运行应用 CMD [\u0026#34;python\u0026#34;, \u0026#34;app.py\u0026#34;] 构建和运行镜像 # 构建镜像 docker build -t my-app:1.0 . # 运行容器 docker run -d -p 5000:5000 --name my-app-container my-app:1.0 # 查看容器状态 docker ps # 查看日志 docker logs my-app-container Docker Compose Docker Compose 用于定义和运行多容器应用。\ndocker-compose.yml 示例 version: \u0026#39;3\u0026#39; services: web: build: . ports: - \u0026#34;5000:5000\u0026#34; environment: - DATABASE_URL=postgres://db:5432/mydb db: image: postgres:13 environment: - POSTGRES_DB=mydb - POSTGRES_PASSWORD=password volumes: - db_data:/var/lib/postgresql/data volumes: db_data: 运行 Docker Compose # 启动所有服务 docker-compose up -d # 停止所有服务 docker-compose down # 查看日志 docker-compose logs -f 最佳实践 使用官方镜像 - 优先使用官方维护的镜像 最小化镜像大小 - 使用 alpine 基础镜像 使用 .dockerignore - 排除不必要的文件 分层构建 - 充分利用 Docker 的缓存机制 不要以 root 运行 - 创建非 root 用户 使用健康检查 - 定期检查容器健康状态 常见问题 Q: 如何查看容器内的文件？\ndocker exec -it container_id ls -la /app Q: 如何复制文件到容器？\ndocker cp file.txt container_id:/app/ Q: 如何保存容器的更改为新镜像？\ndocker commit container_id my-new-image:1.0 总结 Docker 是现代应用开发和部署的必备工具。通过容器化，你可以确保应用在开发、测试和生产环境中的一致性，大大简化了部署流程。\n","permalink":"https://magicbude.github.io/blog/docker-guide/","summary":"\u003ch2 id=\"什么是-docker\"\u003e什么是 Docker？\u003c/h2\u003e\n\u003cp\u003eDocker 是一个开源的容器化平台，用于打包、分发和运行应用程序。它通过将应用程序及其依赖项打包到一个轻量级的容器中，确保应用在任何环境中都能一致地运行。\u003c/p\u003e\n\u003ch2 id=\"docker-的核心概念\"\u003eDocker 的核心概念\u003c/h2\u003e\n\u003ch3 id=\"镜像image\"\u003e镜像（Image）\u003c/h3\u003e\n\u003cp\u003e镜像是一个轻量级的、独立的、可执行的软件包，包含运行应用所需的所有内容（代码、运行时、系统工具、库等）。\u003c/p\u003e\n\u003ch3 id=\"容器container\"\u003e容器（Container）\u003c/h3\u003e\n\u003cp\u003e容器是镜像的运行实例。可以把镜像看作是类，容器就是对象。\u003c/p\u003e\n\u003ch3 id=\"仓库repository\"\u003e仓库（Repository）\u003c/h3\u003e\n\u003cp\u003e存储镜像的地方。Docker Hub 是最大的公共镜像仓库。\u003c/p\u003e\n\u003ch3 id=\"dockerfile\"\u003eDockerfile\u003c/h3\u003e\n\u003cp\u003e用于定义如何构建镜像的文本文件。\u003c/p\u003e\n\u003ch2 id=\"docker-安装\"\u003eDocker 安装\u003c/h2\u003e\n\u003ch3 id=\"windows-和-mac\"\u003eWindows 和 Mac\u003c/h3\u003e\n\u003cp\u003e下载 Docker Desktop：https://www.docker.com/products/docker-desktop\u003c/p\u003e\n\u003ch3 id=\"linuxubuntu\"\u003eLinux（Ubuntu）\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 更新包管理器\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo apt-get update\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 安装 Docker\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo apt-get install docker.io\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 启动 Docker 服务\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo systemctl start docker\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 验证安装\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edocker --version\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"基础命令\"\u003e基础命令\u003c/h2\u003e\n\u003ch3 id=\"镜像操作\"\u003e镜像操作\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 拉取镜像\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edocker pull ubuntu:latest\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 列出本地镜像\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edocker images\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 删除镜像\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edocker rmi image_id\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 搜索镜像\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edocker search nginx\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"容器操作\"\u003e容器操作\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 运行容器\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edocker run -d --name my-container ubuntu:latest\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 列出运行中的容器\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edocker ps\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 列出所有容器（包括已停止的）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edocker ps -a\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 停止容器\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edocker stop container_id\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 启动容器\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edocker start container_id\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 删除容器\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edocker rm container_id\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 查看容器日志\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edocker logs container_id\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 进入容器\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edocker \u003cspan class=\"nb\"\u003eexec\u003c/span\u003e -it container_id /bin/bash\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"编写-dockerfile\"\u003e编写 Dockerfile\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dockerfile\" data-lang=\"dockerfile\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e# 使用基础镜像\u003c/span\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003epython:3.9-slim\u003c/span\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\u003c/span\u003e\u003cspan class=\"c\"\u003e# 设置工作目录\u003c/span\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eWORKDIR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e/app\u003c/span\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\u003c/span\u003e\u003cspan class=\"c\"\u003e# 复制文件\u003c/span\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCOPY\u003c/span\u003e . .\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\u003c/span\u003e\u003cspan class=\"c\"\u003e# 安装依赖\u003c/span\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eRUN\u003c/span\u003e pip install -r requirements.txt\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\u003c/span\u003e\u003cspan class=\"c\"\u003e# 暴露端口\u003c/span\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eEXPOSE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e5000\u003c/span\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\u003c/span\u003e\u003cspan class=\"c\"\u003e# 运行应用\u003c/span\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCMD\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;python\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;app.py\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"err\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"构建和运行镜像\"\u003e构建和运行镜像\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 构建镜像\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edocker build -t my-app:1.0 .\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 运行容器\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edocker run -d -p 5000:5000 --name my-app-container my-app:1.0\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 查看容器状态\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edocker ps\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 查看日志\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edocker logs my-app-container\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"docker-compose\"\u003eDocker Compose\u003c/h2\u003e\n\u003cp\u003eDocker Compose 用于定义和运行多容器应用。\u003c/p\u003e","title":"Docker 容器化完全指南"},{"content":"介绍 Git 基础知识很重要，但掌握进阶技巧能让你的开发工作流更高效。本文介绍一些实用的 Git 进阶技巧。\n分支管理 创建和切换分支 # 创建新分支 git branch feature/new-feature # 切换分支 git checkout feature/new-feature # 创建并切换分支（简写） git checkout -b feature/new-feature # 或使用新语法 git switch -c feature/new-feature 删除分支 # 删除本地分支 git branch -d feature/new-feature # 强制删除分支 git branch -D feature/new-feature # 删除远程分支 git push origin --delete feature/new-feature 分支重命名 # 重命名当前分支 git branch -m new-name # 重命名其他分支 git branch -m old-name new-name # 推送重命名后的分支 git push origin new-name git push origin --delete old-name 变基（Rebase） 变基是一种整理提交历史的强大工具。\n基本变基 # 将当前分支变基到 main git rebase main # 交互式变基（最后 3 个提交） git rebase -i HEAD~3 交互式变基的操作 在交互式变基中，你可以：\npick - 使用提交 reword - 使用提交，但修改提交信息 squash - 使用提交，但将其合并到前一个提交 fixup - 类似 squash，但丢弃提交信息 drop - 删除提交 变基示例 # 合并最后 3 个提交 git rebase -i HEAD~3 # 在编辑器中将后两个 pick 改为 squash # pick abc1234 First commit # squash def5678 Second commit # squash ghi9012 Third commit # 保存并退出，编辑合并后的提交信息 樱桃选择（Cherry-pick） 从其他分支选择特定的提交应用到当前分支。\n# 应用单个提交 git cherry-pick abc1234 # 应用多个提交 git cherry-pick abc1234 def5678 ghi9012 # 应用一个范围的提交 git cherry-pick abc1234..ghi9012 # 应用范围（包括起始提交） git cherry-pick abc1234^..ghi9012 撤销更改 撤销工作区的更改 # 撤销单个文件的更改 git checkout -- file.txt # 撤销所有更改 git checkout -- . # 或使用新语法 git restore file.txt 撤销暂存区的更改 # 取消暂存单个文件 git reset HEAD file.txt # 取消暂存所有文件 git reset HEAD # 或使用新语法 git restore --staged file.txt 撤销已提交的更改 # 创建一个新提交来撤销之前的提交 git revert abc1234 # 修改最后一个提交（不改变历史） git commit --amend # 修改最后一个提交并修改提交信息 git commit --amend -m \u0026#34;New message\u0026#34; 查看历史 查看提交日志 # 查看简洁的日志 git log --oneline # 查看图形化的分支历史 git log --graph --oneline --all # 查看特定文件的历史 git log -- file.txt # 查看某个作者的提交 git log --author=\u0026#34;John Doe\u0026#34; # 查看最近 N 个提交 git log -n 5 查看提交的详细信息 # 查看某个提交的详细信息 git show abc1234 # 查看某个提交的更改 git show abc1234 --stat 搜索和查找 搜索提交信息 # 搜索包含特定文本的提交 git log --grep=\u0026#34;bug fix\u0026#34; # 搜索包含特定代码的提交 git log -S \u0026#34;function_name\u0026#34; # 搜索修改特定文件的提交 git log -- path/to/file.txt 查找引入 bug 的提交 # 使用 bisect 二分查找 git bisect start # 标记当前提交为坏的 git bisect bad # 标记某个提交为好的 git bisect good abc1234 # Git 会自动检出中间的提交，你可以测试 # 然后继续标记为好或坏 git bisect good # 或 git bisect bad # 完成后 git bisect reset 标签（Tags） 标签用于标记重要的版本。\n# 创建轻量级标签 git tag v1.0.0 # 创建带注释的标签 git tag -a v1.0.0 -m \u0026#34;Version 1.0.0\u0026#34; # 列出标签 git tag # 查看标签信息 git show v1.0.0 # 推送标签到远程 git push origin v1.0.0 # 推送所有标签 git push origin --tags # 删除本地标签 git tag -d v1.0.0 # 删除远程标签 git push origin --delete v1.0.0 存储（Stash） 临时保存未提交的更改。\n# 保存当前更改 git stash # 保存并添加描述 git stash save \u0026#34;description\u0026#34; # 列出所有存储 git stash list # 应用最新的存储 git stash apply # 应用特定的存储 git stash apply stash@{0} # 应用并删除存储 git stash pop # 删除存储 git stash drop stash@{0} # 删除所有存储 git stash clear 常见工作流 功能分支工作流 # 从 main 创建功能分支 git checkout -b feature/user-auth main # 在功能分支上工作 git add . git commit -m \u0026#34;Add user authentication\u0026#34; # 推送到远程 git push origin feature/user-auth # 创建 Pull Request，审查后合并 # 删除功能分支 git branch -d feature/user-auth 修复紧急 bug # 从 main 创建修复分支 git checkout -b hotfix/critical-bug main # 修复 bug git add . git commit -m \u0026#34;Fix critical bug\u0026#34; # 推送并创建 Pull Request git push origin hotfix/critical-bug # 合并后，同步到开发分支 git checkout develop git pull origin develop git merge main 总结 掌握这些 Git 进阶技巧能让你的版本控制工作更高效。关键是要理解每个命令的含义，并在实际项目中多加练习。\n","permalink":"https://magicbude.github.io/blog/git-advanced-tips/","summary":"\u003ch2 id=\"介绍\"\u003e介绍\u003c/h2\u003e\n\u003cp\u003eGit 基础知识很重要，但掌握进阶技巧能让你的开发工作流更高效。本文介绍一些实用的 Git 进阶技巧。\u003c/p\u003e\n\u003ch2 id=\"分支管理\"\u003e分支管理\u003c/h2\u003e\n\u003ch3 id=\"创建和切换分支\"\u003e创建和切换分支\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 创建新分支\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit branch feature/new-feature\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 切换分支\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit checkout feature/new-feature\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 创建并切换分支（简写）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit checkout -b feature/new-feature\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 或使用新语法\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit switch -c feature/new-feature\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"删除分支\"\u003e删除分支\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 删除本地分支\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit branch -d feature/new-feature\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 强制删除分支\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit branch -D feature/new-feature\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 删除远程分支\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit push origin --delete feature/new-feature\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"分支重命名\"\u003e分支重命名\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 重命名当前分支\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit branch -m new-name\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 重命名其他分支\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit branch -m old-name new-name\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 推送重命名后的分支\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit push origin new-name\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit push origin --delete old-name\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"变基rebase\"\u003e变基（Rebase）\u003c/h2\u003e\n\u003cp\u003e变基是一种整理提交历史的强大工具。\u003c/p\u003e","title":"Git 进阶技巧和工作流"},{"content":"为什么性能很重要？ 网站性能直接影响用户体验和搜索引擎排名。研究表明，页面加载时间每增加 1 秒，转化率就会下降 7%。\n性能指标 核心 Web 指标（Core Web Vitals） LCP（Largest Contentful Paint） - 最大内容绘制\n衡量页面主要内容加载的速度 目标：\u0026lt; 2.5 秒 FID（First Input Delay） - 首次输入延迟\n衡量用户交互的响应速度 目标：\u0026lt; 100 毫秒 CLS（Cumulative Layout Shift） - 累积布局偏移\n衡量页面稳定性 目标：\u0026lt; 0.1 其他重要指标 TTFB（Time to First Byte） - 首字节时间 FCP（First Contentful Paint） - 首次内容绘制 TTI（Time to Interactive） - 可交互时间 性能优化策略 1. 资源优化 图片优化 // 使用现代格式（WebP） \u0026lt;picture\u0026gt; \u0026lt;source srcset=\u0026#34;image.webp\u0026#34; type=\u0026#34;image/webp\u0026#34;\u0026gt; \u0026lt;img src=\u0026#34;image.jpg\u0026#34; alt=\u0026#34;description\u0026#34;\u0026gt; \u0026lt;/picture\u0026gt; // 使用响应式图片 \u0026lt;img srcset=\u0026#34;small.jpg 480w, medium.jpg 800w, large.jpg 1200w\u0026#34; sizes=\u0026#34;(max-width: 600px) 480px, 800px\u0026#34; src=\u0026#34;medium.jpg\u0026#34; alt=\u0026#34;description\u0026#34;\u0026gt; // 使用 CDN 和图片压缩服务 // 例如：Cloudinary, ImageKit 等 CSS 优化 /* 移除未使用的 CSS */ /* 使用 PurgeCSS 或 Tailwind CSS 的 purge 功能 */ /* 内联关键 CSS */ \u0026lt;style\u0026gt; /* 首屏必需的 CSS */ \u0026lt;/style\u0026gt; \u0026lt;link rel=\u0026#34;stylesheet\u0026#34; href=\u0026#34;non-critical.css\u0026#34; media=\u0026#34;print\u0026#34; onload=\u0026#34;this.media=\u0026#39;all\u0026#39;\u0026#34;\u0026gt; /* 使用 CSS 变量减少重复 */ :root { --primary-color: #007bff; --spacing-unit: 8px; } JavaScript 优化 // 代码分割 import { lazy, Suspense } from \u0026#39;react\u0026#39;; const HeavyComponent = lazy(() =\u0026gt; import(\u0026#39;./HeavyComponent\u0026#39;)); // 延迟加载非关键脚本 \u0026lt;script defer src=\u0026#34;analytics.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;script async src=\u0026#34;ads.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; // 使用 Web Workers 处理耗时任务 const worker = new Worker(\u0026#39;worker.js\u0026#39;); worker.postMessage({ data: largeData }); worker.onmessage = (e) =\u0026gt; { console.log(\u0026#39;Result:\u0026#39;, e.data); }; 2. 缓存策略 浏览器缓存 // 设置缓存头 // HTTP 响应头 Cache-Control: max-age=31536000 // 1 年 Cache-Control: max-age=3600, must-revalidate // 1 小时，需要验证 // 使用 ETag 进行条件请求 If-None-Match: \u0026#34;33a64df...\u0026#34; Service Worker 缓存 // service-worker.js const CACHE_NAME = \u0026#39;v1\u0026#39;; const urlsToCache = [ \u0026#39;/\u0026#39;, \u0026#39;/styles/main.css\u0026#39;, \u0026#39;/script/main.js\u0026#39; ]; self.addEventListener(\u0026#39;install\u0026#39;, (event) =\u0026gt; { event.waitUntil( caches.open(CACHE_NAME).then((cache) =\u0026gt; { return cache.addAll(urlsToCache); }) ); }); self.addEventListener(\u0026#39;fetch\u0026#39;, (event) =\u0026gt; { event.respondWith( caches.match(event.request).then((response) =\u0026gt; { return response || fetch(event.request); }) ); }); 3. 代码分割和懒加载 // 路由级别的代码分割 const routes = [ { path: \u0026#39;/\u0026#39;, component: () =\u0026gt; import(\u0026#39;./pages/Home\u0026#39;) }, { path: \u0026#39;/about\u0026#39;, component: () =\u0026gt; import(\u0026#39;./pages/About\u0026#39;) } ]; // 组件级别的懒加载 const LazyImage = lazy(() =\u0026gt; import(\u0026#39;./LazyImage\u0026#39;)); // 使用 Intersection Observer 实现图片懒加载 const imageObserver = new IntersectionObserver((entries) =\u0026gt; { entries.forEach((entry) =\u0026gt; { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src; imageObserver.unobserve(img); } }); }); document.querySelectorAll(\u0026#39;img[data-src]\u0026#39;).forEach((img) =\u0026gt; { imageObserver.observe(img); }); 4. 网络优化 DNS 预解析 \u0026lt;link rel=\u0026#34;dns-prefetch\u0026#34; href=\u0026#34;https://example.com\u0026#34;\u0026gt; \u0026lt;link rel=\u0026#34;preconnect\u0026#34; href=\u0026#34;https://fonts.googleapis.com\u0026#34;\u0026gt; 资源预加载 \u0026lt;!-- 预加载关键资源 --\u0026gt; \u0026lt;link rel=\u0026#34;preload\u0026#34; href=\u0026#34;font.woff2\u0026#34; as=\u0026#34;font\u0026#34; type=\u0026#34;font/woff2\u0026#34; crossorigin\u0026gt; \u0026lt;link rel=\u0026#34;preload\u0026#34; href=\u0026#34;critical.js\u0026#34; as=\u0026#34;script\u0026#34;\u0026gt; \u0026lt;!-- 预连接 --\u0026gt; \u0026lt;link rel=\u0026#34;preconnect\u0026#34; href=\u0026#34;https://api.example.com\u0026#34;\u0026gt; \u0026lt;!-- 预获取非关键资源 --\u0026gt; \u0026lt;link rel=\u0026#34;prefetch\u0026#34; href=\u0026#34;next-page.js\u0026#34;\u0026gt; 使用 CDN // 使用 CDN 分发静态资源 // 例如：Cloudflare, AWS CloudFront, Akamai 等 // 在 HTML 中使用 CDN URL \u0026lt;script src=\u0026#34;https://cdn.example.com/script.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;link rel=\u0026#34;stylesheet\u0026#34; href=\u0026#34;https://cdn.example.com/style.css\u0026#34;\u0026gt; 5. 渲染优化 避免重排和重绘 // 不好的做法 - 多次重排 for (let i = 0; i \u0026lt; 100; i++) { element.style.width = element.offsetWidth + 1 + \u0026#39;px\u0026#39;; } // 好的做法 - 批量修改 const width = element.offsetWidth; for (let i = 0; i \u0026lt; 100; i++) { element.style.width = (width + i) + \u0026#39;px\u0026#39;; } // 或使用 requestAnimationFrame let width = element.offsetWidth; function update() { element.style.width = width + \u0026#39;px\u0026#39;; width++; } requestAnimationFrame(update); 虚拟滚动 // 只渲染可见的列表项 import { FixedSizeList } from \u0026#39;react-window\u0026#39;; const Row = ({ index, style }) =\u0026gt; ( \u0026lt;div style={style}\u0026gt;Item {index}\u0026lt;/div\u0026gt; ); \u0026lt;FixedSizeList height={600} itemCount={1000} itemSize={35} width=\u0026#34;100%\u0026#34; \u0026gt; {Row} \u0026lt;/FixedSizeList\u0026gt; 6. 监控和分析 使用 Web Vitals 库 import { getCLS, getFID, getFCP, getLCP, getTTFB } from \u0026#39;web-vitals\u0026#39;; getCLS(console.log); getFID(console.log); getFCP(console.log); getLCP(console.log); getTTFB(console.log); 性能监控 API // 使用 Performance API const perfData = window.performance.timing; const pageLoadTime = perfData.loadEventEnd - perfData.navigationStart; console.log(\u0026#39;Page load time:\u0026#39;, pageLoadTime); // 使用 PerformanceObserver const observer = new PerformanceObserver((list) =\u0026gt; { for (const entry of list.getEntries()) { console.log(\u0026#39;Entry:\u0026#39;, entry); } }); observer.observe({ entryTypes: [\u0026#39;navigation\u0026#39;, \u0026#39;resource\u0026#39;, \u0026#39;paint\u0026#39;] }); 性能优化检查清单 图片已优化和压缩 使用了现代图片格式（WebP） CSS 已最小化和分割 JavaScript 已分割和懒加载 关键资源已预加载 使用了 Service Worker 缓存 已配置 CDN 已移除未使用的代码 已启用 Gzip 压缩 已配置浏览器缓存 已优化字体加载 已测试核心 Web 指标 性能测试工具 Google PageSpeed Insights - https://pagespeed.web.dev WebPageTest - https://www.webpagetest.org Lighthouse - Chrome DevTools 内置 GTmetrix - https://gtmetrix.com 总结 前端性能优化是一个持续的过程。通过实施这些优化策略，你可以显著提升网站的加载速度和用户体验。记住，性能优化的关键是测量、优化、验证。\n","permalink":"https://magicbude.github.io/blog/frontend-performance/","summary":"\u003ch2 id=\"为什么性能很重要\"\u003e为什么性能很重要？\u003c/h2\u003e\n\u003cp\u003e网站性能直接影响用户体验和搜索引擎排名。研究表明，页面加载时间每增加 1 秒，转化率就会下降 7%。\u003c/p\u003e\n\u003ch2 id=\"性能指标\"\u003e性能指标\u003c/h2\u003e\n\u003ch3 id=\"核心-web-指标core-web-vitals\"\u003e核心 Web 指标（Core Web Vitals）\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003eLCP（Largest Contentful Paint）\u003c/strong\u003e - 最大内容绘制\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e衡量页面主要内容加载的速度\u003c/li\u003e\n\u003cli\u003e目标：\u0026lt; 2.5 秒\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eFID（First Input Delay）\u003c/strong\u003e - 首次输入延迟\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e衡量用户交互的响应速度\u003c/li\u003e\n\u003cli\u003e目标：\u0026lt; 100 毫秒\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eCLS（Cumulative Layout Shift）\u003c/strong\u003e - 累积布局偏移\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e衡量页面稳定性\u003c/li\u003e\n\u003cli\u003e目标：\u0026lt; 0.1\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"其他重要指标\"\u003e其他重要指标\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eTTFB（Time to First Byte）\u003c/strong\u003e - 首字节时间\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eFCP（First Contentful Paint）\u003c/strong\u003e - 首次内容绘制\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eTTI（Time to Interactive）\u003c/strong\u003e - 可交互时间\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"性能优化策略\"\u003e性能优化策略\u003c/h2\u003e\n\u003ch3 id=\"1-资源优化\"\u003e1. 资源优化\u003c/h3\u003e\n\u003ch4 id=\"图片优化\"\u003e图片优化\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 使用现代格式（WebP）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nx\"\u003epicture\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nx\"\u003esource\u003c/span\u003e \u003cspan class=\"nx\"\u003esrcset\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;image.webp\u0026#34;\u003c/span\u003e \u003cspan class=\"nx\"\u003etype\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;image/webp\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nx\"\u003eimg\u003c/span\u003e \u003cspan class=\"nx\"\u003esrc\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;image.jpg\u0026#34;\u003c/span\u003e \u003cspan class=\"nx\"\u003ealt\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;description\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"err\"\u003e/picture\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 使用响应式图片\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nx\"\u003eimg\u003c/span\u003e \u003cspan class=\"nx\"\u003esrcset\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;small.jpg 480w, medium.jpg 800w, large.jpg 1200w\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e     \u003cspan class=\"nx\"\u003esizes\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;(max-width: 600px) 480px, 800px\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e     \u003cspan class=\"nx\"\u003esrc\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;medium.jpg\u0026#34;\u003c/span\u003e \u003cspan class=\"nx\"\u003ealt\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;description\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 使用 CDN 和图片压缩服务\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 例如：Cloudinary, ImageKit 等\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"css-优化\"\u003eCSS 优化\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-css\" data-lang=\"css\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e/* 移除未使用的 CSS */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e/* 使用 PurgeCSS 或 Tailwind CSS 的 purge 功能 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e/* 内联关键 CSS */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003estyle\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"c\"\u003e/* 首屏必需的 CSS */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003estyle\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003elink\u003c/span\u003e \u003cspan class=\"nt\"\u003erel\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;stylesheet\u0026#34;\u003c/span\u003e \u003cspan class=\"nt\"\u003ehref\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;non-critical.css\u0026#34;\u003c/span\u003e \u003cspan class=\"nt\"\u003emedia\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;print\u0026#34;\u003c/span\u003e \u003cspan class=\"nt\"\u003eonload\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;this.media=\u0026#39;all\u0026#39;\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e/* 使用 CSS 变量减少重复 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"nd\"\u003eroot\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nv\"\u003e--primary-color\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mh\"\u003e#007bff\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nv\"\u003e--spacing-unit\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"kt\"\u003epx\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"javascript-优化\"\u003eJavaScript 优化\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 代码分割\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003eimport\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"nx\"\u003elazy\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eSuspense\u003c/span\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"nx\"\u003efrom\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;react\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eHeavyComponent\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003elazy\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"kr\"\u003eimport\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;./HeavyComponent\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 延迟加载非关键脚本\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nx\"\u003escript\u003c/span\u003e \u003cspan class=\"nx\"\u003edefer\u003c/span\u003e \u003cspan class=\"nx\"\u003esrc\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;analytics.js\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026lt;\u003c/span\u003e\u003cspan class=\"err\"\u003e/script\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nx\"\u003escript\u003c/span\u003e \u003cspan class=\"kr\"\u003easync\u003c/span\u003e \u003cspan class=\"nx\"\u003esrc\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;ads.js\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026lt;\u003c/span\u003e\u003cspan class=\"err\"\u003e/script\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 使用 Web Workers 处理耗时任务\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eworker\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nx\"\u003eWorker\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;worker.js\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003eworker\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003epostMessage\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e \u003cspan class=\"nx\"\u003edata\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003elargeData\u003c/span\u003e \u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003eworker\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eonmessage\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ee\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;Result:\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003ee\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003edata\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"2-缓存策略\"\u003e2. 缓存策略\u003c/h3\u003e\n\u003ch4 id=\"浏览器缓存\"\u003e浏览器缓存\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 设置缓存头\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// HTTP 响应头\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nx\"\u003eCache\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"nx\"\u003eControl\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003emax\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"nx\"\u003eage\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e31536000\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// 1 年\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nx\"\u003eCache\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"nx\"\u003eControl\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003emax\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"nx\"\u003eage\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e3600\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003emust\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"nx\"\u003erevalidate\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// 1 小时，需要验证\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 使用 ETag 进行条件请求\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nx\"\u003eIf\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"nx\"\u003eNone\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"nx\"\u003eMatch\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;33a64df...\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"service-worker-缓存\"\u003eService Worker 缓存\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// service-worker.js\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eCACHE_NAME\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;v1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eurlsToCache\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"s1\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"s1\"\u003e\u0026#39;/styles/main.css\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"s1\"\u003e\u0026#39;/script/main.js\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003eself\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;install\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ewaitUntil\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003ecaches\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eopen\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eCACHE_NAME\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"nx\"\u003ethen\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"nx\"\u003ecache\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nx\"\u003ecache\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddAll\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eurlsToCache\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003eself\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;fetch\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003erespondWith\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003ecaches\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003erequest\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"nx\"\u003ethen\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"nx\"\u003eresponse\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nx\"\u003eresponse\u003c/span\u003e \u003cspan class=\"o\"\u003e||\u003c/span\u003e \u003cspan class=\"nx\"\u003efetch\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003erequest\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"3-代码分割和懒加载\"\u003e3. 代码分割和懒加载\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 路由级别的代码分割\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eroutes\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003epath\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003ecomponent\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"kr\"\u003eimport\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;./pages/Home\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003epath\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;/about\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003ecomponent\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"kr\"\u003eimport\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;./pages/About\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 组件级别的懒加载\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eLazyImage\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003elazy\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"kr\"\u003eimport\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;./LazyImage\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 使用 Intersection Observer 实现图片懒加载\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eimageObserver\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nx\"\u003eIntersectionObserver\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"nx\"\u003eentries\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003eentries\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eforEach\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"nx\"\u003eentry\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eentry\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eisIntersecting\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eimg\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eentry\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etarget\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"nx\"\u003eimg\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003esrc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eimg\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003edataset\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003esrc\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"nx\"\u003eimageObserver\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eunobserve\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eimg\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003edocument\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003equerySelectorAll\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;img[data-src]\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"nx\"\u003eforEach\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"nx\"\u003eimg\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003eimageObserver\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eobserve\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eimg\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"4-网络优化\"\u003e4. 网络优化\u003c/h3\u003e\n\u003ch4 id=\"dns-预解析\"\u003eDNS 预解析\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-html\" data-lang=\"html\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003elink\u003c/span\u003e \u003cspan class=\"na\"\u003erel\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;dns-prefetch\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003ehref\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;https://example.com\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003elink\u003c/span\u003e \u003cspan class=\"na\"\u003erel\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;preconnect\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003ehref\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;https://fonts.googleapis.com\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"资源预加载\"\u003e资源预加载\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-html\" data-lang=\"html\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e\u0026lt;!-- 预加载关键资源 --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003elink\u003c/span\u003e \u003cspan class=\"na\"\u003erel\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;preload\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003ehref\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;font.woff2\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003eas\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;font\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003etype\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;font/woff2\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003ecrossorigin\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003elink\u003c/span\u003e \u003cspan class=\"na\"\u003erel\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;preload\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003ehref\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;critical.js\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003eas\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;script\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e\u0026lt;!-- 预连接 --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003elink\u003c/span\u003e \u003cspan class=\"na\"\u003erel\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;preconnect\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003ehref\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;https://api.example.com\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e\u0026lt;!-- 预获取非关键资源 --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003elink\u003c/span\u003e \u003cspan class=\"na\"\u003erel\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;prefetch\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003ehref\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;next-page.js\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"使用-cdn\"\u003e使用 CDN\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 使用 CDN 分发静态资源\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 例如：Cloudflare, AWS CloudFront, Akamai 等\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 在 HTML 中使用 CDN URL\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nx\"\u003escript\u003c/span\u003e \u003cspan class=\"nx\"\u003esrc\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;https://cdn.example.com/script.js\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026lt;\u003c/span\u003e\u003cspan class=\"err\"\u003e/script\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nx\"\u003elink\u003c/span\u003e \u003cspan class=\"nx\"\u003erel\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;stylesheet\u0026#34;\u003c/span\u003e \u003cspan class=\"nx\"\u003ehref\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;https://cdn.example.com/style.css\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"5-渲染优化\"\u003e5. 渲染优化\u003c/h3\u003e\n\u003ch4 id=\"避免重排和重绘\"\u003e避免重排和重绘\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 不好的做法 - 多次重排\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e \u003cspan class=\"nx\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"nx\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e100\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"nx\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003eelement\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ewidth\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eelement\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eoffsetWidth\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;px\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 好的做法 - 批量修改\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003ewidth\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eelement\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eoffsetWidth\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e \u003cspan class=\"nx\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"nx\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e100\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"nx\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003eelement\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ewidth\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ewidth\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"nx\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;px\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 或使用 requestAnimationFrame\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e \u003cspan class=\"nx\"\u003ewidth\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eelement\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eoffsetWidth\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003eupdate\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003eelement\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ewidth\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003ewidth\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;px\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003ewidth\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003erequestAnimationFrame\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eupdate\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"虚拟滚动\"\u003e虚拟滚动\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 只渲染可见的列表项\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003eimport\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"nx\"\u003eFixedSizeList\u003c/span\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"nx\"\u003efrom\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;react-window\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eRow\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e({\u003c/span\u003e \u003cspan class=\"nx\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003estyle\u003c/span\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nx\"\u003ediv\u003c/span\u003e \u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"nx\"\u003eItem\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"nx\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"err\"\u003e/div\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nx\"\u003eFixedSizeList\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003eheight\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"mi\"\u003e600\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003eitemCount\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"mi\"\u003e1000\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003eitemSize\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"mi\"\u003e35\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003ewidth\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;100%\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"nx\"\u003eRow\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"err\"\u003e/FixedSizeList\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"6-监控和分析\"\u003e6. 监控和分析\u003c/h3\u003e\n\u003ch4 id=\"使用-web-vitals-库\"\u003e使用 Web Vitals 库\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eimport\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"nx\"\u003egetCLS\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003egetFID\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003egetFCP\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003egetLCP\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003egetTTFB\u003c/span\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"nx\"\u003efrom\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;web-vitals\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003egetCLS\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003egetFID\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003egetFCP\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003egetLCP\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003egetTTFB\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"性能监控-api\"\u003e性能监控 API\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 使用 Performance API\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eperfData\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003ewindow\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eperformance\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etiming\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003epageLoadTime\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eperfData\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eloadEventEnd\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"nx\"\u003eperfData\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003enavigationStart\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;Page load time:\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003epageLoadTime\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 使用 PerformanceObserver\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eobserver\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nx\"\u003ePerformanceObserver\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"nx\"\u003elist\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eentry\u003c/span\u003e \u003cspan class=\"k\"\u003eof\u003c/span\u003e \u003cspan class=\"nx\"\u003elist\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003egetEntries\u003c/span\u003e\u003cspan class=\"p\"\u003e())\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;Entry:\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eentry\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003eobserver\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eobserve\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e \u003cspan class=\"nx\"\u003eentryTypes\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;navigation\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;resource\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;paint\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"性能优化检查清单\"\u003e性能优化检查清单\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 图片已优化和压缩\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 使用了现代图片格式（WebP）\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e CSS 已最小化和分割\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e JavaScript 已分割和懒加载\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 关键资源已预加载\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 使用了 Service Worker 缓存\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 已配置 CDN\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 已移除未使用的代码\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 已启用 Gzip 压缩\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 已配置浏览器缓存\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 已优化字体加载\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 已测试核心 Web 指标\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"性能测试工具\"\u003e性能测试工具\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eGoogle PageSpeed Insights\u003c/strong\u003e - \u003ca href=\"https://pagespeed.web.dev\"\u003ehttps://pagespeed.web.dev\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eWebPageTest\u003c/strong\u003e - \u003ca href=\"https://www.webpagetest.org\"\u003ehttps://www.webpagetest.org\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eLighthouse\u003c/strong\u003e - Chrome DevTools 内置\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eGTmetrix\u003c/strong\u003e - \u003ca href=\"https://gtmetrix.com\"\u003ehttps://gtmetrix.com\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"总结\"\u003e总结\u003c/h2\u003e\n\u003cp\u003e前端性能优化是一个持续的过程。通过实施这些优化策略，你可以显著提升网站的加载速度和用户体验。记住，性能优化的关键是测量、优化、验证。\u003c/p\u003e","title":"前端性能优化完全指南"},{"content":"什么是正则表达式？ 正则表达式（Regular Expression，简称 Regex）是一种用于匹配字符串的强大工具。它使用特定的语法来描述字符串的模式，可以用于搜索、替换、验证等操作。\n基础语法 字符类 . 匹配任意单个字符（除了换行符） \\d 匹配数字 [0-9] \\D 匹配非数字 \\w 匹配字母、数字、下划线 [a-zA-Z0-9_] \\W 匹配非字母、数字、下划线 \\s 匹配空白字符（空格、制表符、换行符等） \\S 匹配非空白字符 [abc] 匹配 a、b 或 c [a-z] 匹配 a 到 z 的任意字符 [^abc] 匹配除了 a、b、c 之外的任意字符 量词 * 匹配 0 次或多次 + 匹配 1 次或多次 ? 匹配 0 次或 1 次 {n} 匹配恰好 n 次 {n,} 匹配至少 n 次 {n,m} 匹配 n 到 m 次 锚点 ^ 匹配字符串的开始 $ 匹配字符串的结束 \\b 匹配单词边界 \\B 匹配非单词边界 分组和引用 (abc) 分组，捕获 abc (?:abc) 非捕获分组 (a|b) 匹配 a 或 b \\1 引用第一个捕获组 常见模式 验证电子邮件 ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$ 验证电话号码（中国） ^1[3-9]\\d{9}$ 验证 URL ^https?://[^\\s/$.?#].[^\\s]*$ 验证 IP 地址 ^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ 验证身份证号（简化版） ^\\d{17}[\\dXx]$ 匹配 HTML 标签 \u0026lt;([a-z]+)([^\u0026gt;]*)\u0026gt;(.*?)\u0026lt;/\\1\u0026gt; JavaScript 中的正则表达式 创建正则表达式 // 字面量方式 const regex1 = /hello/i; // 构造函数方式 const regex2 = new RegExp(\u0026#39;hello\u0026#39;, \u0026#39;i\u0026#39;); 常用方法 test() - 测试是否匹配 const regex = /hello/i; console.log(regex.test(\u0026#39;Hello World\u0026#39;)); // true console.log(regex.test(\u0026#39;Goodbye\u0026#39;)); // false exec() - 执行匹配 const regex = /(\\d+)-(\\d+)-(\\d+)/; const result = regex.exec(\u0026#39;2025-12-15\u0026#39;); console.log(result[0]); // \u0026#34;2025-12-15\u0026#34; console.log(result[1]); // \u0026#34;2025\u0026#34; console.log(result[2]); // \u0026#34;12\u0026#34; console.log(result[3]); // \u0026#34;15\u0026#34; match() - 字符串方法 const str = \u0026#39;The year is 2025\u0026#39;; const matches = str.match(/\\d+/g); console.log(matches); // [\u0026#34;2025\u0026#34;] replace() - 替换 const str = \u0026#39;Hello World\u0026#39;; const result = str.replace(/world/i, \u0026#39;JavaScript\u0026#39;); console.log(result); // \u0026#34;Hello JavaScript\u0026#34; // 使用捕获组 const date = \u0026#39;2025-12-15\u0026#39;; const formatted = date.replace(/(\\d+)-(\\d+)-(\\d+)/, \u0026#39;$3/$2/$1\u0026#39;); console.log(formatted); // \u0026#34;15/12/2025\u0026#34; split() - 分割 const str = \u0026#39;apple,banana;orange:grape\u0026#39;; const fruits = str.split(/[,;:]/); console.log(fruits); // [\u0026#34;apple\u0026#34;, \u0026#34;banana\u0026#34;, \u0026#34;orange\u0026#34;, \u0026#34;grape\u0026#34;] search() - 查找位置 const str = \u0026#39;Hello World\u0026#39;; const index = str.search(/world/i); console.log(index); // 6 高级用法 前向断言和后向断言 (?=pattern) 正向前向断言 - 匹配后面跟着 pattern 的位置 (?!pattern) 负向前向断言 - 匹配后面不跟着 pattern 的位置 (?\u0026lt;=pattern) 正向后向断言 - 匹配前面跟着 pattern 的位置 (?\u0026lt;!pattern) 负向后向断言 - 匹配前面不跟着 pattern 的位置 示例 // 匹配不是 .jpg 的文件名 const regex = /\\w+(?!\\.jpg)$/i; // 匹配价格（前面有 $ 符号） const regex = /(?\u0026lt;=\\$)\\d+(\\.\\d{2})?/; // 在 JavaScript 中使用 const str = \u0026#39;$100 and $50.99\u0026#39;; const prices = str.match(/(?\u0026lt;=\\$)\\d+(\\.\\d{2})?/g); console.log(prices); // [\u0026#34;100\u0026#34;, \u0026#34;50.99\u0026#34;] 贪心和非贪心匹配 const str = \u0026#39;\u0026lt;div\u0026gt;Hello\u0026lt;/div\u0026gt;\u0026lt;div\u0026gt;World\u0026lt;/div\u0026gt;\u0026#39;; // 贪心匹配（默认） const greedy = str.match(/\u0026lt;div\u0026gt;.*\u0026lt;\\/div\u0026gt;/); console.log(greedy[0]); // \u0026#34;\u0026lt;div\u0026gt;Hello\u0026lt;/div\u0026gt;\u0026lt;div\u0026gt;World\u0026lt;/div\u0026gt;\u0026#34; // 非贪心匹配 const nonGreedy = str.match(/\u0026lt;div\u0026gt;.*?\u0026lt;\\/div\u0026gt;/g); console.log(nonGreedy); // [\u0026#34;\u0026lt;div\u0026gt;Hello\u0026lt;/div\u0026gt;\u0026#34;, \u0026#34;\u0026lt;div\u0026gt;World\u0026lt;/div\u0026gt;\u0026#34;] 实用示例 验证密码强度 function validatePassword(password) { const regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?\u0026amp;])[A-Za-z\\d@$!%*?\u0026amp;]{8,}$/; return regex.test(password); } console.log(validatePassword(\u0026#39;Weak123\u0026#39;)); // false console.log(validatePassword(\u0026#39;Strong@123\u0026#39;)); // true 提取 URL 参数 function getUrlParams(url) { const params = {}; const regex = /[?\u0026amp;]([^=]+)=([^\u0026amp;]*)/g; let match; while ((match = regex.exec(url)) !== null) { params[match[1]] = decodeURIComponent(match[2]); } return params; } const url = \u0026#39;https://example.com?name=John\u0026amp;age=30\u0026#39;; console.log(getUrlParams(url)); // { name: \u0026#39;John\u0026#39;, age: \u0026#39;30\u0026#39; } 驼峰转下划线 function camelToSnake(str) { return str.replace(/([A-Z])/g, \u0026#39;_$1\u0026#39;).toLowerCase(); } console.log(camelToSnake(\u0026#39;getUserName\u0026#39;)); // \u0026#34;get_user_name\u0026#34; 下划线转驼峰 function snakeToCamel(str) { return str.replace(/_([a-z])/g, (match, letter) =\u0026gt; letter.toUpperCase()); } console.log(snakeToCamel(\u0026#39;get_user_name\u0026#39;)); // \u0026#34;getUserName\u0026#34; 移除 HTML 标签 function stripHtmlTags(html) { return html.replace(/\u0026lt;[^\u0026gt;]*\u0026gt;/g, \u0026#39;\u0026#39;); } console.log(stripHtmlTags(\u0026#39;\u0026lt;p\u0026gt;Hello \u0026lt;b\u0026gt;World\u0026lt;/b\u0026gt;\u0026lt;/p\u0026gt;\u0026#39;)); // \u0026#34;Hello World\u0026#34; 正则表达式标志 g 全局匹配（找到所有匹配项） i 不区分大小写 m 多行匹配 s 使 . 匹配换行符 u Unicode 模式 y 粘性匹配 性能优化建议 避免过度回溯 - 使用具体的模式而不是过于宽泛的模式 使用非捕获分组 - 如果不需要捕获，使用 (?:...) 而不是 (...) 避免嵌套量词 - 如 (a+)+ 可能导致性能问题 使用字符类而不是交替 - [abc] 比 (a|b|c) 更快 预编译正则表达式 - 避免在循环中重复创建正则表达式 常见错误 // 错误：忘记转义特殊字符 const regex = /\\./; // 匹配任意字符，不是点号 // 正确：转义点号 const regex = /\\./; // 匹配点号 // 错误：在字符类中不需要转义某些字符 const regex = /[\\d\\-]/; // 在字符类中，- 应该在开头或结尾 // 正确 const regex = /[\\d-]/; // 或 /[-\\d]/ 在线工具 Regex101 - https://regex101.com RegexPal - https://www.regexpal.com Regex Tester - https://www.regextester.com 总结 正则表达式是文本处理的强大工具。虽然学习曲线陡峭，但掌握它能大大提高开发效率。记住，实践是学习正则表达式的最好方法。\n","permalink":"https://magicbude.github.io/blog/regex-guide/","summary":"\u003ch2 id=\"什么是正则表达式\"\u003e什么是正则表达式？\u003c/h2\u003e\n\u003cp\u003e正则表达式（Regular Expression，简称 Regex）是一种用于匹配字符串的强大工具。它使用特定的语法来描述字符串的模式，可以用于搜索、替换、验证等操作。\u003c/p\u003e\n\u003ch2 id=\"基础语法\"\u003e基础语法\u003c/h2\u003e\n\u003ch3 id=\"字符类\"\u003e字符类\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode class=\"language-regex\" data-lang=\"regex\"\u003e.       匹配任意单个字符（除了换行符）\n\\d      匹配数字 [0-9]\n\\D      匹配非数字\n\\w      匹配字母、数字、下划线 [a-zA-Z0-9_]\n\\W      匹配非字母、数字、下划线\n\\s      匹配空白字符（空格、制表符、换行符等）\n\\S      匹配非空白字符\n[abc]   匹配 a、b 或 c\n[a-z]   匹配 a 到 z 的任意字符\n[^abc]  匹配除了 a、b、c 之外的任意字符\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"量词\"\u003e量词\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode class=\"language-regex\" data-lang=\"regex\"\u003e*       匹配 0 次或多次\n+       匹配 1 次或多次\n?       匹配 0 次或 1 次\n{n}     匹配恰好 n 次\n{n,}    匹配至少 n 次\n{n,m}   匹配 n 到 m 次\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"锚点\"\u003e锚点\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode class=\"language-regex\" data-lang=\"regex\"\u003e^       匹配字符串的开始\n$       匹配字符串的结束\n\\b      匹配单词边界\n\\B      匹配非单词边界\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"分组和引用\"\u003e分组和引用\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode class=\"language-regex\" data-lang=\"regex\"\u003e(abc)       分组，捕获 abc\n(?:abc)     非捕获分组\n(a|b)       匹配 a 或 b\n\\1          引用第一个捕获组\n\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"常见模式\"\u003e常见模式\u003c/h2\u003e\n\u003ch3 id=\"验证电子邮件\"\u003e验证电子邮件\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode class=\"language-regex\" data-lang=\"regex\"\u003e^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"验证电话号码中国\"\u003e验证电话号码（中国）\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode class=\"language-regex\" data-lang=\"regex\"\u003e^1[3-9]\\d{9}$\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"验证-url\"\u003e验证 URL\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode class=\"language-regex\" data-lang=\"regex\"\u003e^https?://[^\\s/$.?#].[^\\s]*$\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"验证-ip-地址\"\u003e验证 IP 地址\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode class=\"language-regex\" data-lang=\"regex\"\u003e^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"验证身份证号简化版\"\u003e验证身份证号（简化版）\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode class=\"language-regex\" data-lang=\"regex\"\u003e^\\d{17}[\\dXx]$\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"匹配-html-标签\"\u003e匹配 HTML 标签\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode class=\"language-regex\" data-lang=\"regex\"\u003e\u0026lt;([a-z]+)([^\u0026gt;]*)\u0026gt;(.*?)\u0026lt;/\\1\u0026gt;\n\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"javascript-中的正则表达式\"\u003eJavaScript 中的正则表达式\u003c/h2\u003e\n\u003ch3 id=\"创建正则表达式\"\u003e创建正则表达式\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 字面量方式\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eregex1\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"sr\"\u003e/hello/i\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 构造函数方式\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eregex2\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nb\"\u003eRegExp\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;hello\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;i\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"常用方法\"\u003e常用方法\u003c/h3\u003e\n\u003ch4 id=\"test---测试是否匹配\"\u003etest() - 测试是否匹配\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eregex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"sr\"\u003e/hello/i\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eregex\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etest\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;Hello World\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// true\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eregex\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etest\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;Goodbye\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e      \u003cspan class=\"c1\"\u003e// false\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"exec---执行匹配\"\u003eexec() - 执行匹配\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eregex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"sr\"\u003e/(\\d+)-(\\d+)-(\\d+)/\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eresult\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eregex\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eexec\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;2025-12-15\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eresult\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e]);\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// \u0026#34;2025-12-15\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eresult\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e]);\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// \u0026#34;2025\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eresult\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e]);\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// \u0026#34;12\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eresult\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e]);\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// \u0026#34;15\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"match---字符串方法\"\u003ematch() - 字符串方法\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003estr\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;The year is 2025\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003ematches\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003estr\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sr\"\u003e/\\d+/g\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ematches\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// [\u0026#34;2025\u0026#34;]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"replace---替换\"\u003ereplace() - 替换\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003estr\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;Hello World\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eresult\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003estr\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ereplace\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sr\"\u003e/world/i\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;JavaScript\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eresult\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// \u0026#34;Hello JavaScript\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 使用捕获组\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003edate\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;2025-12-15\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eformatted\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003edate\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ereplace\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sr\"\u003e/(\\d+)-(\\d+)-(\\d+)/\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;$3/$2/$1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eformatted\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// \u0026#34;15/12/2025\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"split---分割\"\u003esplit() - 分割\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003estr\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;apple,banana;orange:grape\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003efruits\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003estr\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003esplit\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sr\"\u003e/[,;:]/\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003efruits\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// [\u0026#34;apple\u0026#34;, \u0026#34;banana\u0026#34;, \u0026#34;orange\u0026#34;, \u0026#34;grape\u0026#34;]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"search---查找位置\"\u003esearch() - 查找位置\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003estr\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;Hello World\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eindex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003estr\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003esearch\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sr\"\u003e/world/i\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// 6\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"高级用法\"\u003e高级用法\u003c/h2\u003e\n\u003ch3 id=\"前向断言和后向断言\"\u003e前向断言和后向断言\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode class=\"language-regex\" data-lang=\"regex\"\u003e(?=pattern)   正向前向断言 - 匹配后面跟着 pattern 的位置\n(?!pattern)   负向前向断言 - 匹配后面不跟着 pattern 的位置\n(?\u0026lt;=pattern)  正向后向断言 - 匹配前面跟着 pattern 的位置\n(?\u0026lt;!pattern)  负向后向断言 - 匹配前面不跟着 pattern 的位置\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"示例\"\u003e示例\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 匹配不是 .jpg 的文件名\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eregex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"sr\"\u003e/\\w+(?!\\.jpg)$/i\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 匹配价格（前面有 $ 符号）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eregex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"sr\"\u003e/(?\u0026lt;=\\$)\\d+(\\.\\d{2})?/\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 在 JavaScript 中使用\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003estr\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;$100 and $50.99\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eprices\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003estr\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sr\"\u003e/(?\u0026lt;=\\$)\\d+(\\.\\d{2})?/g\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eprices\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// [\u0026#34;100\u0026#34;, \u0026#34;50.99\u0026#34;]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"贪心和非贪心匹配\"\u003e贪心和非贪心匹配\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003estr\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\u0026lt;div\u0026gt;Hello\u0026lt;/div\u0026gt;\u0026lt;div\u0026gt;World\u0026lt;/div\u0026gt;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 贪心匹配（默认）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003egreedy\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003estr\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sr\"\u003e/\u0026lt;div\u0026gt;.*\u0026lt;\\/div\u0026gt;/\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003egreedy\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e]);\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// \u0026#34;\u0026lt;div\u0026gt;Hello\u0026lt;/div\u0026gt;\u0026lt;div\u0026gt;World\u0026lt;/div\u0026gt;\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 非贪心匹配\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003enonGreedy\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003estr\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sr\"\u003e/\u0026lt;div\u0026gt;.*?\u0026lt;\\/div\u0026gt;/g\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003enonGreedy\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// [\u0026#34;\u0026lt;div\u0026gt;Hello\u0026lt;/div\u0026gt;\u0026#34;, \u0026#34;\u0026lt;div\u0026gt;World\u0026lt;/div\u0026gt;\u0026#34;]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"实用示例\"\u003e实用示例\u003c/h2\u003e\n\u003ch3 id=\"验证密码强度\"\u003e验证密码强度\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003evalidatePassword\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003epassword\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eregex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"sr\"\u003e/^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?\u0026amp;])[A-Za-z\\d@$!%*?\u0026amp;]{8,}$/\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nx\"\u003eregex\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etest\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003epassword\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003evalidatePassword\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;Weak123\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e        \u003cspan class=\"c1\"\u003e// false\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003evalidatePassword\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;Strong@123\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e    \u003cspan class=\"c1\"\u003e// true\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"提取-url-参数\"\u003e提取 URL 参数\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003egetUrlParams\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eurl\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eparams\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eregex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"sr\"\u003e/[?\u0026amp;]([^=]+)=([^\u0026amp;]*)/g\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"kd\"\u003elet\u003c/span\u003e \u003cspan class=\"nx\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"nx\"\u003ematch\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eregex\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eexec\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eurl\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e \u003cspan class=\"o\"\u003e!==\u003c/span\u003e \u003cspan class=\"kc\"\u003enull\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003eparams\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"nx\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e]]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003edecodeURIComponent\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e]);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nx\"\u003eparams\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eurl\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;https://example.com?name=John\u0026amp;age=30\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003egetUrlParams\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eurl\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// { name: \u0026#39;John\u0026#39;, age: \u0026#39;30\u0026#39; }\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"驼峰转下划线\"\u003e驼峰转下划线\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003ecamelToSnake\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003estr\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nx\"\u003estr\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ereplace\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sr\"\u003e/([A-Z])/g\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;_$1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"nx\"\u003etoLowerCase\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ecamelToSnake\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;getUserName\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// \u0026#34;get_user_name\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"下划线转驼峰\"\u003e下划线转驼峰\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003esnakeToCamel\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003estr\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nx\"\u003estr\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ereplace\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sr\"\u003e/_([a-z])/g\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eletter\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"nx\"\u003eletter\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etoUpperCase\u003c/span\u003e\u003cspan class=\"p\"\u003e());\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003esnakeToCamel\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;get_user_name\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// \u0026#34;getUserName\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"移除-html-标签\"\u003e移除 HTML 标签\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003estripHtmlTags\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ehtml\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nx\"\u003ehtml\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ereplace\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sr\"\u003e/\u0026lt;[^\u0026gt;]*\u0026gt;/g\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003estripHtmlTags\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u0026lt;p\u0026gt;Hello \u0026lt;b\u0026gt;World\u0026lt;/b\u0026gt;\u0026lt;/p\u0026gt;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// \u0026#34;Hello World\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"正则表达式标志\"\u003e正则表达式标志\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003eg\u003c/span\u003e   \u003cspan class=\"nx\"\u003e全局匹配\u003c/span\u003e\u003cspan class=\"err\"\u003e（\u003c/span\u003e\u003cspan class=\"nx\"\u003e找到所有匹配项\u003c/span\u003e\u003cspan class=\"err\"\u003e）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003ei\u003c/span\u003e   \u003cspan class=\"nx\"\u003e不区分大小写\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003em\u003c/span\u003e   \u003cspan class=\"nx\"\u003e多行匹配\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003es\u003c/span\u003e   \u003cspan class=\"nx\"\u003e使\u003c/span\u003e \u003cspan class=\"p\"\u003e.\u003c/span\u003e \u003cspan class=\"nx\"\u003e匹配换行符\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003eu\u003c/span\u003e   \u003cspan class=\"nx\"\u003eUnicode\u003c/span\u003e \u003cspan class=\"nx\"\u003e模式\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003ey\u003c/span\u003e   \u003cspan class=\"nx\"\u003e粘性匹配\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"性能优化建议\"\u003e性能优化建议\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003e避免过度回溯\u003c/strong\u003e - 使用具体的模式而不是过于宽泛的模式\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e使用非捕获分组\u003c/strong\u003e - 如果不需要捕获，使用 \u003ccode\u003e(?:...)\u003c/code\u003e 而不是 \u003ccode\u003e(...)\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e避免嵌套量词\u003c/strong\u003e - 如 \u003ccode\u003e(a+)+\u003c/code\u003e 可能导致性能问题\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e使用字符类而不是交替\u003c/strong\u003e - \u003ccode\u003e[abc]\u003c/code\u003e 比 \u003ccode\u003e(a|b|c)\u003c/code\u003e 更快\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e预编译正则表达式\u003c/strong\u003e - 避免在循环中重复创建正则表达式\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"常见错误\"\u003e常见错误\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 错误：忘记转义特殊字符\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eregex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"sr\"\u003e/\\./\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// 匹配任意字符，不是点号\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 正确：转义点号\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eregex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"sr\"\u003e/\\./\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// 匹配点号\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 错误：在字符类中不需要转义某些字符\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eregex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"sr\"\u003e/[\\d\\-]/\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// 在字符类中，- 应该在开头或结尾\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 正确\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eregex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"sr\"\u003e/[\\d-]/\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e  \u003cspan class=\"c1\"\u003e// 或 /[-\\d]/\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"在线工具\"\u003e在线工具\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eRegex101\u003c/strong\u003e - \u003ca href=\"https://regex101.com\"\u003ehttps://regex101.com\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eRegexPal\u003c/strong\u003e - \u003ca href=\"https://www.regexpal.com\"\u003ehttps://www.regexpal.com\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eRegex Tester\u003c/strong\u003e - \u003ca href=\"https://www.regextester.com\"\u003ehttps://www.regextester.com\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"总结\"\u003e总结\u003c/h2\u003e\n\u003cp\u003e正则表达式是文本处理的强大工具。虽然学习曲线陡峭，但掌握它能大大提高开发效率。记住，实践是学习正则表达式的最好方法。\u003c/p\u003e","title":"正则表达式完全指南"},{"content":"什么是好的 API？ 好的 API 应该是：\n易于理解 - 清晰的命名和文档 易于使用 - 一致的设计模式 易于维护 - 良好的版本控制和向后兼容性 安全可靠 - 身份验证、授权、速率限制 高性能 - 快速响应和高效的资源使用 RESTful API 原则 基本概念 REST（Representational State Transfer）是一种架构风格，基于以下原则：\n客户端-服务器架构 - 分离关注点 无状态 - 每个请求包含所有必要信息 可缓存 - 响应应该定义自己是否可缓存 统一接口 - 一致的 API 设计 分层系统 - 客户端不知道是否直接连接到最终服务器 HTTP 方法 GET 获取资源 POST 创建新资源 PUT 替换整个资源 PATCH 部分更新资源 DELETE 删除资源 HEAD 获取资源元数据（不返回响应体） OPTIONS 获取资源的通信选项 资源和 URL 设计 好的设计： GET /api/v1/users 获取用户列表 POST /api/v1/users 创建新用户 GET /api/v1/users/:id 获取特定用户 PUT /api/v1/users/:id 更新用户 DELETE /api/v1/users/:id 删除用户 GET /api/v1/users/:id/posts 获取用户的文章 不好的设计： GET /api/getUser GET /api/createUser GET /api/updateUser?id=1 GET /api/deleteUser?id=1 关键原则 使用名词而不是动词 - /users 而不是 /getUsers 使用复数形式 - /users 而不是 /user 使用小写 - /api/users 而不是 /api/Users 使用连字符分隔单词 - /user-profiles 而不是 /userProfiles 避免深层嵌套 - 最多两层 /users/:id/posts 版本控制 URL 版本控制（推荐） /api/v1/users /api/v2/users 请求头版本控制 GET /api/users Accept: application/vnd.myapi.v1+json 查询参数版本控制 GET /api/users?version=1 请求和响应格式 请求示例 POST /api/v1/users Content-Type: application/json { \u0026#34;name\u0026#34;: \u0026#34;John Doe\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;john@example.com\u0026#34;, \u0026#34;age\u0026#34;: 30 } 成功响应示例 HTTP/1.1 201 Created Content-Type: application/json { \u0026#34;id\u0026#34;: 1, \u0026#34;name\u0026#34;: \u0026#34;John Doe\u0026#34;, \u0026#34;email\u0026#34;: \u0026#34;john@example.com\u0026#34;, \u0026#34;age\u0026#34;: 30, \u0026#34;createdAt\u0026#34;: \u0026#34;2025-12-15T10:00:00Z\u0026#34; } 响应结构 { \u0026#34;status\u0026#34;: \u0026#34;success\u0026#34;, \u0026#34;code\u0026#34;: 200, \u0026#34;data\u0026#34;: { \u0026#34;id\u0026#34;: 1, \u0026#34;name\u0026#34;: \u0026#34;John Doe\u0026#34; }, \u0026#34;message\u0026#34;: \u0026#34;User retrieved successfully\u0026#34; } HTTP 状态码 2xx 成功 200 OK 请求成功 201 Created 资源创建成功 204 No Content 请求成功但无返回内容 3xx 重定向 301 Moved Permanently 永久重定向 302 Found 临时重定向 304 Not Modified 资源未修改 4xx 客户端错误 400 Bad Request 请求格式错误 401 Unauthorized 需要身份验证 403 Forbidden 无权限访问 404 Not Found 资源不存在 409 Conflict 请求冲突 422 Unprocessable Entity 请求格式正确但包含语义错误 429 Too Many Requests 请求过于频繁 5xx 服务器错误 500 Internal Server Error 服务器内部错误 502 Bad Gateway 网关错误 503 Service Unavailable 服务不可用 错误处理 统一的错误响应格式 { \u0026#34;status\u0026#34;: \u0026#34;error\u0026#34;, \u0026#34;code\u0026#34;: 400, \u0026#34;error\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;ValidationError\u0026#34;, \u0026#34;message\u0026#34;: \u0026#34;Invalid input\u0026#34;, \u0026#34;details\u0026#34;: [ { \u0026#34;field\u0026#34;: \u0026#34;email\u0026#34;, \u0026#34;message\u0026#34;: \u0026#34;Invalid email format\u0026#34; }, { \u0026#34;field\u0026#34;: \u0026#34;age\u0026#34;, \u0026#34;message\u0026#34;: \u0026#34;Age must be at least 18\u0026#34; } ] } } 错误处理最佳实践 // Express.js 示例 app.post(\u0026#39;/api/v1/users\u0026#39;, (req, res) =\u0026gt; { try { // 验证输入 if (!req.body.email) { return res.status(400).json({ status: \u0026#39;error\u0026#39;, code: 400, error: { type: \u0026#39;ValidationError\u0026#39;, message: \u0026#39;Email is required\u0026#39; } }); } // 处理请求 const user = createUser(req.body); res.status(201).json({ status: \u0026#39;success\u0026#39;, code: 201, data: user }); } catch (error) { res.status(500).json({ status: \u0026#39;error\u0026#39;, code: 500, error: { type: \u0026#39;InternalServerError\u0026#39;, message: \u0026#39;An unexpected error occurred\u0026#39; } }); } }); 分页和过滤 分页 GET /api/v1/users?page=1\u0026amp;limit=10 GET /api/v1/users?offset=0\u0026amp;limit=10 响应示例 { \u0026#34;status\u0026#34;: \u0026#34;success\u0026#34;, \u0026#34;data\u0026#34;: [...], \u0026#34;pagination\u0026#34;: { \u0026#34;page\u0026#34;: 1, \u0026#34;limit\u0026#34;: 10, \u0026#34;total\u0026#34;: 100, \u0026#34;totalPages\u0026#34;: 10 } } 过滤和排序 GET /api/v1/users?status=active\u0026amp;sort=name\u0026amp;order=asc GET /api/v1/users?role=admin\u0026amp;createdAfter=2025-01-01 身份验证和授权 JWT 身份验证 // 登录端点 POST /api/v1/auth/login { \u0026#34;email\u0026#34;: \u0026#34;user@example.com\u0026#34;, \u0026#34;password\u0026#34;: \u0026#34;password123\u0026#34; } // 响应 { \u0026#34;status\u0026#34;: \u0026#34;success\u0026#34;, \u0026#34;data\u0026#34;: { \u0026#34;token\u0026#34;: \u0026#34;eyJhbGciOiJIUzI1NiIs...\u0026#34;, \u0026#34;expiresIn\u0026#34;: 3600 } } // 使用 token 访问受保护的资源 GET /api/v1/users/me Authorization: Bearer eyJhbGciOiJIUzI1NiIs... 速率限制 HTTP/1.1 200 OK X-RateLimit-Limit: 100 X-RateLimit-Remaining: 99 X-RateLimit-Reset: 1640000000 API 文档 使用 OpenAPI/Swagger openapi: 3.0.0 info: title: User API version: 1.0.0 paths: /api/v1/users: get: summary: Get all users parameters: - name: page in: query schema: type: integer responses: \u0026#39;200\u0026#39;: description: List of users content: application/json: schema: type: array items: $ref: \u0026#39;#/components/schemas/User\u0026#39; post: summary: Create a new user requestBody: required: true content: application/json: schema: $ref: \u0026#39;#/components/schemas/UserInput\u0026#39; responses: \u0026#39;201\u0026#39;: description: User created 向后兼容性 版本控制策略 添加新字段 - 安全，客户端可以忽略 重命名字段 - 保留旧字段，添加新字段 删除字段 - 先弃用，后删除 更改字段类型 - 创建新版本 弃用策略 HTTP/1.1 200 OK Deprecation: true Sunset: Sun, 31 Dec 2025 23:59:59 GMT Link: \u0026lt;/api/v2/users\u0026gt;; rel=\u0026#34;successor-version\u0026#34; 安全最佳实践 使用 HTTPS - 加密传输 验证输入 - 防止注入攻击 实施速率限制 - 防止滥用 使用 CORS - 控制跨域访问 实施身份验证 - 保护敏感资源 记录和监控 - 追踪异常活动 定期更新依赖 - 修复安全漏洞 性能优化 使用缓存 - 减少数据库查询 分页 - 限制返回数据量 字段选择 - 只返回需要的字段 异步处理 - 长时间操作使用后台任务 数据库优化 - 索引、查询优化 API 设计检查清单 使用 RESTful 原则 一致的 URL 设计 适当的 HTTP 方法 正确的状态码 统一的错误格式 版本控制 身份验证和授权 速率限制 完整的文档 向后兼容性 安全措施 性能优化 总结 设计好的 API 需要考虑多个方面，包括可用性、安全性、性能和可维护性。遵循这些最佳实践能帮助你创建高质量的 API，提供更好的开发者体验。\n","permalink":"https://magicbude.github.io/blog/api-design-best-practices/","summary":"\u003ch2 id=\"什么是好的-api\"\u003e什么是好的 API？\u003c/h2\u003e\n\u003cp\u003e好的 API 应该是：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e易于理解\u003c/strong\u003e - 清晰的命名和文档\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e易于使用\u003c/strong\u003e - 一致的设计模式\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e易于维护\u003c/strong\u003e - 良好的版本控制和向后兼容性\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e安全可靠\u003c/strong\u003e - 身份验证、授权、速率限制\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e高性能\u003c/strong\u003e - 快速响应和高效的资源使用\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"restful-api-原则\"\u003eRESTful API 原则\u003c/h2\u003e\n\u003ch3 id=\"基本概念\"\u003e基本概念\u003c/h3\u003e\n\u003cp\u003eREST（Representational State Transfer）是一种架构风格，基于以下原则：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003e客户端-服务器架构\u003c/strong\u003e - 分离关注点\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e无状态\u003c/strong\u003e - 每个请求包含所有必要信息\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e可缓存\u003c/strong\u003e - 响应应该定义自己是否可缓存\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e统一接口\u003c/strong\u003e - 一致的 API 设计\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e分层系统\u003c/strong\u003e - 客户端不知道是否直接连接到最终服务器\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"http-方法\"\u003eHTTP 方法\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eGET     获取资源\nPOST    创建新资源\nPUT     替换整个资源\nPATCH   部分更新资源\nDELETE  删除资源\nHEAD    获取资源元数据（不返回响应体）\nOPTIONS 获取资源的通信选项\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"资源和-url-设计\"\u003e资源和 URL 设计\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e好的设计：\nGET    /api/v1/users              获取用户列表\nPOST   /api/v1/users              创建新用户\nGET    /api/v1/users/:id          获取特定用户\nPUT    /api/v1/users/:id          更新用户\nDELETE /api/v1/users/:id          删除用户\nGET    /api/v1/users/:id/posts    获取用户的文章\n\n不好的设计：\nGET    /api/getUser               \nGET    /api/createUser            \nGET    /api/updateUser?id=1       \nGET    /api/deleteUser?id=1       \n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"关键原则\"\u003e关键原则\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003e使用名词而不是动词\u003c/strong\u003e - \u003ccode\u003e/users\u003c/code\u003e 而不是 \u003ccode\u003e/getUsers\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e使用复数形式\u003c/strong\u003e - \u003ccode\u003e/users\u003c/code\u003e 而不是 \u003ccode\u003e/user\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e使用小写\u003c/strong\u003e - \u003ccode\u003e/api/users\u003c/code\u003e 而不是 \u003ccode\u003e/api/Users\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e使用连字符分隔单词\u003c/strong\u003e - \u003ccode\u003e/user-profiles\u003c/code\u003e 而不是 \u003ccode\u003e/userProfiles\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e避免深层嵌套\u003c/strong\u003e - 最多两层 \u003ccode\u003e/users/:id/posts\u003c/code\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"版本控制\"\u003e版本控制\u003c/h2\u003e\n\u003ch3 id=\"url-版本控制推荐\"\u003eURL 版本控制（推荐）\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e/api/v1/users\n/api/v2/users\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"请求头版本控制\"\u003e请求头版本控制\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eGET /api/users\nAccept: application/vnd.myapi.v1+json\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"查询参数版本控制\"\u003e查询参数版本控制\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eGET /api/users?version=1\n\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"请求和响应格式\"\u003e请求和响应格式\u003c/h2\u003e\n\u003ch3 id=\"请求示例\"\u003e请求示例\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003ePOST\u003c/span\u003e \u003cspan class=\"err\"\u003e/api/v\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"err\"\u003e/users\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003eContent-Type:\u003c/span\u003e \u003cspan class=\"err\"\u003eapplication/json\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026#34;name\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;John Doe\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026#34;email\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;john@example.com\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026#34;age\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e30\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"成功响应示例\"\u003e成功响应示例\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003eHTTP/\u003c/span\u003e\u003cspan class=\"mf\"\u003e1.1\u003c/span\u003e \u003cspan class=\"mi\"\u003e201\u003c/span\u003e \u003cspan class=\"err\"\u003eCreated\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003eContent-Type:\u003c/span\u003e \u003cspan class=\"err\"\u003eapplication/json\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026#34;id\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026#34;name\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;John Doe\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026#34;email\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;john@example.com\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026#34;age\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e30\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026#34;createdAt\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;2025-12-15T10:00:00Z\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"响应结构\"\u003e响应结构\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026#34;status\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;success\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026#34;code\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e200\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026#34;data\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026#34;id\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026#34;name\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;John Doe\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026#34;message\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;User retrieved successfully\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"http-状态码\"\u003eHTTP 状态码\u003c/h2\u003e\n\u003ch3 id=\"2xx-成功\"\u003e2xx 成功\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e200 OK              请求成功\n201 Created         资源创建成功\n204 No Content      请求成功但无返回内容\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"3xx-重定向\"\u003e3xx 重定向\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e301 Moved Permanently    永久重定向\n302 Found               临时重定向\n304 Not Modified        资源未修改\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"4xx-客户端错误\"\u003e4xx 客户端错误\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e400 Bad Request         请求格式错误\n401 Unauthorized        需要身份验证\n403 Forbidden          无权限访问\n404 Not Found          资源不存在\n409 Conflict           请求冲突\n422 Unprocessable Entity 请求格式正确但包含语义错误\n429 Too Many Requests   请求过于频繁\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"5xx-服务器错误\"\u003e5xx 服务器错误\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e500 Internal Server Error   服务器内部错误\n502 Bad Gateway            网关错误\n503 Service Unavailable    服务不可用\n\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"错误处理\"\u003e错误处理\u003c/h2\u003e\n\u003ch3 id=\"统一的错误响应格式\"\u003e统一的错误响应格式\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026#34;status\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;error\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026#34;code\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e400\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026#34;error\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026#34;type\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;ValidationError\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026#34;message\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;Invalid input\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026#34;details\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nt\"\u003e\u0026#34;field\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;email\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nt\"\u003e\u0026#34;message\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;Invalid email format\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nt\"\u003e\u0026#34;field\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;age\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nt\"\u003e\u0026#34;message\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;Age must be at least 18\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"错误处理最佳实践\"\u003e错误处理最佳实践\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Express.js 示例\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nx\"\u003eapp\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003epost\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;/api/v1/users\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ereq\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eres\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"k\"\u003etry\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e// 验证输入\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nx\"\u003ereq\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ebody\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eemail\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nx\"\u003eres\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estatus\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e400\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"nx\"\u003ejson\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nx\"\u003estatus\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;error\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nx\"\u003ecode\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e400\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nx\"\u003eerror\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e          \u003cspan class=\"nx\"\u003etype\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;ValidationError\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e          \u003cspan class=\"nx\"\u003emessage\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;Email is required\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e// 处理请求\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e    \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003euser\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003ecreateUser\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ereq\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ebody\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003eres\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estatus\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e201\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"nx\"\u003ejson\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"nx\"\u003estatus\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;success\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"nx\"\u003ecode\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e201\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"nx\"\u003edata\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003euser\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"k\"\u003ecatch\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eerror\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003eres\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estatus\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e500\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"nx\"\u003ejson\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"nx\"\u003estatus\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;error\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"nx\"\u003ecode\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e500\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"nx\"\u003eerror\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nx\"\u003etype\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;InternalServerError\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nx\"\u003emessage\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;An unexpected error occurred\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"分页和过滤\"\u003e分页和过滤\u003c/h2\u003e\n\u003ch3 id=\"分页\"\u003e分页\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eGET /api/v1/users?page=1\u0026amp;limit=10\nGET /api/v1/users?offset=0\u0026amp;limit=10\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"响应示例\"\u003e响应示例\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026#34;status\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;success\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026#34;data\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"err\"\u003e...\u003c/span\u003e\u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nt\"\u003e\u0026#34;pagination\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026#34;page\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026#34;limit\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026#34;total\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e100\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026#34;totalPages\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e10\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"过滤和排序\"\u003e过滤和排序\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eGET /api/v1/users?status=active\u0026amp;sort=name\u0026amp;order=asc\nGET /api/v1/users?role=admin\u0026amp;createdAfter=2025-01-01\n\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"身份验证和授权\"\u003e身份验证和授权\u003c/h2\u003e\n\u003ch3 id=\"jwt-身份验证\"\u003eJWT 身份验证\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 登录端点\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nx\"\u003ePOST\u003c/span\u003e \u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"nx\"\u003eapi\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"nx\"\u003ev1\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"nx\"\u003eauth\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"nx\"\u003elogin\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"s2\"\u003e\u0026#34;email\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;user@example.com\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"s2\"\u003e\u0026#34;password\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;password123\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 响应\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"s2\"\u003e\u0026#34;status\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;success\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"s2\"\u003e\u0026#34;data\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;token\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;eyJhbGciOiJIUzI1NiIs...\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;expiresIn\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e3600\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 使用 token 访问受保护的资源\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nx\"\u003eGET\u003c/span\u003e \u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"nx\"\u003eapi\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"nx\"\u003ev1\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"nx\"\u003eusers\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"nx\"\u003eme\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003eAuthorization\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003eBearer\u003c/span\u003e \u003cspan class=\"nx\"\u003eeyJhbGciOiJIUzI1NiIs\u003c/span\u003e\u003cspan class=\"p\"\u003e...\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"速率限制\"\u003e速率限制\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eHTTP/1.1 200 OK\nX-RateLimit-Limit: 100\nX-RateLimit-Remaining: 99\nX-RateLimit-Reset: 1640000000\n\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"api-文档\"\u003eAPI 文档\u003c/h2\u003e\n\u003ch3 id=\"使用-openapiswagger\"\u003e使用 OpenAPI/Swagger\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-yaml\" data-lang=\"yaml\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003eopenapi\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"m\"\u003e3.0.0\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"nt\"\u003einfo\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"l\"\u003eUser API\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003eversion\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"m\"\u003e1.0.0\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"nt\"\u003epaths\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003e/api/v1/users\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"nt\"\u003eget\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"nt\"\u003esummary\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"l\"\u003eGet all users\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"nt\"\u003eparameters\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e- \u003cspan class=\"nt\"\u003ename\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"l\"\u003epage\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e          \u003c/span\u003e\u003cspan class=\"nt\"\u003ein\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"l\"\u003equery\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e          \u003c/span\u003e\u003cspan class=\"nt\"\u003eschema\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e            \u003c/span\u003e\u003cspan class=\"nt\"\u003etype\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"l\"\u003einteger\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"nt\"\u003eresponses\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"nt\"\u003e\u0026#39;200\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e          \u003c/span\u003e\u003cspan class=\"nt\"\u003edescription\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"l\"\u003eList of users\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e          \u003c/span\u003e\u003cspan class=\"nt\"\u003econtent\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e            \u003c/span\u003e\u003cspan class=\"nt\"\u003eapplication/json\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e              \u003c/span\u003e\u003cspan class=\"nt\"\u003eschema\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e                \u003c/span\u003e\u003cspan class=\"nt\"\u003etype\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"l\"\u003earray\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e                \u003c/span\u003e\u003cspan class=\"nt\"\u003eitems\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e                  \u003c/span\u003e\u003cspan class=\"nt\"\u003e$ref\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;#/components/schemas/User\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"nt\"\u003epost\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"nt\"\u003esummary\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"l\"\u003eCreate a new user\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"nt\"\u003erequestBody\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"nt\"\u003erequired\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"nt\"\u003econtent\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e          \u003c/span\u003e\u003cspan class=\"nt\"\u003eapplication/json\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e            \u003c/span\u003e\u003cspan class=\"nt\"\u003eschema\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e              \u003c/span\u003e\u003cspan class=\"nt\"\u003e$ref\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;#/components/schemas/UserInput\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"nt\"\u003eresponses\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"nt\"\u003e\u0026#39;201\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e          \u003c/span\u003e\u003cspan class=\"nt\"\u003edescription\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"l\"\u003eUser created\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"向后兼容性\"\u003e向后兼容性\u003c/h2\u003e\n\u003ch3 id=\"版本控制策略\"\u003e版本控制策略\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003e添加新字段\u003c/strong\u003e - 安全，客户端可以忽略\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e重命名字段\u003c/strong\u003e - 保留旧字段，添加新字段\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e删除字段\u003c/strong\u003e - 先弃用，后删除\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e更改字段类型\u003c/strong\u003e - 创建新版本\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"弃用策略\"\u003e弃用策略\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eHTTP/1.1 200 OK\nDeprecation: true\nSunset: Sun, 31 Dec 2025 23:59:59 GMT\nLink: \u0026lt;/api/v2/users\u0026gt;; rel=\u0026#34;successor-version\u0026#34;\n\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"安全最佳实践\"\u003e安全最佳实践\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003e使用 HTTPS\u003c/strong\u003e - 加密传输\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e验证输入\u003c/strong\u003e - 防止注入攻击\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e实施速率限制\u003c/strong\u003e - 防止滥用\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e使用 CORS\u003c/strong\u003e - 控制跨域访问\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e实施身份验证\u003c/strong\u003e - 保护敏感资源\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e记录和监控\u003c/strong\u003e - 追踪异常活动\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e定期更新依赖\u003c/strong\u003e - 修复安全漏洞\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"性能优化\"\u003e性能优化\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003e使用缓存\u003c/strong\u003e - 减少数据库查询\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e分页\u003c/strong\u003e - 限制返回数据量\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e字段选择\u003c/strong\u003e - 只返回需要的字段\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e异步处理\u003c/strong\u003e - 长时间操作使用后台任务\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e数据库优化\u003c/strong\u003e - 索引、查询优化\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"api-设计检查清单\"\u003eAPI 设计检查清单\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 使用 RESTful 原则\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 一致的 URL 设计\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 适当的 HTTP 方法\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 正确的状态码\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 统一的错误格式\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 版本控制\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 身份验证和授权\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 速率限制\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 完整的文档\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 向后兼容性\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 安全措施\u003c/li\u003e\n\u003cli\u003e\u003cinput disabled=\"\" type=\"checkbox\"\u003e 性能优化\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"总结\"\u003e总结\u003c/h2\u003e\n\u003cp\u003e设计好的 API 需要考虑多个方面，包括可用性、安全性、性能和可维护性。遵循这些最佳实践能帮助你创建高质量的 API，提供更好的开发者体验。\u003c/p\u003e","title":"API 设计最佳实践"}]