流媒体
流式传输允许您在内容可用时立即提供内容,而不是等待整个页面内容准备就绪,从而增强用户体验。
确保您的托管服务提供商支持流媒体,并非所有提供商都支持。如果您的响应似乎无法流式传输,这可能是原因。
步骤
流式传输数据分为三个步骤:
- 项目设置:我们需要确保我们的客户端和服务器入口点已设置为支持流式传输
- 组件设置:我们需要确保我们的组件可以呈现流式传输数据
- 延迟加载器数据:最后我们可以在加载器中延迟数据
1. 项目设置
从一开始就准备就绪:使用入门模板创建的 Remix 应用程序已预先配置为流式传输。
是否需要手动设置?:如果您的项目是从头开始的,或者使用了较旧的模板,请验证 entry.server.tsx
和 entry.client.tsx
是否支持流式传输。如果您没有看到这些文件,则表示您正在使用默认设置,并且支持流式传输。如果您创建了自己的条目,以下是模板默认设置供您参考:
2. 组件设置
没有流式传输的路由模块可能看起来像这样:
为了呈现流数据,您需要使用 React 中的 <Suspense>
和 Remix 中的 <Await>
。这有点像样板,但很简单:
在我们开始延迟数据之前,此代码将继续工作。最好先编写组件代码。如果遇到问题,可以更轻松地找到问题所在。
3. 在 Loader 中延迟数据
现在我们的项目和路由组件已设置好流数据,我们可以开始在加载器中延迟数据。我们将使用 Remix 中的 defer
实用程序来执行此操作。
注意异步承诺代码的变化。
我们不再等待评论承诺,而是将其传递给defer
。这会告诉 Remix 通过网络将该承诺传输到浏览器。
就这样!您现在应该正在将数据传输到浏览器。
避免低效的流式传输
在等待任何其他承诺之前,发起延迟数据的承诺非常重要,否则您将无法充分利用流式传输。请注意与这个效率较低的代码示例的区别:
处理服务器超时
当使用defer
进行流式传输时,您可以通过entry.server.tsx
文件中的<RemixServer abortDelay>
属性(默认为 5 秒)告诉 Remix 在超时之前等待延迟数据解析的时间。如果您目前没有entry.server.tsx
文件,您可以通过npx remix reveal entry.server
公开它。您还可以使用此值通过setTimeout
中止 ReactrenderToPipeableStream
方法。
使用内容安全策略进行流式传输
流式传输的工作原理是,在延迟承诺解析时将脚本标记插入 DOM。如果您的页面包含 脚本的内容安全策略,则您需要通过在 Content-Security-Policy
标头中包含 script-src 'self' 'unsafe-inline'
来削弱您的安全策略,或者向所有脚本标记添加 nonce。
如果你使用 nonce,则需要将其包含在三个地方:
Content-Security-Policy
标头,如下所示:Content-Security-Policy: script-src 'nonce-secretnoncevalue'
<Scripts />
、<ScrollRestoration />
和 <LiveReload />
组件,如下所示:<Scripts nonce="secretnoncevalue" />
- 在
entry.server.ts
中调用 renderToPipeableStream
,如下所示:
这将确保 nonce 值包含在任何延迟脚本标签中。