大数跨境

如何减少 TTFB

如何减少 TTFB 索引目录
2025-03-13
0

目录

  • 测量 TTFB

  • 什么是追踪?

  • 使用 Sentry 在 Next.js 中设置跟踪

  • 自定义仪表

  • 使用 Sentry 减少 TTFB


TTFB(首字节时间)是一种常用指标,用于测量客户端的 HTTP 请求和收到服务器响应的第一个字节之间的时长。较低的 TTFB 意味着服务器响应更快,页面加载时间更快。在过去几年的 Web 开发领域,我们看到了在服务器上渲染网站的显著趋势。这样做有利于 SEO,并且在低功耗设备上表现更好,但我们必须牺牲一件事,那就是 TTFB。由于我们的页面是在请求时在服务器上渲染的(而不是在构建时静态预渲染),所以我们的浏览器必须等待更长时间才能让服务器响应。这会导致 TTFB 更高,而当 TTFB 更高时,其余的 Web 生命体征也会更高。在本文中,我们将了解如何识别导致 TTFB 过高的原因,以便我们能够修复它。
测量 TTFB
假设你有一个服务器端渲染的 Next.js 应用程序,并且你知道某些页面的加载速度比其他页面慢得多。你转到 Chrome DevTools 查看加载速度变慢的位置:



不幸的是,您唯一能得到的见解是浏览器花了两秒多的时间等待服务器响应,但 DevTools 不会向您显示页面加载时间轴中究竟是什么花了这么长时间。您可能还想在WebPageTest上运行一个测试:




再次,你看到肯定有问题,但你仍然不知道是什么原因造成的。这些工具只会向你展示浏览器看到和体验到的内容。服务器速度变慢导致 TTFB 过高,因此你需要一种不同类型的工具来查看加载页面时服务器上发生了什么。你需要跟踪



什么是追踪?
跟踪是一种常用于帮助您调试性能问题的工具,但它也可用于查找奇怪、复杂的错误,例如竞争条件。它的工作原理是创建“跨度”(最小工作单元),这些跨度相互链接,具有开始时间和结束时间,并且都属于同一个“跟踪”。我们围绕要测量的函数或代码块创建这些跨度。根据您使用的库,这些跨度也可以自动创建。我们将在本文中使用Sentry ,它直接与 Next.js 集成并创建调试高 TTFB 所需的大部分跨度。


跟踪也可以分布式,这意味着您可以在客户端启动跟踪,然后无缝地继续在服务器上跟踪。这会创建一个时间轴,记录客户端和服务器上发生的事情。Sentry 在所谓的火焰图中可视化跟踪及其所有跨度:

如果您想了解有关跟踪的更多信息,请查看我的另一篇文章“分布式跟踪:应用程序调试和监控的强大机制”。
使用 Sentry 在 Next.js 中设置跟踪
要在 Next.js 中设置 Sentry 的跟踪,你只需安装并配置 Sentry。按照说明运行应用程序后,你将开始向 Sentry 发送页面加载的性能数据:



从此屏幕截图中,我们可以清楚地看到浏览器和服务器上发生的事情的时间线。我们可以看到该getServerSideProps函数大约花费了 500 毫秒,这是 Cloudinary 请求。在这种情况下,请求是为了确保在我们呈现页面之前资源存在。我们可以优化它吗?当然,我们可以缓存它,或者找到另一种(更快)的方法来检查资源是否存在。
如果getServerSideProps函数是唯一的罪魁祸首,那么我们的优化就完成了!但在本例中,情况并非如此。我们可以看到,大部分减速甚至发生在getServerSideProps函数执行之前。那么在这之前会发生什么getServerSideProps?中间件!中间件不会自动检测,所以我们现在必须编写一些代码。
自定义仪表
这是中间件功能:

export async function middleware(request: NextRequest) { 
await checkAuth(request);

const { pathname } = request.nextUrl;

if (pathname.startsWith('/p/')) {
const publicId = pathname.split('/').pop();
if (publicId) {
await checkImageExists(publicId);
}
}

await checkLocale(request);
await updateRequest(request);
return NextResponse.next();
}



首先,我们检查身份验证,然后匹配请求是否针对照片页面。如果是,我们将调用一个函数来检查图像是否存在(听起来很熟悉?)。然后我们检查语言环境是否设置正确,我们用额外的数据和标签补充请求,然后调用该next() 方法。
为了添加自定义仪器,我们需要做的就是用 Sentry 的startSpan方法包装它:

import * as Sentry from '@sentry/nextjs'; 

export async function middleware(request: NextRequest) {
return await Sentry.startSpan(
{ name: 'middleware', op: 'middleware' },
async () => {
// the middleware code
}
);
}


因为这发生在浏览器启动跟踪之前,所以它将被视为单独的跟踪,因此我们需要查看之前看到的主页加载跟踪之外的内容。
如果我们运行这个,我们只会得到一个跨度,但这并不能帮助我们确定哪些函数占用了最多的时间。为了产生更详细的结果,我们需要进入每个函数并使用startSpan方法包装它们:

import * as Sentry from '@sentry/nextjs'; 
export const checkAuth = async (request: NextRequest) => {
await Sentry.startSpan({ name: 'check-auth', op: 'function.nextjs' }, () =>
// checkAuth function body
);
};


现在,如果我们再次运行应用程序并打开新的middleware跟踪,我们将看到以下内容:





我们可以看到,该checkAuth函数耗时 171 毫秒,该函数checkImageExists耗时 1.71 毫秒,该函数checkLocale耗时 132 毫秒,该函数updateRequest耗时 531 毫秒。这是对整个中间件函数的一个很好的细分,我们可以准确地看到每个函数花费了多少时间。
我们如何解决这个问题?好吧,我们可能可以做很多事情,例如,删除该checkImageExists函数,因为我们已经在页面中的函数中执行了检查getServerSideProps。删除它将大大加快中间件的速度。其他每个函数都有特定的实现,所以我们需要单独查看它们以找出如何优化它们,但这不是本文的主题。重要的是,我们要清楚地了解在服务器渲染页面时究竟发生了什么 - 在中间件中、在服务器上的页面处理程序中以及在浏览器中。
使用 Sentry 减少 TTFB
TTFB 很容易测量,但很难缩短。如今很多网站都在服务器上呈现,如果您不想让网站变慢,那么能够调试缓慢的 TTFB 是一项重要的技能。
要找出导致 TTFB 过高的原因,您需要使用 Chrome DevTools 或 WebPageTest 以外的工具。这些工具可以帮助您验证页面是否因 TTFB 过高而导致速度变慢,但无法帮助您找出原因。您需要实施跟踪
我们看到了使用 Sentry 实现跟踪是多么容易,以及跟踪视图如何向我们展示导致速度下降最严重的原因。Sentry 的自动检测帮助我们识别getServerSideProps函数中的优化机会。我们还注意到实际getServerSideProps函数执行前的等待时间很长,这告诉我们中间件是导致速度下降最严重的原因。我们使用 Sentry 的函数添加了自定义检测startSpan,并查看了哪个函数耗时最长。
跟踪是一种用于调试跨多个服务、项目或环境的复杂问题的重要工具。它跟踪整个应用程序(从前端到后端)中的请求流,并借此帮助您识别传统日志记录可能遗漏的性能瓶颈和故障。


【声明】内容源于网络
0
0
索引目录
索引目录是一家专注于医疗、技术开发、物联网应用等领域的创新型公司。我们致力于为客户提供高质量的服务和解决方案,推动技术与行业发展。
内容 444
粉丝 0
索引目录 索引目录是一家专注于医疗、技术开发、物联网应用等领域的创新型公司。我们致力于为客户提供高质量的服务和解决方案,推动技术与行业发展。
总阅读12
粉丝0
内容444