部署 & Performance

AdminLTE 是一个静态 HTML/CSS/JS 模板——部署它并没有什么特别之处。但有一些选择会显著影响页面体积、可交互时间和 CDN 可靠性。本页记录了这些值得正确处理的事项。

部署什么

可部署的产物是 dist/ 下的所有内容,加上你自己的 HTML/服务端渲染模板:

dist/
├── css/                ← 样式表(LTR + RTL,开发版 + 压缩版)
│   ├── adminlte.css
│   ├── adminlte.min.css
│   ├── adminlte.rtl.css
│   └── adminlte.rtl.min.css
├── js/                 ← JavaScript 打包文件(开发版 + 压缩版)
│   ├── adminlte.js
│   └── adminlte.min.js
└── assets/             ← 演示图片 / 字体(请替换为您的内容)

如果你将 AdminLTE 嵌入到自己的应用中,则不需要发布 src/node_modules/ 或演示 HTML。

生产环境始终使用 .min 压缩版本

压缩版本是相同的代码,只是去除了空白字符并缩短了标识符。对于 adminlte.css,节省大约 15-20%;对于 adminlte.js,节省更大(gzip 后约 30%)。未压缩文件在开发环境中对于可读的 source-map 调试很有用——切勿将它们提供给用户。

资源 开发环境 生产环境
样式表 dist/css/adminlte.css dist/css/adminlte.min.css
脚本 dist/js/adminlte.js dist/js/adminlte.min.js
RTL 样式表 dist/css/adminlte.rtl.css dist/css/adminlte.rtl.min.css
边缘压缩

确保你的 Web 服务器/CDN 对相关内容类型启用 gzip(或 brotli)压缩:

# nginx
gzip on;
gzip_types text/css application/javascript text/html image/svg+xml;
gzip_comp_level 6;
# Apache
AddOutputFilterByType DEFLATE text/css application/javascript text/html image/svg+xml

Cloudflare、Vercel、Netlify 以及大多数托管服务都会自动执行此操作。使用 curl -I -H "Accept-Encoding: gzip" your-page-url 验证,并在响应中查找 content-encoding: gzip

缓存头

构建产物的文件名是否包含内容哈希,取决于您是否通过构建工具进行配置——AdminLTE 默认使用固定文件名。以下是两种合理的做法:

  1. 短缓存 + 版本查询字符串(简单,无需构建流程即可工作):

    <link rel="stylesheet" href="/dist/css/adminlte.min.css?v=4.0.0" />
    <script src="/dist/js/adminlte.min.js?v=4.0.0"></script>

    在服务器上设置 Cache-Control: public, max-age=86400(1 天)。每次发布时更新 ?v= 以强制缓存失效。

  2. 指纹文件名(生产级,需要打包工具):

    让你的打包工具生成 adminlte.[hash].min.css 并在 HTML 中引用该哈希值。设置 Cache-Control: public, max-age=31536000, immutable(1 年)。如果你通过 Vite/Webpack/Rollup 导入 AdminLTE,它们默认就是这样做的。

CDN 完整性哈希

如果你从公共 CDN(jsDelivr、unpkg)加载 AdminLTE,请包含子资源完整性(SRI)哈希,以防止被入侵的 CDN 静默提供恶意 JavaScript:

<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/admin-lte@4.0.0/dist/css/adminlte.min.css"
  integrity="sha384-PASTE_THE_HASH_HERE"
  crossorigin="anonymous"
/>

你可以从 jsDelivr 文件详情页获取哈希值——点击任意文件并复制 “SRI” 行。对 Bootstrap、Popper、OverlayScrollbars 和 Bootstrap Icons 也要做同样的操作。

对于自托管的资源,自行生成哈希:

openssl dgst -sha384 -binary dist/css/adminlte.min.css | openssl base64 -A
加载顺序很重要

脚本顺序一定要放对,否则有些功能会悄无声息地失效:

<head>
  <!-- 1. Bootstrap Icons(字体 CSS)——首先加载,以便图标随页面一起渲染 -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.13.1/font/bootstrap-icons.min.css" />

  <!-- 2. OverlayScrollbars(可选,用于侧边栏滚动) -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/overlayscrollbars@2.11.0/styles/overlayscrollbars.min.css" />

  <!-- 3. AdminLTE——通过其导入包含 Bootstrap CSS -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/admin-lte@4.0.0/dist/css/adminlte.min.css" />
</head>

<body>


  <!-- 脚本放在 body 末尾 -->
  <!-- 4. Popper(Bootstrap 下拉菜单/工具提示/弹出框的依赖) -->
  <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js"></script>

  <!-- 5. Bootstrap -->
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.min.js"></script>

  <!-- 6. OverlayScrollbars -->
  <script src="https://cdn.jsdelivr.net/npm/overlayscrollbars@2.11.0/browser/overlayscrollbars.browser.es6.min.js"></script>

  <!-- 7. AdminLTE——必须在 Bootstrap 之后加载 -->
  <script src="https://cdn.jsdelivr.net/npm/admin-lte@4.0.0/dist/js/adminlte.min.js"></script>
</body>
Defer 还是 async?

AdminLTE 包会在 DOMContentLoaded 之后再挂载其 data API,因此 defer 是安全且推荐的:

<script defer src="/dist/js/adminlte.min.js"></script>

不要使用 async——脚本可能会在其依赖(Bootstrap、Popper)解析完成之前执行,而监听器会附加到尚不存在的元素上。

关键 CSS

为了实现 1 秒以内的首次绘制,将首屏布局使用的样式(页眉 + 品牌 + 首个可见内容)内联,并异步加载其余的 adminlte.min.css

<style>/* 为 /dashboard 提取的关键 CSS */</style>

<link
  rel="preload"
  as="style"
  href="/dist/css/adminlte.min.css"
  onload="this.onload=null;this.rel='stylesheet'"
/>
<noscript><link rel="stylesheet" href="/dist/css/adminlte.min.css" /></noscript>

使用 CrittersPenthouse 等工具提取关键 CSS,作为构建流程的一部分。对于登录后的仪表板(首屏加载速度的重要性不如营销页面),这通常是多此一举。

预加载关键资源

在浏览器从 HTML 中发现关键资源之前,将其推送至浏览器:

<link rel="preload" as="style" href="/dist/css/adminlte.min.css" />
<link rel="preload" as="font" href="/fonts/source-sans-3.woff2" type="font/woff2" crossorigin />
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin />

只预加载每个页面都会用到的资源。在共享布局中预加载路由级资源会浪费带宽。

子页面懒加载

如果你的仪表板有很多路由,且 JS 是每个路由的服务端渲染 HTML,建议使用按路由导入 CSS,而非一个巨大的样式表。AdminLTE 的核心 CSS 很小(~44KB gzip),但页面特定样式(图表、日历、表格)会累积——只在需要的地方加载它们。

对于 SPA,对重量级集成进行代码拆分:

// 不要将日历应用打包到主 chunk 中
const Calendar = () => import("./Calendar.vue")
打包体积预算

当前发布的 dist/ 产物 gzip 后的大小:

资源 大小(gzip)
adminlte.min.css ~40 KB
adminlte.rtl.min.css ~40 KB
adminlte.min.js ~5 KB

完整的首屏负载(HTML + Bootstrap + AdminLTE + Bootstrap Icons + Popper + OverlayScrollbars)从 CDN 加载时约为 180 KB gzip。CI 构建会强制执行 bundlewatch 检查,如果任何资源超出预算则会失败。

Service Worker / 离线支持

AdminLTE 只是静态文件——将其缓存在 service worker 中无需任何修改即可工作。一个最小化的 Workbox 配置:

import { precacheAndRoute } from "workbox-precaching"

precacheAndRoute([
  { url: "/dist/css/adminlte.min.css", revision: "4.0.0" },
  { url: "/dist/js/adminlte.min.js", revision: "4.0.0" },
  // ...你自己的页面
])
部署前移除开发专用文件

如果你原样部署演示 dist/ 文件夹,请从上传内容中剔除以下模式:

  • *.map (source map——会将源代码泄露给任何打开 devtools 的人)
  • **/html/ (Astro 中间构建产物,如果存在)
  • **/.astro/ (Astro 缓存)

对于 rclone / rsync

rsync -avz --delete \
  --exclude='*.map' \
  --exclude='html/' \
  --exclude='.astro/' \
  dist/ user@server:/var/www/your-app/
关于 Cloudflare 缓存的说明

Cloudflare 的默认浏览器缓存 TTL 为 4 小时。如果你发布了新版本并希望用户立即看到,请从 Cloudflare 仪表板或 API 清除受影响的路径。否则,访问缓存页面的用户将在最多四小时内看到旧的 CSS/JS。

接下来去哪里
  • 定制——在部署前更改颜色、侧边栏宽度、breakpoint
  • 推荐集成——为 AdminLTE 未打包的功能选择轻量级库
  • 无障碍访问——确保你部署的页面保持其无障碍访问