如果 LinkedIn 更美观会怎样? - 新 UI
API
界面
动画和交互
数据管理
结论
大家好,三个月前我开始了一个业余项目,目标是为我们心爱的 LinkedIn 网页版打造一个美观的用户界面。我的想法是通过构建一个流畅友好的界面来提升我的 JavaScript 技能,我个人很喜欢用这个界面浏览 LinkedIn。
由于我的目标不是设计 UI,而是使用React.js进行开发,我四处寻找,找到了Gregoire Vella提出的一个很棒的重新设计方案,与我的想法非常接近。受他作品的启发,我编写了所提出的界面代码。以下是最终效果的简短视频:
我写这篇文章的目的是简要概述一下整个开发过程,讲解一些比较有挑战性的部分,解释我在开发过程中做出的一些决定,以及在整个过程中遇到的一些困难和经验教训。希望这篇文章能对大家有所帮助。
API
发展
在进入界面之前,我的待办事项清单中的第一项任务是创建一个能够以我需要的结构提供数据的 API。我不需要使用真实的数据库从头开始创建它,因为它不需要插入/更新或删除任何数据——我只需要一个返回所有我将要用到的数据的 API。为了实现这一点,我使用了非常棒的包json-graphql-server,它出色地创建了一个带有静态数据的 GraphQL API,这些数据可以存储在服务器上一个简单的 JSON 文件中——我只是意识到包名很好地描述了它。
有问题吗?
我对这个 API 唯一不满意的地方是,json-graphql-server 无法轻松处理一个集合引用另一个集合中多个项目的场景。例如,在一个“推荐”系统中,用户可以给朋友写推荐,也可以接收其他人的推荐。在这种情况下,我们需要author和target字段,它们都引用“用户”集合。这个问题可以通过一个中间集合来解决。起初,这个集合并不是必需的,但除此之外,一切都很顺利。
好了,静态 GraphQL API 作为后端,搞定!接下来是 UI!
界面

发展
React.js在这里扮演主要角色,使用Next.js进行文件系统路由,以及 SSR、图像优化以及框架为我们提供的许多其他优势。
我想说,这个项目大约50%的时间都花在了界面代码编写上,创建所有显示组件,用CSS模块(可以使用SASS)设置样式,确保组件在移动设备上也能正常工作等等……第二周,我不得不将一些组件从基于类的组件重构为基于函数的组件。到了某个时候,我意识到React Hooks可以轻松处理所有必要的场景,将它们创建为JavaScript类实际上并没有什么实际优势。而且,基于函数的组件需要的代码更少,这对每个人来说都是一个优势。
所有组件都已创建并具备工作属性,接下来就该将应用与我们的静态 API 集成了。为此,我们将Apollo 客户端导入到项目中,用于管理应用运行的所有 GraphQL 请求。使用 Apollo 后,可以单独创建页面,从 API 请求数据,将数据传递给子组件并进行渲染。虽然我选择使用基于函数的组件作为显示组件,但为了处理一些复杂的场景,例如无限滚动功能和条件数据获取,页面仍保留为类。目前为止没有问题,只是还有很多工作要做。
动画和交互
发展
毋庸置疑,GreenSock是目前最全面的 JavaScript 动画库之一。该框架主要用来制作直接来自用户交互的动画,例如标签页、弹出窗口、下拉菜单等。
除了用户交互之外,我们还需要页面之间流畅的导航,以打造友好的用户体验,而这正是Framer Motion API在 LinkedIn 中得以应用的。它能够在离开/进入页面时,在 Next 路由器系统之间进行 CSS 动画的衔接。实现过程相当简单,没有任何问题……只是在项目构建和上线测试后出现了一个严重的问题。
有问题吗?
这里的问题是,Next 与 Motion API 产生了冲突,导致 React 组件树中某些组件出现冲突——当页面发生更改时,Next 核心卸载某些组件的 CSS 模块的速度太快,没有给 Motion API 足够的时间让页面淡出屏幕,因此 CSS 在元素离开页面之前就丢失了——该问题仅在项目捆绑到静态文件后发生,奇怪的是,这种行为在 Next 开发模式下不会发生。
事实上,截至本文撰写时,这仍然是 Next 的一个未解决的问题。目前,有一些变通方法可以解决这个问题,但它们也存在一些缺点。幸运的是,这个问题在 GitHub 社区引起了广泛关注,希望它能尽快得到修复。
学到了什么?
处理在设备屏幕上占用大量空间的动画有时会很棘手。定位正确的元素并选择合适的 CSS 属性对于获得出色的性能至关重要。乍一看,这似乎没什么大不了的,但在我使用一些旧的移动和桌面设备进行的性能测试中,它却带来了巨大的差异。
这里还有第二个话题。我不会说这是一个“问题”,更像是Framer Motion API集成的一个注意事项。由于某些路由是根据服务器数据动态生成的,因此使用 React Memo 处理它们非常重要,它可以防止组件不必要的多次渲染。否则,一旦触发路由更改(但在动画之前),当前页面就会重新渲染,从而没有足够的时间使其再次淡出屏幕。这些重新渲染会严重影响应用的最终性能,不仅会影响应用程序的客户端,还会增加对服务器的请求,从而可能导致过载问题。我想说,如果使用得当,memoization 系统是一项非常棒的优化技术,可以显著提升性能,在开发应用程序时值得特别关注。
数据管理

发展
使用单独的独立显示组件在大多数情况下都适用,但在某些情况下,这不足以实现目标。Chat组件(由一个主组件和三个子组件组成)就是一个很好的例子。这里的挑战不仅在于界面本身(以及一个良好的移动版本),还在于如何让子组件之间和谐地通信。起初,我考虑使用Redux.js来实现,但即使它可以满足需求并解决我们的问题,我还是选择使用React Context API,它旨在共享可被视为“全局”的React组件树数据,非常适合Chat组件的情况。这并非唯一需要Context API的地方,但正如前文所述,这只是一个“快速概览”,因此我们将只讨论Chat组件。
学到了什么?
React 在 16 版中首次引入了 Context API,旨在解决 props 传递问题,避免在组件树中通过多个组件传递 props。而使用 Redux 不仅需要在应用程序包中添加更多库,还需要遵循一系列配置及其样板,以便库能够管理应用程序状态。这并不意味着 Context API 会取代 Redux 及其用途——老实说,Redux 非常适合需要高频状态更新的大型应用程序——但这里的重点是理解问题,并在每种需要共享状态的情况下平衡最佳解决方案。
结论

好吧,通常我决定构建的副项目最终会花费比我最初预期更多的时间,但总的来说,在这种情况下,最终结果实际上也比我预期的要好,所以我想这是可以原谅的。
开发过程不应该模糊不清,但你无需事先了解每一件事。我在这里将开发过程划分为单独的步骤,只是为了使文章结构清晰。这些步骤通常在开发过程中相互合并,有时你需要回溯几天,继续完成你认为已经完成的事情。
从基础开始,了解下一步该怎么做,然后努力实现。问题不可避免,这也是每个项目的独特之处。赢得这些小胜利,是激励我们迈向下一个项目的动力之一。
好了,各位,如果您读到这里,非常感谢。另外,欢迎随时在 LinkedIn 上与我联系(这次是真正的 LinkedIn)。
文章来源:https://dev.to/claudiobonfati/what-if-linkedin-was-beautiful-23go