本文简单介绍了Web应用的各种渲染方案,包括客户端渲染、服务端渲染等渲染方案。文章翻译自:https://developers.google.com...。由我团队联合翻译发表于前端技术公众号:FangstoolCollection,转载于此。房僧雅集是阿里CBU前端技术的专业号,感兴趣的朋友可以关注一下。1.扬帆起航作为开发人员,我们经常面临影响应用程序整个架构的决策。我们必须做出的核心决策之一是在哪里实现业务逻辑和渲染逻辑。这可能很困难,因为构建网站的方法有很多种。对这个领域的理解来自于我们过去几年在一些大型网站上的工作。从广义上讲,鼓励开发人员选择具有再水化(在下一节中解释)或静态渲染的服务器端渲染。为了在做出决定时更好地理解我们选择的架构,我们需要对每种方法和术语有扎实的了解,不同渲染方法的页面性能可以帮助我们理解它们之间的差异。2.术语渲染:SSR:服务器端渲染。CSR:客户呈现。补水:基于服务端渲染的dom树和数据,浏览器端使用JavaScript再次渲染。预呈现:在构建时生成静态HTML和页面的初始状态。性能:TTFB:TimetoFirstByte——从浏览器发送资源请求到接收到资源的第一个字节的时间。FP:FirstPaint——从页面打开到呈现视觉内容的第一个像素的时间。FCP:FirstContentfulPaint——从页面打开到页面主要内容可见的时间。TTI:TimeToInteractive——页面打开进入交互状态的时间。这里只是简单介绍一下这些性能术语。如果你想详细了解它们,你可以阅读我们之前写的两篇文章。指标中心(b)。3.服务器端渲染服务器端渲染:当页面打开时,服务器生成完整的HTML并返回。这样就避免了在浏览器端获取和渲染的成本,因为这些事情在服务器响应用户之前就已经完成了。服务器端渲染会带来快速的FP和FCP,在服务器端处理业务逻辑和渲染逻辑,可以避免向浏览器发送大量的JavaScript,有助于实现快速的TTI,这种方式适用于各种设备和网络环境,如果启用一些流式浏览器优化,例如流式文档解析。对于服务器端渲染,用户不太可能等待浏览器执行其他消耗CPU的JavaScript代码再继续,因为页面内容已经显示。当无法避免第三方js(打广告)时,服务端渲染虽然可以减少FP、FCP渲染的JavaScript消耗,但可能会给接下来要执行的js带来一定的“负担”。服务端渲染的主要缺点是渲染需要时间,所以TTFB可能比较大。服务器渲染是否足以满足应用程序的需求在很大程度上取决于您正在构建的体验类型。关于哪个更好的服务器端渲染或客户端渲染的争论从未停止过。但我们需要记住的是,我们可以选择让一些页面在服务器端呈现,而另一些在客户端呈现。一些网站使用这种混合渲染模式取得了不错的效果。比如Netflix的登录页面使用了服务端渲染,同时对于交互性强的页面预取js,对那些交互性强、客户端渲染的页面进行页面加速。加载的机会。许多现代框架、库和体系结构使同一个应用程序可以同时在服务器和浏览器中呈现。虽然这些技术可用于服务器端渲染,但需要注意的是,用于在服务器和客户端上渲染的架构具有非常不同的性能特征和权衡。React用户可以使用它的renderToString方法或者其他基于该方法的框架进行服务端渲染,比如Next.js;Vue用户可以参考其服务端渲染指南或Nuxt;Angular用户可以参考Universal。4.静态渲染静态渲染:在构建(build)时,直接渲染页面中不会变化的内容,然后打入HTML。在浏览器端需要执行的js有限的假设下,该方法可以提供快速的FP、FCP和TTI。与服务器端渲染不同,它还提供了一个快速的TTFB,因为不需要在服务器端生成HTML。一般来说,静态渲染需要为每个URL生成一个单独的HTML。用户访问时,直接返回预渲染的HTML即可。另外渲染出来的HTML也可以部署到CDN,通过边缘缓存(edgecaching)做一些优化。不了解边缘缓存的同学可以看一下我们之前写的React缓存笔记,里面有关于它的介绍。静态渲染也有不同的方案,像Gatsby这样的工具旨在让开发人员感觉他们的应用程序是动态渲染的,而不是在构建过程中生成静态HTML;Jekyl和Metalsmith等工具包含静态属性,提供许多模板驱动的方法。静态渲染需要为每个URL生成单独的HTML,这是它的缺点之一。如果你无法提前预知这些URL的内容,或者一个网站有大量的URL,那么静态渲染可能就不合适了。对于静态渲染,React用户可能熟悉Gatsby、Next.js静态导出或Navi。这里需要重点理解静态渲染和预渲染的区别:静态渲染的页面只需要执行很少的js代码,浏览器就可以交互了;虽然预渲染可以实现FastFP、FCP,但是应用必须在浏览器端执行js代码才能变得交互。如果你不确定是使用静态渲染还是预渲染,那就测试一下,在应用程序加载时禁用JavaScript加载和执行。禁用JavaScript后,对于静态渲染,页面的大部分功能仍然可以正常工作;对于预渲染,只有页面的一些基本功能可能起作用,例如连接跳转。另一个有用的测试是通过Chrome的DevTools减慢网络速度,以查看在页面变为交互之前下载了多少JavaScript。预渲染通常需要更多的JavaScript,并且通常比具有渐进增强的静态渲染更复杂。5.服务端渲染VS静态渲染服务端渲染不是灵丹妙药,其动态特性会带来巨大的计算开销。服务器端渲染会增加TTFB或发送双重数据(例如将客户端状态数据键入HTML)。在React中,renderToString会很慢,因为它是同步的和单线程的。为了使服务器端渲染“正确”工作,我们需要关注组件缓存、内存消耗、memoization技术的应用等问题。很多时候,您可能需要多次渲染同一个应用程序——一次在服务器上,一次在客户端上。服务端渲染只能让需要显示的内容更快,并不能减少工作量。服务器端渲染可以根据不同的URL生成不同的内容,其速度可能比静态渲染慢。其实我们可以做一些工作来缓解这个问题,服务端渲染+HTML缓存可以大大减少渲染时间。服务端渲染的优势在于可以获取实时数据,并且可以处理比静态渲染更大的一组请求。因为静态渲染只能处理可以提前预知内容的页面,静态渲染无法处理需要个性化(千人千面)的页面。在构建PWA时,服务器端渲染也很有用。服务器端渲染页面碎片,前端使用ServiceWorker进行缓存。6.客户端渲染客户端渲染:是指直接在浏览器中使用JavaScript渲染页面,所有的逻辑、数据获取、模板、路由都在客户端处理,而不是在服务端。在移动端,客户端渲染很难实现并保持较快的渲染速度。有时我们只需要做一点工作就可以让客户端渲染的性能和服务端渲染的性能几乎一样,比如保持尽可能小的JS体积和尽可能小的RTT(https://en.wikipedia.org/wiki...)。即使使用HTTP/2服务器端或使用
