建站教程

建站教程

Products

当前位置:首页 > 建站教程 >

client-side-rendering: 客户端渲染CSR优化案例(js可以实现简单的秒表效果)

GG网络技术分享 2025-03-18 16:13 0


client-side-rendering: 客户端渲染CSR优化案例


该项目是 CSR 的案例研究,旨在探索客户端渲染应用程序与服务器端渲染相比的潜力。点击标题进入
术语:

  • CSR:客户端渲染
  • SSR:服务器端渲染
  • SSG:静态站点生成
  • UX:用户体验
  • DX:开发人员体验


在过去的几年里,服务器端渲染已经开始(重新)以Next.js和Remix等框架的形式流行起来。尽管 SSR 有一些优势,但这些框架一直强调它们的速度有多快(“默认性能”),这意味着客户端渲染速度很慢。此外,一个普遍的误解是,只有使用 SSR 才能实现出色的 SEO,而搜索引擎无法正确抓取 CSR 应用程序。
该项目实现了一个基本的 CSR 应用程序,并进行了一些调整,例如代码拆分,其目标是随着应用程序的扩展,单个页面的加载时间大部分不会受到影响。目标是模拟生产级应用程序中使用的包数量,并尝试尽可能地减少其加载时间,主要是通过并行化请求。
需要注意的是,提高性能不应该以牺牲开发人员的经验为代价,所以这个项目的架构方式应该与“正常”的 react 项目相比只有轻微的变化,并且不会像 Next.js 那样极端固执己见。
本案例研究将涵盖两个主要方面:性能和 SEO。与 SSR 和他们自己相比,我们将尝试在这两个方面取得高分。

SSR服务器端渲染缺点
以下列出了一些不应掉以轻心的 SSR 缺点:

  • 当转向客户端数据获取时,SSR总是比 CSR 慢,因为它的文档总是更大并且下载时间更长。
  • SSR 应用程序总是比 CSR 应用程序更重,因为每个页面都由完全构建的 HTML 文档及其脚本(用于水化)组成。
  • 由于所有图像最初都包含在文档中,因此脚本和图像将争夺带宽,从而导致慢速网络上的交互延迟。
  • 由于在服务器渲染阶段访问与浏览器相关的对象会引发错误,因此一些非常有用的工具变得无法使用,而其他工具(例如react-media)则需要特定于 SSR 的自定义。
  • SSR 页面响应大多不返回304 Not Modified状态。


当我们谈到 SSR 的渲染流程时,我们脑海中描绘的画面如下:

浏览器请求===>初始 HTML 到达(页面可见)===>JS 到达(页面是交互式的)


但实际上,大多数 SSR 网站并没有内联关键 CSS。所以实际的渲染流程如下:

浏览器请求===>初始 HTML 到达===>CSS 到达(页面可见)===>JS 到达(页面是交互式的)


这使得 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 已经完全加载。
优化最佳实践:

  • CSR性能提升技巧
    捆绑大小 缓存 代码拆分 预加载异步块 生成静态数据 预加载数据 进一步调整
    从异步块中拆分供应商 预加载其他页面数据 防止顺序渲染 过渡异步页面 预取异步页面 部署 基准 需要改进的方面 模块联合
  • 搜索引擎优化
    站点地图 索引
    谷歌 其他搜索引擎 社交媒体分享预览
  • CSR 与 SSR
    SSR的缺点 内联 CSS 为什么不是 SSG?


结论
我们看到客户端渲染性能在加载时间方面与 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优化案例

js可以实现简单的秒表效果

实现一个简单的秒表,点击启动按钮时开始计时,随后启动按钮变为暂停,

点击暂停暂停计时,点击复位回到最初始状态。

效果:

js可以实现简单的秒表效果 (https://www.wpmee.com/) javascript教程 第1张

代码如下

<!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