发布于 2026-01-06 2 阅读
0

NIL 模式 #perfmatters DEV 的全球展示挑战赛,由 Mux 呈现:展示你的项目!

NIL 模式 #perfmatters

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

封面图片来源:Marc-Olivier Jodoin,来自unsplash.com

在通过互联网向用户提供内容时,性能是需要重点关注的因素之一。即使我们的内容很棒,如果网站/应用性能不佳,我们仍然可能面临用户流失。我们需要快速启动并保持高速运行,才能吸引并留住用户。

有很多很棒的巧妙方法可以提高我们网站的性能,包括减少初始加载、合理缓存资源、预取关键资源、将繁重的计算任务卸载到工作进程等等。

本文将介绍另一种类似的技术,其灵感来源于 Pinterest 工程博客上Zack Argyle撰写的关于他们一年 PWA 成功案例的文章。整篇文章对他们的历程进行了非常清晰的叙述。强烈推荐阅读,了解更多有趣的加载模式。

这篇文章的观点是:

如果您浏览 Pin 图列表,我们会提供每个 Pin 图的信息。点击其中一个 Pin 图,即可查看详细信息。由于 Pin 图数据已标准化,因此在从服务器获取完整信息之前,我们可以轻松地在列表视图中显示部分详细信息。

在我们的应用程序中,可能会出现这样的情况:用户需要从列表中选择一项,点击后,我们需要加载该项的全部详细信息。这时,NIL 模式(稍后详述😜)就派上用场了。它会将列表视图中的所有数据都加载到详情视图中,当用户点击特定项时,只获取剩余的详细信息,并在用户浏览列表视图中的数据时才显示出来。

将上述模式命名为近乎瞬时加载(NIL)模式 😉!

通过实现这一点,我们甚至可以完全消除每次用户点击项目时弹出的加载指示器。凭借这种微小的性能提升,用户可能会感觉页面渲染速度几乎是瞬间完成的💪

以下是在 Ember.js 应用中实现 NIL 模式的示例,可以推广到任何框架中。

我们的示例应用程序是一个博客网站,其中包含博客文章列表。在常规实现中,该网站大致如下所示👇

通常的装载模式

每次点击文章后都会出现加载提示,需要等待服务器加载数据。加载时间受多种因素影响。要实现 NIL 模式,首先需要消除中间的加载状态(点击文章后的加载页面),然后将数据从列表页面传递到详情页面。这个加载状态是由于模型钩子发起的网络请求,用于获取完整的文章详情。如果我们抑制模型钩子,就不会出现加载页面。太好了!但是,该如何实现呢?

在切换到详情视图时,如果我们传递模型数据,则详情页面中存在的模型钩子不会被调用,而是会使用从列表页面发送的数据作为模型。

// routes/posts.js - Before

this.transitionTo('post.details', post.id);
Enter fullscreen mode Exit fullscreen mode
// routes/posts.js - After

this.transitionTo('post.details', post);
Enter fullscreen mode Exit fullscreen mode

这里post展示的是列表页面的部分数据。需要注意的是,为了避免数据出错,这些数据需要进行标准化处理,使其与详情页面中维护的模型保持一致。

例如,如果您将详情页面中的帖子数据结构化为一个带有键的对象details,那么您必须正确地对其进行规范化。

// routes/posts.js

let postDetails = {
    details: post // from the list page
}
this.transitionTo('post.details', postDetails);
Enter fullscreen mode Exit fullscreen mode

如果你已经做到这一步了,那你真是太棒了!现在你的详情页面应该可以立即加载,无需任何加载子状态。太棒了🙌

但您也会注意到,我们的页面目前还不完善。别担心!我们会解决这个问题。正如之前提到的,我们需要在用户浏览现有数据的同时,获取剩余的数据。为此,我们可以在钩子函数中触发数据获取操作setupController,提取剩余数据。

// routes/posts/list.js

setupController(controller, model) {
    this._super(...arguments);
    let postId = model.details.id; // model is the passed data from the list
    controller.get('fetchPostMeta').perform({ postId });
    controller.get('fetchComment').perform({ postId });
}
Enter fullscreen mode Exit fullscreen mode

在上面的代码片段中,我使用ember-concurrency任务来获取该帖子的剩余详情和评论。在任务完成且数据加载到 UI 之前,我们可以在适当的位置使用加载图标。同样,我们需要正确地规范化延迟加载的数据。为了进一步提升性能,一个额外的技巧是尽可能使用骨架加载器。Lauren 还写了一篇关于 Ember.js 中骨架加载器的精彩文章可以查看详细的实现细节😃

实现NIL 模式后,我们的示例应用程序将如下所示:

NIL 模式实现

你可以看到,博客作者和评论都采用了延迟加载的方式。这比之前的版本好得多,之前的版本用户需要等待一段时间才能在屏幕上看到一些内容。

希望这能帮您节省用户一些时间🙂这可是件好事,对吧!😉完整的示例在这里。

文章来源:https://dev.to/gokatz/nil-pattern-perfmatters-3jjh