巧用SSR、SSG、CSR三件套拆分方案,基础设施费直降30%

AI 概述
三种渲染,配一张“地图”,争论瞬间闭麦只把“必须新鲜”的,留给 SSR大多数页面交给 SSG + 定时再验证(ISR)需要“活在加载之后”的交互,用 CSR 小岛把“缓存键”和“路由”对齐,才算真正拆完写进路由与构建规则,团队不用靠记忆上线前的“必修四句真话” 流量涨了,账单涨得更快。我们一把梭把所有页面同一...
目录
文章目录隐藏
  1. 三种渲染,配一张“地图”,争论瞬间闭麦
  2. 只把“必须新鲜”的,留给 SSR
  3. 大多数页面交给 SSG + 定时再验证(ISR)
  4. 需要“活在加载之后”的交互,用 CSR 小岛
  5. 把“缓存键”和“路由”对齐,才算真正拆完
  6. 写进路由与构建规则,团队不用靠记忆
  7. 上线前的“必修四句真话”

巧用 SSR、SSG、CSR 三件套拆分方案,基础设施费直降 30%

流量涨了,账单涨得更快。我们一把梭把所有页面同一种渲染端到端扫过去,然后就为这个选择分分秒秒付钱

直到我们老老实实把每个页面随时间与操作的变化轨迹画出来——渲染策略按变化模式拆分

结果?仪表盘安静了,发票瘦了。故事的精华,就在“拆”的过程里。

三种渲染,配一张“地图”,争论瞬间闭麦

我们的用户很多在中端机 + 慢网上;新鲜数据只在少数页面必须现做,大多数页面几乎不变

所以我们画了张行为 → 渲染的对应图。它比任何文档都更有说服力——成本的曲线和箭头对上了

      Request
           |
    +------+------+
    |             |
   SSR           CDN
    |             |
  Fresh         Cached
    |             |
  HTML           SSG
    |             |
  Hydrate       CSR islands

该不再调用的端点不再“机械劳动”;CDN开始扛大头,应用只给真正动态的路径出力。

这张小图就贴在任务墙上,每条路由的修改都对着它走。

只把“必须新鲜”的,留给 SSR

我们把服务端渲染严格限在:依赖当前访问者鉴权态、或按请求过滤的页面。其它统统撤席。 服务器只返回可直接展示的 HTML,再配一份瘦身后的 hydrate 载荷

// pages/orders/[id].js
export async function getServerSideProps({ params, req }) {
  const user = await getUser(req);
  const order = await api.orders.get(params.id, { user });
  return { props: { user: pick(user, ["id"]), order } }; // small props
}

export default function OrderPage({ user, order }) {
  return <OrderView userId={user.id} order={order} />;
}<

冷启动 TTFB 变快,因为链路短且可预期热请求在合规前提下用短期、精细的私有键吃缓存。 想复制?先审一遍 SSR 路由:如果 90% 的访客看到的 HTML 都一样,它大概率不该 SSR。因此,做减法。

大多数页面交给 SSG + 定时再验证(ISR)

营销、文档、FAQ、列表页变化慢。它们改成静态生成 + 再验证构建期做重活,线上交给 CDN 直接飞:

case          | p95 TTFB | monthly cost
--------------+----------+-------------
SSG reval 60s |  45 ms   |   –27%
SSR baseline  | 220 ms   |    0%

命中率上来了,源站 CPU下去了,因为我们不再重复渲染。编辑用定时 revalidate,不发版也能更新。 给你的建议:从一个高流量、低波动的路径下手;先用 几十秒的再验证,预览流程稳了再拉长

需要“活在加载之后”的交互,用 CSR 小岛

筛选器、图表、编辑器这类纯交互,我们做成 CSR islands:壳子快、组件活。

// pages/products/index.js
export async function getStaticProps() {
  const featured = await api.products.featured();
  return { props: { featured }, revalidate: 120 };
}

// components/Filters.client.jsx
export default function Filters({ onChange }) {
  const [state, set] = useState(init());
  useEffect(() => onChange(state), [state, onChange]);
  return <Controls state={state} onChange={set} />;
}

首屏来自静态 HTML,交互再按岛屿渐进水合。用户滚、点、打字不必等网络。 加岛时记住:props 小且稳定。为了改一个 slider 而整页重渲染,卡顿和云费用都会跟你急。

把“缓存键”和“路由”对齐,才算真正拆完

方案一开始并不灵:缓存键没贴着页面的变化点走。 我们把数据流摊开,标注键该放哪、不该放哪

Client -> CDN(key: /docs/v3/page)
               |
         HIT -> HTML
         MISS-> Origin
               |
         SSG build or revalidate

去掉吵闹的 query后,命中率上去、源站继续打哈欠。 鉴权页绕开 CDN;文档页新鲜时根本不碰应用。 如果你的缓存像随机数,在预发里把缓存键打印到响应头,再压测扫一遍——问题会自己跳出来。

写进路由与构建规则,团队不用靠记忆

我们把拆分规则代码化,让“选模式”跟着路径走,而不是某次迭代会上自由心证

// next.config.js (idea sketch)
const SSR = [/^\/account/, /^\/orders\/\w+$/];
const SSG = [/^\/docs/, /^\/pricing/, /^\/catalog/];

module.exports = {
  async headers() {
    return [
      { source: "/docs/:slug*", headers: [{ key: "Cache-Control", value: "s-maxage=60, stale-while-revalidate=300" }] },
      { source: "/account/:path*", headers: [{ key: "Cache-Control", value: "no-store" }] },
    ];
  },
  async rewrites() {
    return [
      { source: "/catalog", destination: "/_static/catalog" },
      { source: "/orders/:id", destination: "/_ssr/orders/:id" },
    ];
  },
};

包更小SSR 机器约少三成、静态页 p95 TTFB腰斩。最大的红利是:流量尖峰来了也把规则贴近路由,这样偏移会出现在代码评审,而不是云账单

上线前的“必修四句真话”

  1. 别迷信一种模式。把渲染策略和数据的时间变化对齐,才是降本增稳的正解。
  2. SSR 留给真正个性化的视图;SSG+短 revalidate 扛大盘;CSR 小岛负责灵活交互。
  3. 这套做法能规模化,是因为它把“口水战”变成路由、键与代码
  4. 账单不值就别硬顶——挑一条忙路径先拆它

以上关于巧用SSR、SSG、CSR三件套拆分方案,基础设施费直降30%的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。

「点点赞赏,手留余香」

0

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » 巧用SSR、SSG、CSR三件套拆分方案,基础设施费直降30%

发表回复