ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SSR并非万能药:详解优缺点与技术选型,避免简历驱动开发

SSR并非万能药:详解优缺点与技术选型,避免简历驱动开发 前两天一个做前端的朋友找我聊技术选型说新项目在纠结要不要上SSR。我照例先问一句你现在遇到了什么真实问题是SEO没收录还是首屏太慢他想了半天挤出一句好像都没有但不上SSR感觉简历都没法更新了。这句话我这些年听过太多次。作为一个在电商中台、内容平台、SaaS后台之间来回切换、也亲手维护过一堆老SPA项目的前端技术人我想认真回答一个问题你的项目真的需要SSR吗还是说需要它的其实只是你的简历这篇文章不贴大段代码更像是一次架构评审复盘——把SSR真正解决的问题、引入的成本、可替代的方案、以及做决策前必须问自己的几个问题一次性讲透。适合正在做技术选型的团队负责人也适合一个人扛前端、想搞清楚下一步要不要折腾一轮重写的独立开发者。1. SSR被神化的背后它真正解决的只有两个问题先把SSR到底在解决什么说清楚。传统SPA的响应过程是这样的浏览器拿到一个几乎空的HTML外壳里面只有一个root节点和一堆script标签然后下载JS、解析执行、通过JS发API请求、拿到数据后再把页面渲染出来。整个过程里用户盯着白屏搜索引擎看到的也基本是白纸一张。SSR的思路是把渲染HTML这件事挪到服务器端完成。用户请求进来时服务器直接执行组件代码、取数、拼出一份完整HTML返回给浏览器浏览器拿到就能直接显示内容之后再用JavaScript把交互事件绑回去这一步叫hydrate水合。听起来很美好但你要明白SSR从诞生那天起真正能解决的问题只有两个内容可见性以及首屏渲染速度。任何超出这两条线的理由都得打个问号。1.1 搜索引擎到底能不能爬你的SPA先聊内容可见性。很多人对SPA无法做SEO的理解还停留在十年前现实情况要复杂得多。Google的爬虫确实会执行JavaScript但它是分两波走的第一波先抓原始HTML第二波再用无头浏览器渲染JS执行后的页面。这带来一个很现实的问题——你的SPA不是不会被收录而是收录很慢、很不稳定。Google会给每个页面分配render budget如果你的JS体积太大、接口响应太慢第二波渲染很可能直接超时放弃页面就一直停留在已抓取未索引的状态。至于百度、必应以及微信内嵌浏览器里分享链接时的卡片预览、微博和Telegram的链接摘要抓取对JS的兼容性就更看心情了。很多项目声称为了SEO所以要上SSR结果连百度站长平台都没提交过流量来源也全是广告投放和App导流那这个理由就纯粹是自我感动。判断标准其实很俗你的页面是公开的、需要被搜索引擎收录并且能带来真实转化吗如果答案是不那SEO这条理由可以直接划掉。1.2 首屏到底慢在哪里再说首屏渲染。SPA在低端设备上的体验确实一言难尽JS要下载、要解析、要执行这期间页面就是一片白。但不妨先搞清楚一件事你的首屏慢瓶颈到底在哪儿是JS执行太慢还是API响应太慢还是图片资源太大这里有个容易被忽略的事实——SSR只是把白屏等JS变成了白屏等服务器渲染完。如果你的页面里有一个串行依赖的慢接口服务器端也一样要等它。SSR确实能让FCP首次内容绘制和LCP最大内容绘制明显变好但代价是TTFB首字节时间可能变差因为服务器得先完成取数和渲染才吐第一个字节。很多时候你测出来的首屏慢问题出在一个能缓存的图片、一段不用阻塞的脚本或者一个应该做并发请求的接口上这些跟SSR一毛钱关系都没有。要判断到底值不值先拿你线上最慢的页面做个Lighthouse实测看看耗时构成再说话。2. 四个常见的上SSR理由一个比一个站不住脚我参与过的架构评审里推动SSR的理由翻来覆去就这么几类。几乎每一个最后都能扒出一个没被验证的假设。2.1 为了SEO——可你的页面根本不需要被收录这个理由最普遍也最经不起追问。需要被搜索引擎收录的只有一种页面公开的、能被站外用户通过搜索触达的、而且你愿意投入精力做关键词运营的页面。后台管理系统不是需要登录才能看的SaaS控制台不是内部数据分析平台更不是——这些产品的用户永远是通过URL、书签和导航进入的搜索引擎连登录页都爬不进来你做SSR给谁看判断方法很简单把话说透我做一个纯后台项目用户全部是公司内部员工页面全部在登录态后面——那我为什么要关心Google能不能抓到它就算Google抓到了能访问吗搜索引擎在登录墙外面什么都看不到SSR做得再好也是对着空气优化。这类项目真正需要做的是登录后的页面性能优化、路由级代码分割、骨架屏这些和SSR没有半点关系。2.2 为了首屏速度——但瓶颈往往不在JS执行还有一拨人Slogan是首屏太慢所以要SSR。我一般会反问你做过性能剖析吗是白屏时间太长还是内容出现后一直在跳还是接口数据迟迟不来如果最大那块图片占了LCP的三秒SSR完全帮不上忙如果主JS包有3MB拆分和压缩比SSR性价比高得多如果接口串行调用SSR只是让这个问题从浏览器搬到了服务器。真实案例之前有个电商小程序的管理后台首屏慢到用户抱怨团队提出要重构成SSR。结果排查下来是列表页里有个统计接口要跑12秒而且前端串行等了三个接口才渲染。最后我们把统计接口改异步、把三个请求并行化首屏直接快了三倍全程没有碰SSR。不是数据渲染位置的问题是数据获取链路的问题——这个问题搬到服务器上也一样慢。2.3 为了用户体验——SSR也可能让体验更差很多人没意识到SSR在改善某些指标的同时也在恶化另外一些指标。首先是字节量SSR返回一份渲染好的HTML同时浏览器还要下载同样一份JavaScript来做水合等于用户买了两份内容。在弱网环境里总下载字节可能比纯CSR更高白屏虽然短了但可交互时间TTI不见得变好甚至可能更差。其次是水合不匹配问题。服务器渲染的HTML和客户端首次渲染的结果如果对不上常见于依赖当前时间的组件、随机数、浏览器存储状态React会在控制台报Hydration mismatch你只能靠抑制警告来掩盖或者把组件改成客户端再渲染。这类问题在真实项目中几乎必踩不是技术能力问题是同一段代码跑在两个环境里这件事天然就有坑。2.4 为了简历——这个理由最危险这就是我最想聊的那种理由。简历驱动开发的核心特征是技术选型的第一优先级不是解决业务问题而是这个技术写在简历上好不好看。SSR恰好是个典型——它是面试官听得懂、又不会深究你优化的每一项指标都带来了什么业务收益的技术名词。但你要想清楚一件事简历上写主导SPA向SSR架构升级只需要一行字可这个升级的后果——半夜被报警叫起来处理Node服务OOM、排查一个只有线上环境才出现的取数错误、给团队普及两套运行环境下的开发规范——是实打实要你还的债。你拿到offer就走了剩下的坑全是团队在填。被这么坑过的技术负责人会在下一次评审里对所有新技术都变得更加保守这何尝不是对整个行业信任度的一种消耗。3. 部署SSR的隐性账单技术债到底有多少如果前面的理由都过了确实是强业务需求那也先别急着动手。SSR不是换一种写法那么简单它是一次基础设施层面的变更。这台机器的全生命周期成本很多人一开始根本没算进去。3.1 架构复杂度从静态托管到常驻服务纯SPA的部署是全世界最简单的发布流程构建、上传静态文件到CDN/OSS、完事。没有服务器没有进程没有环境变量管理出问题最多回滚上一个版本。上了SSR你得到的东西包括但不限于一个常驻运行的Node服务、进程管理PM2或容器编排、健康检查、优雅退出、日志采集、监控告警、横向扩容后的负载均衡策略。这些以前完全不用你管的东西现在全部落到团队头上。CI/CD也变了。以前构建产物传CDN一条流水线就够现在要构建镜像、推送镜像、滚动发布、验证服务恢复。不要小看这一步很多团队的DevOps能力其实不足以支撑一个24小时在线的前端服务。我见过不止一个项目SSR上线三个月后因为没人愿意运维悄悄降级回静态托管——不是SSR不好是他们低估了运维的持续性成本。3.2 运行成本内存、并发与崩溃恢复SSR服务的内存模型和普通API服务不一样。每个请求进来你都要跑一遍React组件渲染要分配V8堆内存、执行组件生命周期、存储临时数据。并发一高内存直接往上飙。你以为一个页面平均2MB内存没什么200个并发同时打过来那就是400MB起步再加上Node的GC机制小内存实例分分钟OOM给看。还有上游依赖。你的页面要调商品服务、库存服务、用户服务任何一个上游超时轻则这个请求渲染失败重则拖垮整个Node进程。所以你必须给所有上游请求设置超时时间、做降级兜底、给渲染过程加超时保护。这里有一个很反直觉的点SSR让前端第一次直接暴露在流量攻击和突发并发之下以前CDN扛在最前面现在你的Node服务成了第一防线。3.3 开发体验双重运行环境带来的调试地狱这是所有上过SSR的人最有共鸣的一条。你的组件代码既要能在Node里跑也要能在浏览器里跑。于是你不得不开始处理一系列浏览器才有的东西window用不了、document不存在、localStorage会报错。每写一个涉及浏览器API的组件都要先判断当前环境或者用动态导入只在客户端加载。举段常用的防护代码你就懂了// 服务端没有 window一跑就崩 if (typeof window ! undefined) { const width window.innerWidth; // 只在浏览器里执行的逻辑 }这还只是开始。有些第三方库默认依赖浏览器全局对象编译时就要做shim调试时你要分清楚一个报错是发生在服务端渲染阶段还是客户端水合阶段两边的堆栈长得完全不一样日志要分两套错误上报要标记环境。所有这些都在消耗你每天的开发效率。这不是什么不可逾越的难题但它是纯CSR项目完全不需要承担的隐性成本。3.4 数据获取的重复执行陷阱SSR有个经典坑同样的页面数据服务器渲染时取了一遍客户端水合时又取了一遍。为了不闪一下又为了不重复请求你不得不把服务器端的数据序列化塞进HTML里的一个全局变量比如window.__INITIAL_STATE__让客户端直接用它来完成水合。这一套逻辑增加了不少心智负担也带来一个更隐蔽的安全问题——所有塞进HTML里的数据用户都能看到。你以为数据在服务端处理就安全但服务器渲染出来的HTML最终是发给浏览器的里面带什么字段用户就能看到什么字段。如果把不该暴露的内部接口字段、权限相关信息也一股脑serialize进去那就是直接把隐私晾在页面源代码里。这类问题在SSR项目里出现频率远比你想象的高。4. 大多数项目真正需要的SSG、预渲染还是混合方案讲了这么多成本不是要劝退你彻底不碰SSR。而是想说在CSR和全量SSR中间还有一整个光谱的中间方案。多数项目的最优解其实都在这个光谱里。4.1 SSG内容型项目的正确答案静态站点生成SSG的逻辑是构建时就把所有页面渲染成静态HTML然后传到CDN。用户请求时CDN直接返回文件连源站都不回TTFB基本是全网最快同时服务器成本约等于零、运维成本约等于零、安全性还高因为根本没有动态代码可以被打。对博客、文档站、官网、活动落地页这类内容更新不频繁的项目SSG几乎是标准答案。用Astro、Hugo、Eleventy或者Next.js的静态导出模式都行。内容更新了就重新构建发布一下数据库都不需要。你要做的取舍只有一个内容跟用户请求的实时性关联强不强如果答案是不强SSG永远优先于SSR。4.2 预渲染给SPA套一层静态壳如果你已经有了一套运行良好的SPA不想推倒重来又确实想要机器人能看到内容这个能力预渲染是性价比极高的妥协方案。思路是用react-snap或prerender-spa-plugin这类工具在构建阶段用无头浏览器把每个路由跑一遍把渲染结果拍成静态HTML快照。线上服务时搜索引擎和首次访问者拿到的是快照之后框架照常水合接管。它的问题也很明确快照是构建那一刻的状态内容更新后快照不更新除非重新构建。另外遇到强依赖用户登录态的页面拍出来也是一张空壳。所以预渲染适合大部分内容公开、小部分动态逻辑的项目——用它拿到Seo和首屏收益,同时保留SPA的开发体验。坦白讲很多喊着要上SSR的项目一个预渲染插件就解决了80%的问题剩下20%是想象出来的。4.3 岛屿架构与流式渲染两个折中思路再往外延伸一点还有两张更现代的牌可以打。一张是岛屿架构Islands Architecture核心思想是整页大部分内容是静态HTML只有少数交互组件是岛屿这些岛屿独立提供JS并按需水合。Astro就是这套思路的代表。它特别适合内容多、交互少的页面——既有SSG的速度又有SPA的局部交互能力还不用承担整页水合的巨大成本。另一张是流式渲染。React 18的renderToPipeableStream允许服务器先把HTML的壳子返回给浏览器然后边取数据边把后续内容流式追加过去。它的最大价值在于TTFB变得非常快用户先看到页面骨架和已经就绪的部分其余内容陆续填充。Next.js App Router内部就用了这套机制。这两张牌都比上一次SSR全页面服务器渲染要精细也更符合现代前端的优化思路。方案内容更新方式首屏速度服务器成本运维复杂度适用场景CSR每次请求动态拉取依赖JS执行无静态托管极低后台、工具型应用SSG构建时生成极快无极低博客、官网、文档预渲染构建时快照快无低已有SPA的SEO优化SSR每请求渲染中依赖服务端中高高强SEO实时内容岛屿架构静态局部交互快无中内容型少量交互5. 动手之前先回答这几个问题再决定如果你读完前面还在犹豫那最好。犹豫说明你在认真评估。这里给一个我常用的决策清单从业务属性出发反推技术选型而不是从技术名词出发寻找存在的理由。5.1 三个核心问题判断业务属性第一个问题你的页面需要被搜索引擎收录并且关键词排名是真实的获客手段吗回答不是的SEO这条理由直接删除。第二个问题你在低端设备、弱网环境下的真实用户有没有因为首屏白屏而流失要拿数据说话不是感觉。打开Google CrUX或者用Lighthouse跑一次Field Data看看真实的LCP分布如果75分位的LCP本来就达标SSR优化出来的成绩只是锦上添花。第三个问题你的团队有没有能力运营一个7x24小时的Node服务包括监控、日志、告警、升级、复盘。三个问题如果都是是SSR可以进入候选只要有一个不是继续往下找替代方案。5.2 按业务场景对号入座结合上面的判断逻辑我用一张表把常见场景的推荐方案列出来方便你直接对号入座场景核心需求推荐方案博客/文档/官网SEO强需求、内容更新慢SSG电商商品页SEO实时库存、价格SSR 或 SSG客户端取数内容平台文章页SEO快速发布SSG内容发布时增量构建SaaS官网应用官网要SEO、应用要登录SSG官网 CSR应用管理后台/报表无SEO、强交互CSR实时数据大盘无SEO、数据实时刷新CSRWebSocket5.3 给中小团队的现实参考如果你是三个人以内的前端团队我的建议偏向保守先选工程量最小的方案拿到可量化的结果再决定要不要升级。从CSR升级到预渲染大部分时候改动量很小从预渲染升级到SSR至少你保留了此前的大部分代码。反过来一上来就全套SSR如果团队撑不住运维你就只能在一片混乱中做减法回退那才是最大的浪费。记住一个原则架构演进应该是可逆的选一个能撤回的方案比选一个最酷的方案重要得多。6. SSR到底还学不学以及怎么避免简历驱动开发落到个人层面这个问题其实很动人心魄我学了SSR是不是就没有白学我简历上不写SSR是不是就落后了我的答案可能和你想的不太一样。6.1 简历驱动开发的隐性代价我自己也干过简历驱动的事最典型的一次是给一个用户量刚过千的内部工具上了全套微前端理由无非是想试试。结果呢三个月的开发周期拖成七个月中间出了无数环境问题最后我离职了留下一个没人能完全说清的工程给后来者。那行写在简历上的主导微前端架构落地回头想想其实是拿团队的时间给大家交学费。简历驱动开发最隐蔽的代价不是你浪费了时间而是你消耗了信任。当团队里有人因为你提议的技术栈踩了坑以后你说这个新技术值得试的时候同伴的第一反应是上次也是这样说的。技术选型这件事业务价值永远排在第一个人成长排第二简历上的字数是排在最后面的。顺序一旦反了早晚有一天你会发现自己写了一堆看起来厉害的东西但它们之间没有任何一条业务逻辑能串起来。6.2 SSR值得学但建议换个姿势SSR本身当然是一门值得学的技术。它背后的流式渲染、水合机制、服务端状态管理、缓存策略每一块都是硬功夫学会了不亏。但学习和在项目里采用是两码事。想学SSR完全可以用一个小Demo项目来练手搭一个Next.js应用接一个真实接口跑一遍Lighthouse对比CSR和SSR在TTFB、FCP、LCP、TTI上的差异写一篇带数据的技术笔记。这个过程的效果比在业务项目里硬塞一个SSR要好得多。更关键的是面试官真正想看到的不是你用过SSR而是你能不能判断什么时候不该用SSR。我在面试里问起技术选型时最打动我的回答不是我们用了SSR并且性能提升了30%而是我们评估过SSR最后没有采用原因是我们的页面全部在登录墙后面SEO没有意义首屏瓶颈在接口而不在渲染所以我们用代码分割和接口优化解决了问题。这段话展示的判断力和业务思维比一行熟悉SSR值钱十倍。6.3 一点个人体会我这些年最大的感受是架构评审会上翻车的很少是技术本身不行绝大多数是团队说不清楚为什么要做这个选择。技术选型这件事本质是讲一个关于取舍的故事——你放弃了什么换来了什么依据是什么。当你下次再有人问要不要上SSR时能自信地说出这个问题取决于三件事内容要不要被搜索引擎看到、首屏瓶颈到底在哪、团队扛不扛得住运维成本你就已经比大多数嚷嚷着必须SSR不然没法交差的人往前迈了一大步。至于简历它真正需要记录的从来不是你会哪些名词而是你在哪些关键岔路口做出了有理有据的决定——后者才是经得起追问的东西。
返回列表