Products
GG网络技术分享 2025-03-18 16:13 0
该项目是 CSR 的案例研究,旨在探索客户端渲染应用程序与服务器端渲染相比的潜力。点击标题进入
术语:
在过去的几年里,服务器端渲染已经开始(重新)以Next.js和Remix等框架的形式流行起来。尽管 SSR 有一些优势,但这些框架一直强调它们的速度有多快(“默认性能”),这意味着客户端渲染速度很慢。此外,一个普遍的误解是,只有使用 SSR 才能实现出色的 SEO,而搜索引擎无法正确抓取 CSR 应用程序。
该项目实现了一个基本的 CSR 应用程序,并进行了一些调整,例如代码拆分,其目标是随着应用程序的扩展,单个页面的加载时间大部分不会受到影响。目标是模拟生产级应用程序中使用的包数量,并尝试尽可能地减少其加载时间,主要是通过并行化请求。
需要注意的是,提高性能不应该以牺牲开发人员的经验为代价,所以这个项目的架构方式应该与“正常”的 react 项目相比只有轻微的变化,并且不会像 Next.js 那样极端固执己见。
本案例研究将涵盖两个主要方面:性能和 SEO。与 SSR 和他们自己相比,我们将尝试在这两个方面取得高分。
SSR服务器端渲染缺点
以下列出了一些不应掉以轻心的 SSR 缺点:
当我们谈到 SSR 的渲染流程时,我们脑海中描绘的画面如下:
|
但实际上,大多数 SSR 网站并没有内联关键 CSS。所以实际的渲染流程如下:
|
这使得 SSR 流程几乎与CSR 流程相同,唯一的区别是在 CSR 中,浏览器也必须等待 JS 完成加载,才能绘制屏幕。这就是为什么两者之间的FCP差异很小,有时甚至不存在(尤其是在快速互联网连接下)。
我们有Next.js和Remix网站来展示关键 CSS 内联的缺失。
不提取关键 CSS 的主要原因是 HTML 变得更大(延迟交互性)并且 CSS 变得不可缓存。
SSG静态站点生成缺点
我们已经看到了静态文件的优点:它们是可缓存的;可以为他们返回304 Not Modified状态;它们可以从附近的 CDN 提供服务,并且不需要 Node.js 服务器。
这可能会让我们相信 SSG 结合了 CSR 和 SSR 的优势:我们可以让我们的应用程序在视觉上看起来非常快(FCP),它甚至可以非常快地进行交互。
然而,在现实中,SSG 有一个很大的限制:由于 JS 在最初的时候是不活跃的,所有依赖于 JS 来呈现的东西根本就不可见,或者它会在不正确的状态下可见
以下网站演示了此问题的一个经典示例:https ://death-to-ie11.com
请注意计时器如何无法立即使用?那是因为它是由JS生成的,下载和执行需要时间。有很多关于这种延迟功能如何损害 UX 的示例,例如某些网站仅在 JS 加载后才显示导航栏的方式。
水合作用的代价
在处理慢速连接(例如移动网络)时,SSR 似乎在加载时间方面优于 CSR。
虽然这看起来是一个很大的优势,但这种行为在连接速度慢时有一个主要缺陷——在加载 JS 之前,用户可以点击他们想要的任何地方,但应用程序不会对它们做出反应。当按钮不响应点击事件时可能会带来一些不便,但如果不阻止默认事件,它就会成为一个更大的问题。
换句话说,在 SSR 应该比 CSR 具有性能优势的地方,我们看到了一种非常“危险”的行为,它可能只会降低 UX。
在 CSR 应用程序中不可能发生此问题,因为它们呈现的那一刻 - JS 已经完全加载。
优化最佳实践:
结论
我们看到客户端渲染性能在加载时间方面与 SSR 相当,有时甚至优于 SSR。我们还了解到,使用预渲染可以提供完美的 SEO 效果,而且一旦设置好,我们甚至不需要考虑它。最重要的是——我们主要通过修改 2 个文件(Webpack 配置和 HTML 模板)和使用预渲染服务来实现这一切,因此每个现有的 CSR 应用程序都应该能够快速轻松地实现这些修改并从中受益。
这些事实得出的结论是,没有理由再使用 SSR,它只会给我们的项目增加很多复杂性和限制,并降低开发人员的体验。
Reddit网友评论
1、SSG 在本文中得到了不公平的待遇。虽然我同意 SSG 对于客户端交互繁重的应用程序并不理想,但我认为 Web 上的大多数网站实际上会通过切换到 SSG 来显着提高他们的用户体验。如果你有一个交互繁重的应用程序(想想像秒表网站或媒体控件)或一个严重依赖用户数据的页面(想想 facebook、twitter 和 co),SSG 不适合你。在大多数其他情况下,您可能会从中受益。
2、SSR 在第一次加载时可能(只是可能)更快,但 CSR 在第二次及以后的加载中总是更快。
3、并不是搜索引擎不能抓取 CSR,而是他们必须使用无头浏览器进行更昂贵(就资源而言)的抓取。查看“Google 抓取预算”。因此,CSR 网站的抓取频率可能会降低。
4、预渲染时遇到的一个问题是,如果您有数千个页面需要预渲染,那么服务根本就跟不上。如果每月有 1000 万个请求,却只有数万个页,但它们每天更新多次。
项目进入后点击标题:client-side-rendering: 客户端渲染CSR优化案例
实现一个简单的秒表,点击启动按钮时开始计时,随后启动按钮变为暂停,
点击暂停暂停计时,点击复位回到最初始状态。
效果:
代码如下
<!DOCTYPE html> <html lang=\"en\"> <head> <meta charset=\"UTF-8\"> <title>Title</title> <style> #showTime { width: 300px; height: 60px; font-size: 60px; line-height: 60px; } </style> </head> <body> <div> <div id=\"showTime\">00:00:00</div> <button id=\"startBn\">启动</button> <button id=\"restBn\">复位</button> </div> <script> //—————— var time,showTime,startBn,restBn,pauseDate; //布尔开关 var bool=false; //暂停的累计时间 var pauseTime=0; init(); function init() { showTime=document.getElementById(\"showTime\"); startBn=document.getElementById(\"startBn\"); restBn=document.getElementById(\"restBn\"); startBn.addEventListener(\"click\",clickHandler);//开始按钮 ~ 暂停按钮 restBn.addEventListener(\"click\",clickHandler);//复位按钮 setInterval(animation,16); } //转化时间函数 function animation() { if(!bool) return; //前时间减去上次开启时间减去暂停累计时间 var times=new Date().getTime()-time-pauseTime; var minutes=Math.floor(times/60000);//毫秒转化为分钟 var seconds=Math.floor((times-minutes*60000)/1000);//已知分钟 将time减去分钟 除去1000得出 秒 var ms=Math.floor((times-minutes*60000-seconds*1000)/10);// showTime.innerHTML= (minutes<10 ? \"0\" +minutes : minutes)+\":\" +(seconds<10 ? \"0\"+seconds :seconds)+\":\" +(ms<10 ? \"0\"+ms : ms); } //点击时的事件 function clickHandler(e) { e= e || window.event; if(this===startBn){ bool=!bool; if(bool){ this.innerHTML=\"暂停\"; //如果我们上一次暂停时间是空,表示没有暂停过,因此,直接返回0 //如果上次的暂停时间是有值得,用当前毫秒数减去上次的毫秒数,这样就会得到暂停时间 pauseTime+=(!pauseDate ? 0 : new Date().getTime()-pauseDate); if(time) return; time=new Date().getTime(); return;//是为bool判断跳出 } this.innerHTML=\"启动\"; pauseDate=new Date().getTime(); return;//是为this是否等于startBn判断跳出 } startBn.innerHTML=\"启动\"; pauseTime=0; pauseDate=null; bool=false; time=0; showTime.innerHTML=\"00:00:00\"; } </script> </body> </html> |
以上就是js如何实现简单的秒表效果的详细内容,更多请关注php中文网其它相关文章!
Demand feedback