Chris Ferdinandi 的 Smashing Podcast 第 21 集:现代最佳实践对 Web 不利吗?
已发表: 2022-03-10今天,我们要问的是现代最佳实践是否对网络不利? 现代框架是否将我们带入了错误的道路? 我与精益网络专家 Chris Ferdinandi 进行了交谈以找出答案。
显示注释
- Chris 的页面,其中包含播客的链接和注释
- 精益网络书
- 克里斯·费迪南迪在网络上
- 克里斯在推特上
- 香草 JavaScript 播客
每周更新
- “将设计线框转换为可访问的 HTML/CSS”
哈里斯·施耐德曼 - “使用 Electron 和 Vue 构建桌面应用程序”
蒂米·奥莫耶尼 - “提高易读性的现代 CSS 技术”
爱德华多·卡瓦扎 - “如何在 React 中使用样式化组件”
作者:阿德比伊 Adedotun Lukman - “如何使用草图创建保时捷 911”
尼古拉·拉扎雷维奇
成绩单
Drew McLellan:他是 Vanilla JS 袖珍指南系列的作者,Vanilla JS 学院培训计划的创建者,以及 Vanilla JS 播客的主持人。 他开发了一份 Tips 时事通讯,每个工作日都有近 10,000 名开发人员阅读。 他曾在 Chobani 和 The Boston Globe 等组织教授开发人员。 他的 JavaScript 插件已被 Apple 和哈佛商学院等组织使用。 最重要的是,他喜欢帮助人们学习 Vanilla JavaScript。 所以我们知道他宁愿选择 Vanilla JavaScript 而不是框架,但你知道他曾经在警察阵容中被选为最不可能犯罪的人吗? 我的 Smashing 朋友,请欢迎 Chris Ferdinandi。 你好,克里斯。 你好吗?
克里斯·费迪南迪:哦,我太棒了。 感谢您的款待。
德鲁:我今天想和你谈谈精益网络的概念,这对你来说是一种热情,不是吗?
克里斯:是的,非常如此。
德鲁:你为什么不为我们设置场景? 当我们谈论精益网络时,我们试图解决的问题是什么?
克里斯:是的,很好的问题。 就像对所有听众的警告一样,这一集可能会让一个小老头对云大喊大叫。 我会尽量避免这种情况。 当我看到我们今天为网络构建的方式时,感觉有点像一个臃肿的过度设计的混乱。 我开始相信,我们今天认为的许多最佳实践实际上可能会让网络变得更糟。
Chris:精益 Web 是一种专注于简单性、性能和开发人员体验的 Web 开发方法……对不起,不是开发人员体验。 用户体验,而不是开发人员体验,以及从团队的角度构建事物的便利性,这是我认为我们今天非常关注的地方,并且我们可能会在我们的对话中进行讨论。
Chris:实际上,我发现很多我们认为可以改善开发人员体验的事情对一小部分开发人员来说都是如此,但不一定是所有在你正在构建的东西上工作的人。 所以这也有很多问题,我们可以深入研究。 但实际上,精益网络关注的是用户的简单性和性能,并真正优先考虑或关注使用我们制造的东西的人,而不是我们,制造它的人。
Drew:随着网络作为开发平台的成熟,似乎有越来越多的专业化驱动力。
克里斯:是的。
Drew:以前是覆盖Full Stack的人,后来我们分成前端和后端。 然后前端分裂成从事 CSS 或 JavaScript 开发的人。 然后越来越多地在 JavaScript 中,它变得更加专业化。 有人可能会认为自己并将自己推销为 React 开发人员或 Angular 开发人员,他们的整个身份和前景都基于他们精通的特定框架。这种对框架的依赖是我们在 Web 上工作的核心吗?坏事?
克里斯:这是微妙的。 我曾经非常强烈地支持“是的,永远”阵营。 我认为从广义上讲,我仍然认为是的,我们作为一个对框架和工具的行业的痴迷确实可能有点损害我们的利益。 我不认为框架本质上是坏的。 我认为它们对于非常狭窄的用例子集很有用。 我们最终将它们用于几乎所有事情,包括许多情况,它们实际上不一定是您或项目的最佳选择。
克里斯:当我想到我们今天在网络上遇到的许多问题时,这些问题的核心实际上始于我们对框架的过度依赖。 之后发生的所有其他事情在很多方面都是如此,因为我们在网络上抛出的不仅仅是一般的 JavaScript 框架。 我这么说是作为一个专业地教人们如何编写和使用 JavaScript 的人。 这就是我赚钱的方式。 我在这里是说我认为我们使用了太多的 JavaScript,这有时有点奇怪。
Drew:在大型框架出现之前,我们曾经使用 jQuery 或其他东西来构建用户界面和东西。 然后框架出现了,它们给了我们更多关于基于状态的 UI 的概念。
克里斯:是的。
德鲁:现在,这是一个相当复杂的工程,你需要到位。 使用较少的 JavaScript 会排除使用类似的东西,还是您必须自己重新实现它? 你只是在创建一个加载的样板吗?
克里斯:很大程度上取决于你在做什么。 如果你有一个不变的界面,你可以构建一个基于状态的 UI……我不知道,可能有十几行代码。 如果你有一个不变的界面,老实说我可能会说基于状态的 UI。 这不一定是正确的方法。 您可能还可以做其他事情。 想想静态站点生成器、一些预渲染的标记,甚至是老式的 WordPress 或 PHP 驱动的站点。
克里斯:但是当你进入更加动态和交互式的界面时,这开始变得有趣。 不仅仅是应用程序。 我知道人们喜欢在网站和应用程序之间划清界限,我认为两者之间存在这种奇怪的混合,而且界限并不总是那么清晰。 当您开始深入了解用户所做的事情时,就会发生一些变化。 基于状态的 UI 变得更加重要。 但是你仍然不需要大量的代码来实现这一点。
Chris:我看 React 或 Vue 之类的东西,它们绝对是令人惊叹的工程。 我不想剥夺从事这些工作的人。 我最终作为一个学习练习,构建了我自己的迷你框架,只是为了更好地了解这些东西是如何在幕后工作的。 很难解释所有不同的移动部分。 所以我非常尊重那些构建和使用这些工具的人。 但是 React 和 Vue 在压缩和 gzip 压缩后都是大约 30 KB。 所以一旦你打开它们,它们就会比这大得多。
克里斯:不是全部,但其中很大一部分是用于称为虚拟 DOM 的东西。 有使用类似 API 或方法的替代方案。 对于 React,你有 Preact,它是 2.5 KB 或大约 3 KB,而不是 30。它是大小的十分之一。 对于 Vue,你有 Alpine JS,大约 7 KB。 尽管如此,还是要小得多。 这些和他们的老大哥同行之间的最大区别在于他们摆脱了虚拟 DOM。 他们可能会放弃一两个方法。 但总的来说,在处理代码的方式上,它是相同的方法和相同类型的 API,而且它们要小得多。
克里斯:我认为我们使用的很多工具对于我们正在尝试做的事情来说可能过于强大了。 如果您需要基于状态的 UI,并且需要响应式数据和这些动态界面,那就太好了。 我认为我今天尝试谈论的一件大事不是……永远不要使用工具。 对我来说,Vanilla JS 并不是你在手写每一行代码和你所做的每一个项目。 那是疯狂。 我不能那样做,我不那样做。 但它对我们使用的工具更具选择性。 我们总是选择多功能工具,即拥有所有这些东西的瑞士军刀。 有时,你真正需要的只是一把剪刀。 你不需要所有其他的东西,但无论如何我们都有。
克里斯:这真的是一个很长的路要走……我很抱歉,回答你的问题。 有时它比您自己编写或想要编写的代码多,但它并不像我认为我们认为它需要的那么多代码。 当我说你不需要框架时,我对这个想法有很多反对意见,“好吧,如果你不使用框架,你基本上是在编写自己的。” 随之而来的是它自己的问题。 我认为在使用 React 或 Vue 和编写自己的框架之间有一个地方,它可能会选择一些更小的东西。 有时,编写自己的框架实际上可能是正确的选择,这取决于您要尝试做什么。 这一切都非常流畅和主观。
Drew:非常有趣的是,作为一个学习练习,您实现了自己的基于状态的框架。 我记得在过去,我曾经认为每次我伸手去拿图书馆或其他东西时,我都喜欢认为我可以自己实现它。
克里斯:当然,当然。
德鲁:但是去图书馆为我省去了这样做的麻烦。 我知道如果我必须自己编写这段代码,我知道我会采取什么方法来完成它。 一直到使用 jQuery 之类的东西都是如此。 这些天来,我想如果我必须编写自己的 Vue 或 React 版本,我几乎不知道现在在那个库中发生了什么,在所有代码中。
Drew:对于我们这些不熟悉的人来说,当你说 Preact 放弃了虚拟 DOM 并使一切变得更小时,虚拟 DOM 给了我们什么?
克里斯:要回答这个问题,我想稍微退后一步。 框架和其他基于状态的库为您提供的最好的东西之一就是 DOM diff。 如果你并没有真正更新 UI,你可以说:“这是标记应该是什么样子的字符串。 在 HTML 中,我将把所有这些标记放在这个元素中。” 当你需要改变某事时,你会再做一次。 这对浏览器来说有点贵,因为它会触发重绘。
克里斯:但我认为可能比这更重要的是,这样做的一个问题是你有任何类型的交互式元素,一个表单域,一个有人关注的链接。 因为元素失去了焦点……即使你有一个看起来相似的新事物,它也不是同一个字面元素。 因此,如果失去焦点,可能会给使用屏幕阅读器的人造成混乱。 这只是一大堆问题。
Chris:任何值得重视的基于状态的 UI 都将实现一些 DOM diffing,他们说,“这就是 UI 应该是什么样子。 这是它现在在 DOM 中的样子。 有什么不同?” 它会去改变那些事情。 它实际上是在做你自己手动更新 UI 会做的事情,但它是在幕后为你做的。 所以你可以说,“这就是我想要的样子。” 然后库或框架会计算出来。
Chris:像 Preact 或 Alpine 这样的小东西,他们实际上是直接这样做的。 他们正在将您提供给他们的关于 UI 外观的字符串转换为 HTML 元素。 然后他们将每个元素与文字 DOM 中的相应部分进行比较。 当你最终得到越来越大的 UI 时,这可能会对性能产生影响,因为一遍又一遍地查询 DOM 变得昂贵。 如果您想了解成为问题的界面类型,请右键单击并检查 Twitter 上的“收藏”按钮或 Facebook 上的“喜欢”按钮上的元素。 并查看让您进入该元素的 div 嵌套。 它非常非常深。 它就像十几个 div,一个嵌套在另一个里面,只是为了那条推文。
克里斯:当你开始向下很多层时,它开始真正影响性能。 虚拟 DOM 所做的不是每次都检查真实的 DOM,它会创建一个基于对象的映射,以反映 JavaScript 中 UI 的样子。 然后对要替换现有 UI 的 UI 执行相同的操作,并将这两者进行比较。 理论上,这比在真实 DOM 中的性能要高得多。 一旦它获得了需要更改的内容的列表,它就会运行并进行这些更改。 但它只需要攻击 DOM 一次。 它不是每次都检查每一个元素。 如果您有 Twitter、Facebook 或 QuickBooks 之类的界面,那么虚拟 DOM 可能会很有意义。
Chris:它面临的挑战是...... Preact 和 React 之间的差异是 27 KB,然后你将整个东西解压缩到它的实际代码波中。 仅此一项的原始下载、解包和编译时间就会给 UI 上的初始加载增加相当多的延迟。 如果您的用户使用的不是 Apple 的最新设备,这一点会更加明显。 即使是几年前的 Android 设备或功能手机,或者如果你有发展中国家的人,这真的是……开始的时间要慢一些。 然后最重要的是,由于额外的抽象,实际的交互时间更慢。
克里斯:所以不仅仅是你加载它,它们在速度上也相当。 某人进行的每个微交互以及需要发生的更改也可能会稍微慢一些,因为那里有所有额外的代码。 如果您有一个非常非常复杂的 UI,其中包含大量嵌套元素和大量数据,那么虚拟 DOM 的性能增益将超过额外的代码量。 但是,对于我看到的大多数开发人员使用 React 或 Vue 的典型应用程序的任何典型 UI,你从虚拟 DOM 中获得的好处都不存在,他们会做得更好。 即使您想保持与 React 相同的便利性,也请使用 Preact。 它只是尺寸的一小部分,它的工作方式完全相同,而且性能更高。 这是我倾向于争论的事情。
克里斯:我们需要更好地为工作选择正确的工具。 如果你采用这样的方法,如果你达到了虚拟 DOM 真正有意义的地步,那么将 Preact 移植到 React 比使用自己的方法要容易得多。 情况就是这样。 如果您真的对此感到担心,那么您也可以内置一些面向未来的功能。
Drew:有些人可能会说,他们可能会认为这些框架,比如 Vue、React 都针对性能进行了高度优化,以至于你在那里获得了很多好处,当然只需将其与捆绑器中的包管理器配对以确保你仅发送您想要的代码。 当然,您这样做就已经遥遥领先了?
克里斯:是的。 我不同意。 除了……我想也许,但不是真的。 即使使用捆绑器,您仍然需要那个 React 核心。 即使有捆绑,这仍然比使用 Preact 之类的东西要大。
克里斯:德鲁,我真的很感谢你提出这个问题。 因为我在我的书《精益网络》和我的同名演讲中谈到的另一件事是这些工具如何……例如,您提到了捆绑。 为了解决使用所有这些 JavaScript 所带来的性能损失,我们所做的其中一件事是我们在前端抛出了更多的 JavaScript 来解决这个问题。 我们这样做的方法之一是包管理器和模块捆绑器。
Chris:正如你所提到的……对于那些不知道的人来说,这些工具将……它们会将你所有的单独 JavaScript 位编译成一个大文件。 新的和更多的……我不想称他们为深思熟虑的。 但是较新的将使用一种称为摇树的功能,他们可以摆脱任何实际上不需要的代码。 如果该代码有一些未用于您实际完成的事情的依赖项,他们将删除其中的一些内容以使您的包尽可能小。 这实际上不是一个糟糕的想法,但它导致了我通常称之为依赖健康的东西,在这种情况下,你可以在依赖关系之上拥有这个非常精致的依赖关系卡片之家。
克里斯:设置您的流程需要时间。 任何曾经运行过 NPM 安装然后发现一堆依赖项已经过时并且不得不花费一个小时试图找出哪些需要修复的人,哦,它实际上是依赖项中的一个依赖项,而你不需要没有能力自己去修。 这是一整件事。 也许它对你有用,但我宁愿花时间不要试图把我的依赖关系放在一起。
克里斯:我已经开始收集人们抱怨在工作流程上浪费时间的推文。 几年前,我最喜欢的一位 Brad Frost 谈到了一个令人沮丧的认识,即你在现代 JS 中苦苦挣扎的事情可能在 jQuery 中花费了你 10 分钟。 我不是一个真正的 jQuery 粉丝,但是当涉及到使用框架时,我感到很痛苦。
克里斯:很多这些工具的另一个问题是它们开始成为看门人。 德鲁,我不知道你是否真的想深入研究这个。 但我对 JS 的最大反对之一是工作流程中的所有事情。 尤其是当你开始说,“好吧,如果我们已经将 JS 用于 HTML,为什么不将它也用于 CSS?” 你开始将很多真正有才华的人排除在开发过程之外。 对于整个社区来说,这对项目来说是一个非常大的损失。
Drew:嗯,我当然是……我在 2020 年初开始学习 React,并将其添加到我的技能中。 我已经做了将近七个月了。 我不得不说我最不自信的一部分是围绕启动项目设置工具。
Drew:似乎有很多工作要为 Hello World 提供一些东西,而且您还需要了解更多内容才能将其投入生产。 如果将其作为您在 2020 年学习成为 Web 开发人员应该做的事情提出来,那么这必须使开发更难开始。 刚接触它的人会遇到真正的问题。 这将是一个真正的进入障碍,不是吗?
克里斯:当然。 这里的另一部分是 JavaScript 开发人员并不总是唯一在代码库上工作或以有意义的方式为该代码库做出贡献的人。 我们越是让了解 JavaScript 成为使用代码库的必要条件,这些人就越不可能真正参与到项目中。
克里斯:我喜欢谈论的一个例子是 WordPress,它最近……我现在不应该说最近。 现在已经一两年了。 但是他们已经越来越多地将后端堆栈转移到 JavaScript,远离 PHP,这本质上并不是一件坏事。 他们的新编辑器 Gutenburg 是基于 React 构建的。
克里斯: 2018 年,WordPress 的首席可访问性顾问 Rian Rietveld,我几乎可以肯定他的名字被我屠杀了……她非常公开地辞去了她的职位,并在一篇非常详细的文章中记录了原因。 问题的核心是她和她的团队的任务是审核这个编辑器,以确保它可以被访问。 WordPress 现在占网络的 30%。 他们的目标是使出版民主化,因此可访问性是其中非常重要的一部分。 它应该是任何 Web 项目的重要组成部分。 但对于他们来说,这尤其重要。 她团队的全部工作是确保……她团队的全部工作是确保该编辑器可以访问。 但是因为她和她团队中的任何人都没有 React 经验,而且他们在无障碍社区中找不到有这种经验的志愿者,这让她和她的团队很难完成他们的工作。
克里斯:从历史上看,他们可以识别错误,然后进行修复。 但是使用基于 React 的新工作流程,他们只需要识别错误然后提交工单。 它们与 JavaScript 开发人员正在处理的所有其他功能开发请求一起被添加到积压工作中。 很多本可以很容易修复的东西并没有进入第一个版本。
Chris: 2019 年 5 月,也就是 Rian 辞职大约一年后,对 Gutenburg 进行了详细的可访问性审核。 完整的报告有 329 页。 仅执行摘要就有 34 页。 它非常详细地记录了 91 个与可访问性相关的错误。 其中许多真的是……我不想称它们为简单的唾手可得的果实,但其中很多都是 Rian 的团队可以修复的基本问题,它可以让开发人员腾出精力专注于功能开发。 这就是他们最终似乎在做的事情,花了很多时间在功能开发上,并将这些东西推迟到以后。 但是那个团队对这个项目非常重要,他们突然因为技术选择而被排除在这个过程之外。
Chris: Alex Russell 是 Chrome 团队的开发人员。 几年前,他写了一篇名为 The Developer Bait and Switch 的文章,其中他谈到了框架的稻草人论点。 这些工具可以让您更快地移动,因此,您可以更快地迭代并提供更好的体验。 正是这个想法,更好的开发者体验意味着更好的用户体验。 我认为这是一个非常清楚的例子,说明该论点并不总是以人们认为的方式发挥作用。 对于某些人来说,这可能是一种更好的体验,而不是对所有人。
Chris: CSS 开发人员,从事设计系统工作的人,他们创建其他人可以使用的工具的能力有时也会受到这些工具选择的限制。 根据我的经验,我曾经更擅长 CSS。 在过去的几年里,情况发生了很大变化,我远不如从前那么好。 以我的经验,真正高级的 CSS 开发人员……我的意思是真正意义上的。 从事 CSS 工作的人是从事编程语言的合适的 Web 开发人员。 这是一个非常特别的,或者可以是一个非常专业的东西。 根据我的经验,特别擅长 JavaScript 的人并不总是非常擅长 JavaScript,因为你最终会真正深入地研究一件事,并且在其他一些东西上滑了一点点。 他们使用这些技术的能力也受到了阻碍,这太糟糕了,因为过去并非如此。
Chris:当堆栈更简单时,来自多个学科的人更容易参与开发过程。 我认为这对我们构建的东西和整个社区都是有害的,而情况不再如此。
Drew:我最近在一个项目中发现,该项目正在研究处理一些 CSS 问题、工作流问题的方法,我们在该项目上进行了多次工作,并且捆绑包的大小不断增加,而旧的 CSS 永远不会被删除。 这是一个 React 项目,所以我们在 JavaScript 中研究了其中的一些 CSS 方法,以了解最适合我们用来解决我们遇到的问题的方法。 很快就显而易见的是,不仅有一种解决方案可以做到这一点。 有几十种不同的方法可以做到这一点。
Drew: JS 中的 CSS 是一种通用方法,但您可能会从一个项目转到下一个项目,它会以完全不同的方式受到影响。 即使您是一名 CSS 人员并且您在项目中学习了一种特定的方法,这些技能也可能无法转移。 如果某人对 JavaScript 不是特别熟悉,那么很难看出他们应该如何投入太多时间来学习这一点。
克里斯:是的。 另一件有趣的事情,我认为你刚刚说出来的一点是,当我谈到这个时,我得到的最大的回击之一是框架强制执行约定。 你将使用 Vanilla JavaScript,你有这片绿色的田野——蓝天,你可以做任何你想做的项目。 有了 React,就有了一种 React 做事的方式。
Chris:但我发现的一件事是有 Reacty 方法,但没有一种严格的正确方法来使用 React 做事。 这是人们喜欢它的原因之一。 它更灵活一点,如果你愿意,你可以用几种不同的方式做事。 与 Vue 相同。 您可以使用基于 HTML 的东西,在 HTML 中正确设置属性,然后 Vue 替换它们,但如果您愿意,也可以使用更类似于 JSX 的模板语法。
Chris:我听过很多人在学习 React 时抱怨,其中一个大问题是你在谷歌上如何在 React 中做 X,你会得到十几篇文章告诉你可以用十几种不同的方式来做这件事。 这并不是说他们不对项目设置一些护栏。 我不认为它像“我选择了一个框架”那么明确。 现在这就是我用它构建的方式。” 老实说,我也不知道那一定是我想要的。 我不认为你会想要那些被严格限制的……也许有些人会想要。 但如果你吹捧这是一种好处,我认为它并不像人们有时所说的那样明显。
克里斯:你刚刚遇到了一件有趣的事情,你提到了不再需要的 CSS。 我认为这是合法有趣的事情之一,比如 CSS 和 JS……或者以某种方式将你的 CSS 与 JavaScript 组件联系起来,如果该组件退出,CSS 在理论上也会随之消失。 对我来说,其中很多感觉就像把工程扔给人们的问题。 总是,你仍然依赖于沿线某个地方的人。 这并不是说永远不要使用这些方法,但它们肯定不是解决这个问题的唯一方法。
Chris:您可以使用一些工具来审核您的 HTML,并提取即使不使用 CSS 和 JavaScript 也不会使用的样式。 你可以用“老式的方式”编写 CSS,并且仍然对未使用的样式进行 linting。 有一些 CSS 创作方法可以为您提供类似 JS 的输出中的 CSS,并保持您的样式表很小,而不会吐出您有时使用 CSS 和 JS 获得的这些胡言乱语的人类不可读的类名。 像 X2354ABC,或者只是这些被吐出来的废话。
克里斯:这就是我开始真正了解老人对云大喊大叫之类的事情的地方。 我真的在这里展示了我的开发人员年龄。 但是,是的,这些东西不一定是坏事,它们是为解决合法问题而设计的。 有时我觉得有点……如果它对 Facebook 来说足够好,那么对于我们这种发生在这些事情上的事情来说就足够好了。 好吧,Facebook 使用了这个工具。 如果我们是一个真正的工程项目……团队、部门、组织,我们也应该这样做。 我不一定认为这是正确的思考方式。 这是因为 Facebook 会处理您不处理的问题,反之亦然。 他们所从事的工作的规模和规模是不同的,这没关系。
德鲁:没错。 我看到其中一些像 CSS 和 JavaScript 几乎就像一个 polyfill。 我们有合法的问题,我们需要一种方法来解决它。 该技术还没有为我们提供解决它的方法。 也许当我们等待网络平台发展并解决这个问题时,我们现在用 JavaScript 做的这件事会让我们度过难关,我们会没事的。 我们知道这很糟糕。 我们知道这不是一个很好的解决方案,但它现在对我们有帮助。 并希望在此期间我们可以将其拉出来并使用本机解决方案。
克里斯:你提起这个真的很有趣。 因为从字面上看,昨晚,我正在观看 Jeremy Keith 去年关于渐进式网络应用程序的演讲。 但他说的是几十年前,他试图说服人们使用 JavaScript。 这在当时看起来很荒谬,但 JavaScript 是一个新事物。 他向人们展示了如何做一些很酷的事情,比如用这个新的改变悬停时链接的颜色……现在你需要 JavaScript 似乎很荒谬,因为这就是 CSS 为你做的。 但是当时并不存在诸如焦点属性或属性之类的东西。
克里斯:他在演讲中所说的其中一件我认为真正引起我共鸣的事情是 JavaScript 在很多方面都铺平了那些牛路。 这是一种非常灵活和开放的语言,我们可以使用它来创建或插入尚不存在的功能。 最终,浏览器会赶上并以更原生的方式实现这些功能。 但这需要时间。 我完全理解你在说什么。 这不是完美的解决方案,但它是我们现在所拥有的。
Chris:我认为对我来说,polyfills 和其中一些解决方案之间的最大区别是 polyfills 被设计为被淘汰。 如果我想要实现浏览器尚不支持的功能,但有某种规范,我编写了一个 polyfill……一旦浏览器赶上,我可以撕掉那个 polyfill 而我不必改变任何东西。 但是当你走上使用这些工具的道路时,把它们撕掉就意味着重写你的整个代码库。 这真的很昂贵而且有问题。 这并不是说永远不要使用它们,但我非常强烈地认为我们应该考虑选择以后可以轻松取出的工具。 如果我们不再需要它们或平台迎头赶上,它不需要大量的重写来将它们拉出来。
克里斯:因此,我们有一大堆不再使用的样式,这就是为什么我个人倾向于一种构建工具技术,它可以根据渲染的标记审核你的 CSS 并提取你不需要的东西。 因为如果一个平台赶上来,你可以把那部分构建工具拉出来,而不必改变一切。 它只是增加了你已经拥有的东西,而 CSS 和 JS 并没有给你同样的好处。 我只是选择那个,但我更广泛地考虑了很多这些技术。
Chris:我确实觉得 React 或 Vue 之类的东西可能正在铺平一些浏览器最终会赶上的牛路,并且可能会使用类似的方法(如果不一样的话),因此可能涉及的重写更少。 许多被插入的生态系统东西可能不那么重要。
Drew:我认为网络平台缓慢而谨慎地移动是正确的,不是吗。 您认为如果五年前,我们都将 JavaScript 轮播放在我们的页面上。 他们无处不在。 每个人都在实现 JavaScript Carousels。 如果 Web 平台已经跳出并实施了 Carousel 解决方案来满足这种需求,那么它就不会坐在那里而没有人使用它,因为人们不再使用 Carousels 来做这件事了。 因为它只是一种时尚,一种设计趋势。 为了抵消这一点并阻止平台本身变得臃肿并成为需要解决的问题,它确实必须以更稳定的速度移动。 其结果是我在 1999 年编写的 HTML 由于这个缓慢的过程而在今天仍然有效。
Drew: One of the other areas where things seem to be bloating out on the web is… I guess it's related to the framework conversation. But it's the concept of a single-page app. I feel like that a lot of promises are made around single-page apps as to their performance, like you're getting all this benefit because you're not reloading the entire page framework. I feel like they don't always make good on those performance promises. 你同意吗?
Chris: Yes. Although I will confess, despite having a very lengthy chapter in my book on this and talking about that a lot in talks and conversations with people, I don't think single-page apps are always a terrible thing. But I do think this idea that you need one for performance is overstated. You can oftentimes get that same level of performance with different approaches.
Chris: I think one of the bigger challenges with single-page apps is… For anybody who's unfamiliar with those. When a single-page app, instead of having separate HTML files or if you're using something like a database driven site like WordPress, even though you don't have actual physical HTML files for each page in your WordPress site, WordPress is creating HTML files on the fly and sending them back to browsers when URLs are requested. For purposes of this conversation, instead of having separate HTML files for every view in your app, a single-page app has a single HTML file. That's what makes it a single-page app. JavaScript handles everything. Rendering the content, routing to different URL paths, fetching new content if it needs to from an API or something like that.

Chris: One of the spoken benefits of these or stated benefits of these is that only the content on the page changes. You don't have to re-download all the JS and the CSS. Oh, and you can do those fancy page transitions that designers sometimes love. In theory, this is more performant than having to reload the whole page.
Chris: The problem with this approach from my perspective is that it also breaks a bunch of stuff that the browser just gives you for free out-of-the-box, and then you need to recreate it with more JS. You have an app that's slow because it has a lot of JS. So you throw even more JavaScript at it to improve that performance and in doing so, you break a bunch of browser features and then have to re-implement those with even more JS too.
Chris: For example, some things that the browser will do for free with a traditional website that you need to recreate with JavaScript when you go the single-page app. You need to intercept clicks on links and suppress them from actually firing, with your JavaScript. You then need to figure out what you actually need to show based on that URL, which is normally something that would get handled on the server or based on the file that goes with that URL path. You need to actually update the URL in the address bar without triggering a page reload. You need to listen for forward and back clicks on the browser and update content again, just like you would with clicks on links. You need to update the document title.
Chris: You also need to shift focus in a way that announces the change in page to people who are using screen readers and other devices so that they're not confused about where they are or what's going on. Because they can't see the change that's happening, they're hearing it announced. If you don't actually shift focus anywhere, that announcement doesn't happen. These are all things that the browser would do for you that get broken with single-page apps.
Chris: On top of that, because you have all this extra JavaScript, this is complicated. So most people use frameworks and libraries to handle this sort of thing. Because of all this extra JavaScript to support this approach, you end up with potentially slower initial page load than you would have otherwise. Depending on the content you have, this approach I think sometimes can make sense. If you have an app that is driven by API data where you don't necessarily know what those URL paths are going to look like ahead of time.
Chris: Just an example here. You have an animal rescue where you have some adoptable animals, and that data comes from Petfinder, the animal adoption website. You have a bunch of animals there. Petfinder manages that, but you want to display them on your site with the Petfinder API. When your website's being built, it doesn't always necessarily have visibility to what pets are available in this exact moment and what kind of URL paths you're going to need. A single-page app can help you there because it can dynamically on the fly, create these nice URLs that map with each dog or cat.
Chris: Something like Instagram with lots of user created content, maybe that also makes sense. But for a lot of things, we do know where those URLs are going to be ahead of time. Creating an HTML file that has the content on it already is going to be just as fast as… sometimes even faster than the JavaScript based single-page app approach, especially if you use some other techniques to keep your overall CSS and JavaScript size down. I use this approach on a course portal that I have. The page loads feel instantaneous because HTML is so easy for browsers to render compared to other parts of the stack. It feels like a single-page app, but it's not.
Drew: Especially when you consider hosting solutions like a Jamstack approach of putting HTML files out in a CDN so it's being served somewhere physically close to the user.
Chris: Yep.
Drew: Loading those pages can just be so, so quick.
Chris: Yes. 绝对地。 绝对地。 One of the other arguments I think people used to make in favor of single-page apps is offline access. If someone loads it and then their network goes down, the app is already up and all the routes are handled just with the file that's already there. So there's no reloading, they don't lose any work. That was true for a long time. Now with service workers and progressive web apps, that is I think less of a compelling argument, especially since service workers can fetch full HTML files and cache them ahead of time if needed.
Chris: You can literally have your whole app available offline before someone has even visited those pages if you want. It just happens in the background without the user having to do anything. It's again, one of those technologies that maybe made sense for certain use cases a few years ago a little less compelling now.
Drew: It reminds me slightly of when we used to build websites in Flash.
Chris: Yes.
Drew: And you'd have just a rectangle embedded in an HTML page which is your Flash Player, and you'd build your entire site in that. You had to reimplement absolutely everything. There was no back button. If you wanted a back button, you had to create a back button, and then you had to create what the concept of a page was. You were writing code upon code, upon code to reimplement just as you are saying things that the browser already does for you. Does all this JavaScript that we're putting into our pages to create this functionality… is this going to cause fragility in our front-ends?
Chris: Yes. This is almost certainly from my mind, one of the biggest issues with our over-reliance on JavaScript. JavaScript is just by its nature, is a scripting language, the most fragile part of the front-end stack.
Chris: For example, if I write an HTML element that doesn't exist, I spell article like arcitle instead of article and the browser runs across that, it's going to be like, “Oh, I don't know what this is. Whatever, I'll just treat it like a div.” And it keeps going. If I mistype a CSS property… Let's say I forget the B in bold, so I write old instead, font way old. The browser's going to be, “I don't know what this is. Whatever, we'll just keep going.” Your thing won't be bold, but it will still be there.
Chris: With JavaScript, if you mistype a variable name or you try to use a property, you try to call a variable that doesn't exist or a myriad of other things happen… your minifier messes up and pulls one line of code to the one before it without a semicolon where it needs one, the whole app crashes. Everything from that line on stop working. Sometimes even stuff that happens before that doesn't complete, depending on how your app is set up. You can very quickly end up with an app that in a different approach, one where you rely a lot more on HTML and CSS, it would work. It might not look exactly right, but it would still work… to one that doesn't work at all.
Chris: There's an argument to be made that in 2020, JavaScript is an integral and important part of the web and most people don't disable it and most people are using devices that can actually handle modern JavaScript. That's true, but that's not the only reason why JavaScript doesn't work right, even if you have a linter there for example and you catch bugs ahead of time and things. There's plenty of reasons why JavaScript can go horribly awry on you. CDNs fail.
Chris: Back in July of last, a year ago this month… at least, when we're recording this… a bad deploy took down Cloudflare. Interestingly as we're recording this, I think a week or two ago, Cloudflare had another massive outage that broke a whole bunch of things, which is not a knock on Cloudflare. They're an incredibly important service that powers a ton of the web. But CDNs do sometimes go down. They are a provider used by 10% of Fortune 1,000 companies. If your JS is served by that CDN and it breaks, the JavaScript file never loads. And if your content is dependent on that JS, your users get nothing instead of getting something just not styled the way you'd like.
Chris: Firewalls and ad blockers get overly aggressive with what they block. I used to work at a company that had a JavaScript white list because they were extremely security conscious, they worked with some government contract stuff. They had a list of allowed JavaScript, and if your site or if your URL wasn't part of that, no JavaScript. You have these sites. I remember going to a site where it had one of the hamburger kind of style menus on every view whether it was desktop or mobile, and I could not access any page other than the homepage because no JavaScript, no hamburger, that was it.
Chris: Sometimes connections just timeout for reasons. Either the file takes a while or someone's in a spotty or slow connection. Ian Feather, an engineer at BuzzFeed, shared that about 1% of requests for JavaScript on the site fail which is 13 million requests a month. Or it was last year, it's probably even more now. That's a lot of failed JavaScript. People commuting go through tunnels and lose the internet. There's just all sorts of reasons why JavaScript can fail and when it does, it's so catastrophic.
Chris: And so we built this web that should be faster than ever. It's 2020, 5G is starting to become a thing. I thought 4G was amazing. 4G is about as fast as my home wifi network. 5G is even faster, which is just bonkers. Yet somehow, we have websites that are slower and less performant than they were 5 or 10 years ago, and that makes no sense to me. 不一定要那样。
Drew: How do we get out of this mess, Chris?
Chris: Great question. I want to be really clear. I know I've hammered on this a couple times. I'm not saying all the new stuff is bad, never use it. But what I do want to encourage is a little bit more thoughtfulness about how we build for the web.
Chris: I think the overlying theme here is that old doesn't mean obsolete. It doesn't mean never embrace new stuff, but don't be so quick to just jump on all the shiny new stuff just because it's there. I know it's one of the things that keeps this industry really exciting and makes it fun to work in, there's always something new to learn. But when you pick these new things, do it because it's the right tool for the job and not just because it's the shiny new thing.
克里斯:我们没有像我希望的那样深入的另一件事,但我认为非常重要的是,该平台在过去几年中已经以非常大的方式赶上了。 尽可能多地接受这一点将为人们带来更快、更不脆弱、更容易构建和维护的 Web 体验,因为它需要更少的依赖项,例如使用浏览器提供给你的东西-盒子。 我们曾经需要 jQuery 来选择类之类的东西。 现在浏览器有本地方法来做到这一点。 人们喜欢 JSX,因为它允许您以更无缝的方式在 JavaScript 中编写 HTML。 但是我们在 Vanilla JavaScript 中也有模板文字,可以让您在没有额外依赖的情况下获得同样程度的易用性。 HTML 本身现在可以取代很多过去需要 JavaScript 的东西,这绝对是惊人的。
克里斯:我们谈了一点……这是一个 CSS 的东西,但悬停在链接上,以及过去如何需要 JavaScript。 但是使用细节和摘要元素之类的东西,您可以创建披露,例如展开和折叠或手风琴元素,无需脚本。 你可以只用一个……我不应该说只是,我讨厌这个词来自动完成输入。 但是使用一个不起眼的输入元素,然后使用一个与之关联的数据列表元素,并带有一些选项。 如果您对 vanillajstoolkit.com 上的这些东西如何工作感到好奇,我有一堆该平台为您提供的 JavaScript 东西。 但是我也有一些过去需要 JavaScript,如果你想要一些代码示例来配合它,现在也没有一些有趣的东西。
Chris:在 CSS 方面,我最流行的 Vanilla JS 插件是这个库,它可以让你动画向下滚动到锚链接。 它非常大。 这是我写过的最难的一段代码。 而现在它完全被单行 CSS 取代,滚动行为流畅。 它的性能更高。 写起来更容易。 修改其行为更容易。 这只是一个更好的整体解决方案。
克里斯:我希望我们做得更多的另一件事是依靠多页应用程序。 我觉得这里有点被证明是正确的,因为我最近看到谷歌某人的一篇文章现在实际上也在推动这种方法。 我认为这很有趣,考虑到这个巨大的角度和框架......所有的事情,繁荣,谷歌几年前开始的。 看到他们回来做这件事真是太酷了。 使用静态站点生成器和 Netlify 和 CDN 缓存之类的出色服务,您可以为使用单个 HTML 文件以获取所有不同视图的人们创建令人难以置信的快速 Web 体验。 所以有点依赖一些开箱即用的东西。
Chris:在这对你来说不现实的情况下,你确实需要更多的 JavaScript,你确实需要某种库,也许首先看看更小、更模块化的方法,而不是仅仅为行业的庞然大物而努力。 Preact 可以代替 React 吗? 而不是 Angular ......我的意思是,而不是 Vue,Alpine JS 会工作吗? 还有一个非常有趣的预编译器,现在称为 Svelt,它为您提供类似框架的体验,然后将您的所有代码编译成 Vanilla JavaScript。 所以你会得到这些非常小的捆绑包,里面只有你需要的东西,没有别的。 除了 CSS 和 JavaScript,你能不能插入一些第三方 CSS linter 来比较你的 HTML 和你的 CSS,然后把那些不小心留在里面的东西取出来? 是否可以采用不同的方式来创作 CSS,例如 Nicole Sullivan 的面向对象的 CSS? 我们并没有真正谈论这个,但人们应该看看这是一件非常酷的事情。
克里斯:然后我认为也许是第三个也是最重要的部分,尽管它不是一种具体的方法,而更多的是我希望更多人记住的一件事,那就是网络适合每个人。 我们今天使用的许多工具都适用于拥有良好互联网连接和强大设备的人。 但它们不适用于使用旧设备、互联网连接不稳定的人。 这不仅仅是发展中地区的人。 这也是英国人,在美国某些地区,我们的互联网连接绝对糟糕透顶。 我们国家中部的互联网速度非常慢。 我知道在伦敦的某些地方,由于历史原因,他们无法连接新的宽带,所以你只剩下这些非常糟糕的旧互联网连接。 全世界都有这样的地方。 上次我在意大利,同样的事情。 那里的互联网太可怕了。 我不知道从那以后它是否改变了。
克里斯:我们今天建造的东西并不总是对每个人都有效,这太糟糕了。 因为网络的愿景,我喜欢它的一点是,它是一个绝对适合所有人的平台。
Drew:如果听众想了解更多关于这种方法的信息,您已经在《精益网络》一书中详细介绍了它。 这可以在线获得。 是实体书还是数字书?
克里斯:两者兼而有之。 嗯,不。 这绝对不是实体书。 你去leanweb.dev。 您可以在线免费阅读整本书。 如果你愿意,你也可以,有 EPUB 和 PDF 版本,只需很少的钱,我现在忘记了多少钱。 我有一段时间没看它了。 如果您愿意,整个过程都是免费的。 您还可以观看有关此主题的演讲,如果您愿意,我将在其中详细介绍。
克里斯:但我还在 gomakethings.com/smashingpodcast 上为 Smashing Podcast 的听众准备了一个特别页面,因为我在命名事物方面很有创意。 除了本书之外,这还包括大量资源,围绕着我们今天讨论的内容。 它链接到我们涵盖的许多不同技术,我写的其他文章更深入地探讨了其中一些主题并稍微扩展了我的想法。 如果人们想了解更多信息,那可能是最好的起点。
德鲁:太棒了。 谢谢你。 我一直在学习精益网络。 克里斯,你最近在学习什么?
克里斯:是的,有几件事。 我早些时候在观看 Jeremy 关于渐进式网络应用程序的视频时提到了这一点。 几年来,我一直在推迟学习如何真正编写自己的渐进式 Web 应用程序,因为我对正在使用的任何东西没有特别的需求。 我最近从我在南非的一位学生那里得知,他们一直在处理轮流停电,因为那里发生了一些事情。 结果,她无法参与我们经常一起做的一些项目,因为停电了,她无法访问学习门户并继续跟进。
克里斯:对我来说,现在建立一种即使有人没有互联网也能发挥作用的体验比……我意识到也许以前是这样,所以我开始深入研究,希望把它放在一起接下来的几周。 走着瞧。 Jeremy Keith 在这方面的资源绝对是救命稻草。 我很高兴他们存在。
克里斯:我知道,德鲁,你提到你喜欢问这个问题的原因之一是为了表明人们无论多么老练,总是在学习。 只是一个相关的轶事。 我想我一直是一名网络开发人员,大约有八年了。 我仍然必须谷歌使用 CSS 属性来制作斜体,实际上每次我使用它时。 出于某种原因,我的大脑默认使用文本装饰,即使那不是正确的。 我会尝试几种不同事物的组合,每次我总是有一个词错。 我有时也写斜体而不是斜体。 是的。 如果有人曾经觉得,哦,我永远不会学习这些东西……只要知道,无论你多么老练,总会有一些非常基本的东西,你一遍又一遍地谷歌。
Drew:我已经做了 22、23 年的 Web 开发人员,但我仍然每次都必须在 Google 上搜索 Flexbox 的不同属性。 虽然我已经使用了 23 年。 但是,是的,有些事情只是……随着年龄的增长,可能会有更多的事情发生。
克里斯:是的。 老实说,我最终建立了一个完整的网站,我一遍又一遍地用谷歌搜索,只是为了更容易复制粘贴参考,因为这比谷歌搜索更容易。
德鲁:这不是一个坏主意。
克里斯:我就是那种懒惰的人。 我将建立一个完整的网站来拯救自己,就像三秒钟的谷歌搜索一样。
Drew:如果您的听众想从 Chris 那里听到更多信息,您可以在网上找到他的书:leanweb.dev,以及他的开发者 Tips 时事通讯和更多信息,请访问 gomakethings.com。 克里斯在推特上的克里斯费迪南迪。 您可以在 vanillajspodcast.com 或您通常获得播客的任何地方查看他的播客。 感谢您今天加入我们,克里斯。 你有什么离别词吗?
克里斯:不。非常感谢你邀请我,德鲁。 我有一个绝对粉碎的时间。 这很有趣。 我真的很感激有机会来聊天。