当前位置:首页>排行榜>静态站框架怎么选?Hugo和Next.js实测:网站从1.8秒降到0.4秒

静态站框架怎么选?Hugo和Next.js实测:网站从1.8秒降到0.4秒

  • 更新时间 2026-11-10 20:42:08
静态站框架怎么选?Hugo和Next.js实测:网站从1.8秒降到0.4秒

先说个数:我把跑了两年的文档站换了个框架,首页从 1.8 秒降到 0.4 秒。

不是换服务器,不是加 CDN,就是换了个生成器。服务器还是那台 2 核 4G 的机器。

算完这个数我盯着 curl 的输出看了半天,怀疑是本地缓存骗我,把浏览器关了重跑三次,还是 0.4 秒。

"

结论先放这:如果你只有一个内容站点,页面不多、改完就发、平时不登录,别上 Next.js。Hugo 能干的活,没必要用一个带 Node 运行时和服务端的框架去干。

01

PART 01

起因:客户资料站越来越慢

背景交代一句。我做宽带和号卡生意,客户需要在网站上查套餐、看覆盖小区、读办理说明。这个东西最初是我自己用 Next.js 搭的,功能不算多,但内容一天天堆,现在有 120 多篇文档、40 多个套餐页。

问题出在上个月。有个客户打电话来,说“你们网站打不开”。我自己打开看,等了将近两秒才出来首屏。

我知道两秒对很多人不算什么,但这是静态内容——一个只有文字和几张图的说明页,凭什么要两秒?

— 图1:两个框架在同一批页面上的首屏耗时

02

PART 02

先把我当时的三条路摆出来

改之前我列了三个方向,每条都有代价:

继续用 Next.js,把动态渲染改成纯静态导出(`output: ’export’`)

换 Hugo,Go 写的静态生成器,一个二进制文件

换 Astro,主打“默认零 JS”

下面是我当时记的表,数字是这台机器上跑出来的:

方案
构建 120 篇耗时
产物大小
部署依赖
我否掉的原因
Next.js 静态导出
47 秒
约 38 MB
需要 Node 打底
构建慢,js 包还是不小
Hugo 0.169.0
0.52 秒
约 9 MB
一个 21 MB 的二进制
模板语法要重新学
Astro
9.6 秒
约 12 MB
Node + 依赖目录
组件写法要迁一遍

先说 Next.js,我没换它,不是因为不好,是因为它的重心不在这里。它是给“需要服务端、需要登录、需要接口”的站点准备的。我这个站点这些全都不需要。

— 图2:三个方案的构建耗时对比

03

PART 03

卡在哪:模板语法和实时预览

Hugo 我试了三天,中间卡了两次。

第一次卡在模板语法。它用的不是 JSX,是 {{ }} 那一套,循环、条件判断、变量作用域都得重新记。我第一天写了半小时,页面一直报 template: partials/head.html:12: unexpected “}}” in operand,改了四遍才发现是少了一个 end。

...bash

$ hugo --minify

Error: error building site: Tpl: template: partials/head.html:12: unexpected “}}” in operand

$ grep -n “{{” layouts/partials/head.html | sed -n ’9,13p’

10:  <title>{{ .Title }}</title>

11:  {{ with .Site.Params.description }}

12:    <meta name=“description” content=“{{ . }}>

13:  {{ end }}

第 12 行引号没闭合,右边少了一个 “。这种错误跟新人用 Jinja 时一模一样,跟框架好坏没关系,纯手生。

第二次卡的地方更实际:实时预览。我这人改文案的习惯是「改一句,看一句」,所以必须有个边改边刷新的本地服务。

...bash

$ hugo server --port 1417

Web Server is available at http://localhost:1417/

启动之后我改了 content/posts/hello.md,保存,刷新浏览器——页面还是旧的。

我以为热更新坏了,重启服务、换端口、清缓存,折腾了二十分钟。最后翻开日志才看见:

...bash

$ tail -3 hugo.log

WARN  found no layout file for “html” for kind “section”

新加的文件里 draft = true 没改。Hugo 默认不给草稿渲染,所以它不是“没刷新”,是“这个页面压根没生成”。

这一条我后来写进了自己的笔记:改完看不见,先看 front matter 的 draft,再看布局文件有没有缺失。日志里的 WARN 不是噪声,是答案。

把 draft 改成 false 之后,再保存一次,页面立刻变了,构建日志打了一行 Total in 2 ms。

两毫秒。这个数字就是我当时决定换的理由——不是因为它快得离谱,是因为它快到我不用等。

— 图3:Hugo 的目录结构和三条命令

04

PART 04

部署这一步,Hugo 确实省事

换过来之后,部署变成了复制一个目录。

...bash

$ hugo --minify --gc

Start building sites …

                   | EN

-------------------+-----

  Pages            | 163

  Static files     |  41

  Total in 512 ms

$ du -sh public

9.1M public

$ rsync -az public/ root@server:/var/www/site/

没有 npm ci,没有 node_modules,没有“本地能跑服务器上跑不了”。服务器上只需要一个 nginx,它连 Hugo 都不用装——构建在我这台开发机上做完,传上去的就是一堆 html。

这个变化对运维的意义比速度更大。我以前的部署脚本里有一半的失败都出在依赖上:某台机器 Node 版本不对、某个包在 arm 上编译不过、锁文件冲突。现在这些全没了。

∞

THE END

说句可能不中听的

Hugo 不是新东西,9 万多星、2013 年就有了,它不酷,社区里也没什么热闹话题。

但我觉得它被低估的地方恰恰在这里:一个不需要你陪着的框架,比一个很酷但要你伺候的框架值钱。你一个月不开这个站,回来它照样一条命令构建完。

反过来说,什么情况下我不建议你用 Hugo:

1

站点需要登录、需要接口、需要后台 → 别考虑它,它做不了,硬上就是拿锤子拧螺丝

2

团队里没人愿意学 Go 模板语法 → Astro 或者 Next.js 静态导出更顺,代价是构建慢十倍左右

3

页面要大量交互(图表筛选、实时搜索) → Hugo 得配 JS,配完之后你等于又维护了一套前端

我的判断标准很简单:一个月改不到三次、页面以文字为主、没有登录,这三个条件满足两个以上,我会直接推荐它。

最后留个问题:那个 0.4 秒,我用的是 curl -w 量的服务器响应,不是浏览器里的首屏渲染时间——你们的站点,是看这两个数里的哪一个?

06

PART 06

补一段:迁移过程里真正费时间的不是框架

框架本身我一天就迁完了,因为 Markdown 文件几乎是原样搬过去的。真正费时间的是那些“附带的活”。

第一个是图片路径。原来的站点图片放在 /public/uploads/ 下面,文章里写的是绝对路径 /uploads/xxx.png。Hugo 的 static 目录是直接映射到根路径的,所以这部分基本没动,一行 sed 就换完了:

...bash

$ grep -rl “/uploads/” content/ | wc -l

27

$ grep -rl “/uploads/” content/ | xargs sed -i ’s#/uploads/#/images/#g’

第二个是旧链接。有 40 多个套餐页的地址里带日期和分类前缀,直接换框架会全部 404。我给 nginx 加了一段跳转,把老的路径模式重写到新位置,改完之后抽查了 30 个链接,全部 200。

第三个比较隐蔽:原来 Next.js 生成的页面里有一层自动加的 og:image 和结构化数据,换过来之后这些标签没了,站长后台里的收录掉了一截。补回来花了两个小时,写了一个 partial,所有页面共用。

这三个活加起来占了我迁移时间的三分之二。所以如果你在评估换不换,别只看“构建从 47 秒到 0.5 秒”,真正的账是:

构建时间省下的

每天几次,一次几十秒,基本可以忽略

页面体积省下的

38MB 到 9MB,流量费能感觉到

迁移一次的成本

两天,其中一天半在补链接和标签

后续维护

从“每月总得修一次依赖”变成“半年不用管”

最后一行的价值我个人觉得最大,但它没法写进任何一张对比表里。你只有在被依赖问题咬过一次之后,才会知道“没有依赖”这四个字值多少钱。

END

互动 · TALK

你们的站点是看服务器响应,还是看浏览器首屏?这两个数差得可能比框架还大。

👍
点赞
👀
在看
↗
转发

觉得有用,欢迎点赞、在看、转发

THANKS FOR READING

随机文章