Semantic UI实战:从入门到项目落地的完整指南

南宫爱菊 框架 阅读 2,139
赞 22 收藏
二维码
手机扫码查看
反馈

优化前:卡得不行

上个月接手一个老项目,前端用的是 Semantic UI,版本还挺老(2.4.x)。本地开发时感觉还行,但一部署到测试环境,首页加载直接干到 5 秒多,用户点个按钮卡半秒,下拉菜单动画掉帧严重,连 modal 弹出来都肉眼可见地慢。团队里有人吐槽:“这哪是语义化 UI,这是语义化卡顿吧?”

Semantic UI实战:从入门到项目落地的完整指南

说实话,我一开始也没太当回事,以为就是资源没压缩。结果打包后 CSS 有 1.8MB,JS 也有 900KB,全量引入了 Semantic UI 的所有组件。用户只用了按钮、表单、卡片和模态框,其他像 accordion、calendar、sidebar 这些根本没用,却全被打包进去了。难怪慢。

找到瓶颈了!

先用 Chrome DevTools 的 Performance 面板录了一次加载过程,发现主线程被大量样式计算和布局重排占满。再看 Network,semantic.min.css 和 semantic.min.js 两个大文件首屏就加载,而且阻塞渲染。Lighthouse 评分惨不忍睹:Performance 只有 32 分。

关键问题其实就两个:

  • 全量引入:不管用不用,整个框架都塞进 bundle
  • 未 Tree Shaking:Semantic UI 的 JS 是基于 jQuery 的,ESM 支持差,Webpack 根本没法做模块级摇树

折腾了半天发现,想靠现代构建工具自动优化这条路基本走不通——Semantic UI 的架构决定了它天生不适合按需加载。

核心方案:手动按需引入 + 自定义构建

既然自动不行,那就手动来。我试了三种方案:

  1. 用官方提供的 LESS 源码,只编译需要的组件
  2. 用 CDN 按需加载组件(但项目要求离线可用,pass)
  3. 直接复制粘贴用到的 CSS/JS 到项目里(太脏,维护困难)

最后选了第一种,虽然麻烦点,但最干净可控。

具体操作:

先在项目里安装 semantic-ui-less(不是 semantic-ui):

npm install semantic-ui-less --save-dev

然后新建一个 custom.semantic.less,只导入需要的模块:

/* custom.semantic.less */
@import "semantic-ui-less/definitions/globals/reset";
@import "semantic-ui-less/definitions/globals/site";

@import "semantic-ui-less/definitions/elements/button";
@import "semantic-ui-less/definitions/elements/container";
@import "semantic-ui-less/definitions/elements/divider";
@import "semantic-ui-less/definitions/elements/flag";
@import "semantic-ui-less/definitions/elements/header";
@import "semantic-ui-less/definitions/elements/icon";
@import "semantic-ui-less/definitions/elements/image";
@import "semantic-ui-less/definitions/elements/input";
@import "semantic-ui-less/definitions/elements/label";
@import "semantic-ui-less/definitions/elements/list";
@import "semantic-ui-less/definitions/elements/loader";
@import "semantic-ui-less/definitions/elements/rail";
@import "semantic-ui-less/definitions/elements/reveal";
@import "semantic-ui-less/definitions/elements/segment";
@import "semantic-ui-less/definitions/elements/step";

@import "semantic-ui-less/definitions/collections/form";
@import "semantic-ui-less/definitions/collections/grid";
@import "semantic-ui-less/definitions/collections/menu";
@import "semantic-ui-less/definitions/collections/message";
@import "semantic-ui-less/definitions/collections/table";

@import "semantic-ui-less/definitions/modules/modal";
@import "semantic-ui-less/definitions/modules/dropdown";
@import "semantic-ui-less/definitions/modules/checkbox";
@import "semantic-ui-less/definitions/modules/transition";

注意:这里没引入 accordioncalendarsidebar 等未使用组件,连 dimmer 都只在 modal 依赖时才带进来。

然后在 Webpack 或 Vite 里配置 LESS 编译,把 custom.semantic.less 作为入口。同时,JS 部分不能全量引入,得一个个 require:

// main.js
import $ from 'jquery';
import 'semantic-ui-less/semantic.less'; // 实际指向上面的 custom.semantic.less

// 按需初始化组件
import 'semantic-ui-css/components/modal';
import 'semantic-ui-css/components/dropdown';
import 'semantic-ui-css/components/checkbox';
import 'semantic-ui-css/components/transition';

// 初始化
$(document).ready(() => {
  $('.ui.dropdown').dropdown();
  $('.ui.checkbox').checkbox();
  $('.ui.modal').modal();
});

这里有个坑:Semantic UI 的 JS 组件依赖顺序很敏感。比如 modal 依赖 dimmertransition,如果你只引了 modal,运行时会报错。所以必须手动把依赖链补全。我查了源码,把常用组件的依赖关系整理成了一份清单,避免反复试错。

额外优化:禁用不需要的动画

Semantic UI 默认给很多交互加了 CSS 动画(比如 dropdown 展开、modal 弹出),这些动画在低端机上特别卡。其实很多场景根本不需要动画,或者可以用更轻量的 fade 替代。

我在 custom.semantic.less 里覆盖了默认动画设置:

/* 禁用所有复杂动画,只保留 fade */
@defaultDuration: 0ms;
@defaultEasing: ease;

/* 或者针对特定组件 */
.ui.dropdown {
  .menu {
    transition: none !important;
  }
}

或者更彻底一点,在 JS 初始化时关掉动画:

$('.ui.dropdown').dropdown({
  duration: 0
});
$('.ui.modal').modal({
  duration: 0
});

亲测有效,尤其在 Android 低端机上,点击响应速度提升明显。

性能数据对比

优化前后对比数据(本地开发环境,Chrome DevTools 模拟 3G):

  • 首屏 CSS 体积:1.8MB → 280KB(减少 84%)
  • JS 体积:900KB → 120KB(减少 87%)
  • 首屏加载时间:5.2s → 780ms
  • Lighthouse Performance 分数:32 → 86
  • Modal 弹出延迟:~400ms → ~30ms(肉眼几乎无感)

上线后用户反馈“页面变快了”,产品经理终于不再催我了(笑)。

踩坑提醒:这三点一定注意

  • 图标问题:Semantic UI 默认用的是自己的 icon 字体,如果你没引入 icon 模块,所有图标会显示为方框。确保 @import "semantic-ui-less/definitions/elements/icon"; 在你的 custom 文件里。
  • 主题变量覆盖:如果项目有自定义主题色,记得在 custom.semantic.less 最前面定义 @primaryColor 等变量,否则会被默认值覆盖。
  • jQuery 依赖:Semantic UI 的 JS 部分强依赖 jQuery,如果你的项目想移除 jQuery,这条路基本走不通。建议评估是否值得为了 Semantic UI 保留 jQuery。

另外,这个方案虽然有效,但维护成本略高——每次新增组件都要手动改 LESS 和 JS 引入。不过对于长期不换 UI 框架的项目来说,一次配置,长期受益。

结尾

以上是我对 Semantic UI 性能优化的实战总结。虽然现在很多人转向 Tailwind、Ant Design 这类更现代的方案,但老项目还得维护。这套手动按需引入的方法,亲测能把 Semantic UI 的性能拉回到可接受水平。

当然,这也不是最优解——如果能重写,我肯定换框架。但在现实约束下,这已经是最简单有效的方案了。

以上是我踩坑后的总结,希望对你有帮助。有更好的优化方案?欢迎评论区交流!

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论

暂无评论