多年来,网络社区赞同单个分页申请(SPA)架构的益处。几乎任何Web会议或流行的技术博客,你一定会遇到一个关于他们的福利的讨论。它使我们为什么这是一个感觉:每次导航到网站的不同页面时,等待加载和初始化HTML,JavaScript和样式表的完整页面;按需加载小型JavaScript是快速的。SPA也允许我们避免在页面加载之间避免可怕的空白屏幕,而让我们提供更多用户友好的加载屏幕。这使得SPAs比传统架构更适合用于在某些国家/地区的移动网络,甚至是桌面网站的连接环境。如果正确优化,即使是第一页的负载也可以相当瘦;我甚至不会进入着名的财务激励,提供快速浏览体验。简短版本是:得快。
但是,许多SPA讨论不考虑哪些水疗讨论是如何迁移到单页架构的过程。
特别是当您在处理成熟的应用程序时,占有数百万用户和大量的良好理解的代码。它是可以理解的,为什么这不谈到太多的大多数声乐科技公司往往落入两类之一:要么是一个相对较新的启动,都有比例的技术债务;或者他们是一个更建立的Faang型,几乎无限的资源来解决技术债务。
在Ok188bet金宝搏官网cupid,我们自2004年以来一直存在,具有相当小的(〜30人)工程团队在整个方面发电。我们的Web CodeBase将Ruby上的Ruby预测,您可能会感到惊讶(或适当地恐怖),以了解我们的技术堆栈依赖于我们呼叫酒吧的服务器端渲染的家庭成长的PHP样框架。我们的产品是最近,Pub,Vanilla JS,JQuery,CoffeScript,React,Reftux,Redux等,大部分地依赖于服务器端水合状态,代替适当的API。此外,有一个无数的可能死的代码路径,有条件地注入了可疑用品的第三方脚本。所以,当我们谈论遗产代码和技术债务时,这就是我们带到桌子的东西。
正如你所以,我们常常难以为产品的全锻作家进行商业理由。那么你如何拍摄比某些JavaScript程序员年龄较大的Web应用程序,并将其带入现代时代?好吧,我们现在实际上已经在这一目标方面取得了重大进展。事实上,反应很容易渲染到现有的应用程度至关重要,帮助我们早在2016年中期 - 今天我们的产品很快就是几乎完全反应所能的。我也很高兴地报告,我们所有的产品页面都是API驱动的(尽管我们不完全在GraphQL动力的乌托邦,我们稍后会争取更多)。这两个都是我们多年工作的缓慢,渐进的过渡,这使得我们的最终转向水疗中心明显更容易。
但尽管所有这些都取得了巨大的进步,但我们最近仍然依赖于Pub来实际上,每次请求都能使用每次申请来生成我们的每个HTML页面。这阻止了我们做冷酷的事情,就像没有我们的程序员必须学习拟订语言(非常有用的招聘)。因此,大约6个月前我开始在一个项目上移动我们的酒吧。我们使用我们的移动网络产品开始此转换,并将这些学习带到桌面3月后。两个平台的任务列表广泛但相当简单:
- 在编译时生成HTML文件以提供我们的JavaScript捆绑包。
- 确保快速(足够)的第一漆。
- 使用代码拆分以避免以臃肿的捆绑结束。
- 确定样品板逻辑等更好的抽象,如第三方脚本。
- 更新遗留vanilla javascript工具依靠直接DOM操作进行反应。
- 消除任何未使用的代码,我找到了一路。
在这种大规模迁移的过程中,我发出了一些观察结果,并设计了一种夫妻抽象,我希望您可以在清理旧代码以及编写新代码时发现有用。
追踪死亡代码
因此,让我们从最合乎逻辑的方式开始解决这些项目符号:按字母顺序排列。消除未使用的代码是迁移我们的传统基础架构时的巨大目标。部分这是理想主义的(Yay删除代码!),部分这是务实的(参与少代码转换!)。但是,令人难以置疑的挑战是在遗留的代码对保持我们的网站工作中至关重要的挑战,以及可以安全地删除哪些代码,因为从Okcupid托管期刊和论坛的日子里没有相关(是的,我们曾经做过那样188bet金宝搏官网;不,我不能告诉你为什么我们认为这是一个好主意)。然而,在我们的工具带中有一个非常基本的工具,证明了在弄清楚的代码是运行的并且不是:分析!
甜美,甜美。
有很多代码,我偶然发现了我的工程侵权队已经有了远见,以便将分析事件添加到。当我找到这些时,我会检查他们是否在去年左右被解雇,并在什么卷中被解雇,并判断判断是否可以切除违规代码。这位诚实让我想向我曾写的每个反应组件添加分析事件。有人谈到我。
如果只有一切都像发射分析事件一样简单!
优化第一个油漆
迁移到单个页面应用程序的另一个困难方面是我们的大部分网络应用程序依赖于我们的React应用程序中始终保证的某些数据。虽然这很易于确保使用服务器端数据保健程序,但在移动到静态HTML模板时,这更具挑战性。摆脱所有这些依赖性都会非常繁琐,难以致讨,所以我们必须制定解决问题的策略。最后,我们解决了这样的东西:
// index.js - 我们的主要应用进入点导入从“反应”反应;从“反应 - DOM”的进口反应组;从“./api”导入api;导入助手来自“./helpers”;从“./app”导入应用程序;从“./app_error”导入apperror;const root = document.getElementById(“root”);//加载绝对必需品。api.loadCriticalData().then(()=> elplers.initializeglobals()).then(()=> acctdom.render(,root)).catch((错误)=> acctdom.render(,root));
这是什么,它加载了对我们的应用程序绝对关键的数据。然后,它通过初始化某些全局库使其其余的应用程序可用。最后,它将应用程序呈现给DOM。如果此过程中的任何内容都会失败,则我们反映到错误状态。
然而,这种方法有一个重要的缺点:在我们等待数据加载时呈现的是什么?我们不想向用户展示一个空白屏幕,而这发生 - 即使它只会每次会话发生一次,也显示用户一个空白屏幕永远不会理想。要打击此功能,我们将使用App Shell填充我们的模板文件:
// index.html 188bet金宝搏官网 okcupid title> head> div> div>