Skip to content

feat: reduce init payload data#291

Merged
PaiJi merged 2 commits intomainfrom
feat/opti-bundle-size
Feb 8, 2026
Merged

feat: reduce init payload data#291
PaiJi merged 2 commits intomainfrom
feat/opti-bundle-size

Conversation

@PaiJi
Copy link
Member

@PaiJi PaiJi commented Feb 8, 2026

Summary by CodeRabbit

发布说明

  • 文档更新

    • 更新了生产部署徽章,优化了 CI/CD 工作流程展示。
  • 性能改进

    • 优化了事件和组织数据的传输结构,提升系统性能。

@coderabbitai
Copy link

coderabbitai bot commented Feb 8, 2026

📝 Walkthrough

工作流程

此PR引入了两个新的精简类型定义(SimpleEventItem 和 OrganizationListItem),用于替换页面组件中的完整类型,以简化消费的数据结构。同时更新了 CI/CD 管道徽章。

变更

内聚组 / 文件 摘要
CI/CD 徽章更新
README.md, README.zh.md
将 CN 构建徽章替换为"部署到 CN 生产环境"徽章,更新工作流程链接。
类型定义
src/types/event.ts, src/types/organization.ts
新增 SimpleEventItem 类型(包含 id、slug、name、startAt、endAt、scale、region、organization)和 OrganizationListItem 类型(包含 id、slug、name、status、logoUrl)。
组件更新
src/components/SimpleEventCard/index.tsx
更新组件 props 类型从 EventItem 改为 SimpleEventItem。
页面类型迁移
src/pages/[organization]/index.tsx, src/pages/organization.tsx, src/pages/years.tsx
将页面组件和 getServerSideProps/getStaticProps 中的事件/组织类型从完整类型替换为新的精简类型,包含相应的数据映射转换。

代码审查工作量

🎯 3 (中等复杂度) | ⏱️ ~20 分钟

可能相关的 PR

  • feat(api): update endpoints #281 - 相关联 — 两个 PR 都修改了事件和组织类型的使用以及相关页面(如 src/types/event.ts 和 src/pages/years.tsx / src/pages/organization.tsx),改变了导出的类型定义和页面消费这些类型的方式。

诗句

🐰 新类型轻盈起舞,SimpleEventItem 和 OrganizationListItem,
精简数据的艺术,页面不再臃肿,
生产徽章闪闪发光,代码焕然一新,
小小改进,大大优雅! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确反映了pull request的核心目标 - 通过引入SimpleEventItem和OrganizationListItem等精简类型,减少初始化时传输的数据负载。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/opti-bundle-size

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/pages/organization.tsx (1)

22-26: ⚠️ Potential issue | 🟡 Minor

groupByStatusOrganizations["active"] 缺少空值保护(已有问题)。

如果 API 返回的组织列表中没有 active 状态的记录,groupBy 结果中不会有 "active" 键,此时 .map() 会因 undefined 而崩溃。"inactive" 同理。虽然这是已有代码,但既然这次改动涉及此区域的类型,建议顺手加个防护。

🛡️ 建议修复
-          {groupByStatusOrganizations["active"].map((o) => (
+          {(groupByStatusOrganizations["active"] ?? []).map((o) => (
-          {groupByStatusOrganizations["inactive"].map((o) => (
+          {(groupByStatusOrganizations["inactive"] ?? []).map((o) => (
src/pages/[organization]/index.tsx (1)

339-343: ⚠️ Potential issue | 🟡 Minor

data 的空值检查位于其使用之后,属于无效代码。

第 302-304 行已经访问了 data.organizationdata.events,如果 datanull/undefined,在到达第 339 行之前就会抛出异常。此检查永远不会生效。

虽然这是既有问题,但既然在修改这段逻辑,建议将 null 检查移到第 302 行之前,或者直接移除(如果 API 保证返回非空值)。

建议的修复方案
  try {
    const data = await OrganizationsAPI.getOrganizationDetail(reqParamsParseResult.organization);

+   if (!data) {
+     return {
+       notFound: true,
+     };
+   }
+
    const validOrganization = data.organization;
    const validEvents: EventCardItem[] =
      data.events
        ?.map((e) => ({
          // ...
        }))
        .sort(/* ... */) || [];
    const slug = context?.params?.organization;

-   if (!data) {
-     return {
-       notFound: true,
-     };
-   }
-
    const locale = (context.locale as currentSupportLocale) || "zh-Hans";
🤖 Fix all issues with AI agents
In `@src/pages/years.tsx`:
- Around line 12-13: The type error occurs because SimpleEventItem does not
satisfy the generic constraint T extends EventListable required by
eventGroupByYear and eventGroupByMonth (EventListable requires a scale: string),
so update the types to match: either add a scale: string property to the
SimpleEventItem type/interface, or loosen the grouping functions' generic
constraint to accept items with at least startAt (e.g. change EventListable
constraint to require { startAt: string | null }), or implement a dedicated
grouping function for SimpleEventItem; reference the SimpleEventItem type and
the eventGroupByYear/eventGroupByMonth function signatures when making the
change.
🧹 Nitpick comments (3)
src/types/event.ts (1)

186-195: 考虑使用 PickEventItem / EventCardItem 派生,减少手动同步负担。

SimpleEventItem 的字段是 EventCardItem 的子集,但采用了手动定义的方式。如果将来 EventItem 的字段类型发生变化(例如 scale 改为枚举),这里需要手动同步更新。此外,organizationEventSchema 中是非空的,但此处声明为可空,与源数据不一致——虽然更加防御性,但建议加个注释说明原因。

♻️ 可选:用工具类型派生
-export type SimpleEventItem = {
-  id: string;
-  slug: string;
-  name: string;
-  startAt: string | null;
-  endAt: string | null;
-  scale: string;
-  region: { localName: string | null } | null;
-  organization: { slug: string; name: string } | null;
-};
+export type SimpleEventItem = Pick<EventCardItem, "id" | "slug" | "name" | "startAt" | "endAt" | "scale" | "region"> & {
+  organization: { slug: string; name: string } | null;
+};
src/types/organization.ts (1)

32-38: status 类型从枚举宽化为 string

OrganizationSchemastatus 的类型是 "active" | "inactive",但 OrganizationListItem 将其声明为 string,丢失了枚举约束。如果下游代码依赖精确的状态值做条件判断,可能会降低类型安全性。

♻️ 可选:使用 Pick 保留原始类型
-export type OrganizationListItem = {
-  id: string;
-  slug: string;
-  name: string;
-  status: string;
-  logoUrl: string | null;
-};
+export type OrganizationListItem = Pick<Organization, "id" | "slug" | "name" | "status" | "logoUrl">;
src/pages/[organization]/index.tsx (1)

337-337: slug 已声明但未使用。

第 337 行的 const slug = context?.params?.organization; 在后续代码中没有被引用。可以安全移除。

Comment on lines +12 to 13
export default function Years({ events }: { events: SimpleEventItem[] }) {
const groupByYearEvents = eventGroupByYear(events, "asc");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for eventGroupByYear and eventGroupByMonth function definitions and usages
rg -n "eventGroupByYear|eventGroupByMonth" --type=ts --type=tsx -C 3

Repository: FurryConsChina/website

Length of output: 93


🏁 Script executed:

#!/bin/bash
# Search for eventGroupByYear and eventGroupByMonth function definitions and usages
rg -n "eventGroupByYear|eventGroupByMonth" --type=ts -C 3

Repository: FurryConsChina/website

Length of output: 2353


🏁 Script executed:

#!/bin/bash
# Search for EventListable interface and SimpleEventItem type definitions
rg -n "interface EventListable|type SimpleEventItem|interface SimpleEventItem" --type=ts -C 5

Repository: FurryConsChina/website

Length of output: 574


🏁 Script executed:

#!/bin/bash
# Search for EventListable interface definition more specifically
rg -n "interface EventListable|type EventListable" --type=ts -A 10

Repository: FurryConsChina/website

Length of output: 699


SimpleEventItem 不满足 eventGroupByYeareventGroupByMonth 的类型约束。

这两个函数要求泛型参数 T extends EventListable,但 SimpleEventItem 缺少 EventListable 所需的 scale: string 属性。虽然函数内部只访问 startAt 属性,但类型签名要求不匹配会导致类型错误。需要:

  1. SimpleEventItem 添加 scale 属性,或
  2. 修改函数签名以接受更宽泛的类型(如 { startAt: string | null }),或
  3. SimpleEventItem 创建单独的分组函数
🤖 Prompt for AI Agents
In `@src/pages/years.tsx` around lines 12 - 13, The type error occurs because
SimpleEventItem does not satisfy the generic constraint T extends EventListable
required by eventGroupByYear and eventGroupByMonth (EventListable requires a
scale: string), so update the types to match: either add a scale: string
property to the SimpleEventItem type/interface, or loosen the grouping
functions' generic constraint to accept items with at least startAt (e.g. change
EventListable constraint to require { startAt: string | null }), or implement a
dedicated grouping function for SimpleEventItem; reference the SimpleEventItem
type and the eventGroupByYear/eventGroupByMonth function signatures when making
the change.

@github-actions
Copy link

github-actions bot commented Feb 8, 2026

📦 Next.js Bundle Analysis for furrycons-site

This analysis was generated by the Next.js Bundle Analysis action. 🤖

⚠️ Global Bundle Size Increased

Page Size (compressed)
global 333.85 KB (🟡 +3 B)
Details

The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.

Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis

If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!

One Page Changed Size

The following page changed size from the code in this PR compared to its base branch:

Page Size (compressed) First Load % of Budget (350 KB)
/organization 3.78 KB 337.63 KB 96.47% (🟢 -0.01%)
Details

Only the gzipped size is provided here based on an expert tip.

First Load is the size of the global bundle plus the bundle for the individual page. If a user were to show up to your website and land on a given page, the first load size represents the amount of javascript that user would need to download. If next/link is used, subsequent page loads would only need to download that page's bundle (the number in the "Size" column), since the global bundle has already been downloaded.

Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis

The "Budget %" column shows what percentage of your performance budget the First Load total takes up. For example, if your budget was 100kb, and a given page's first load size was 10kb, it would be 10% of your budget. You can also see how much this has increased or decreased compared to the base branch of your PR. If this percentage has increased by 20% or more, there will be a red status indicator applied, indicating that special attention should be given to this. If you see "+/- <0.01%" it means that there was a change in bundle size, but it is a trivial enough amount that it can be ignored.

@PaiJi PaiJi merged commit af11e0e into main Feb 8, 2026
9 checks passed
@PaiJi PaiJi deleted the feat/opti-bundle-size branch February 8, 2026 10:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant