导读:本文深入探讨了从浏览器开发回归 Web 开发的经验,揭示了一些关于 Web 开发的观念和看法。作者提醒我们,尽管我们可能认为自己的 Web 经验已经足够丰富,但实际上,Web 开发领域远比我们想象的要广阔和复杂。通过比较浏览器工程师、标准编辑和其他 Web 开发者的观点,我们可以更全面地理解 Web 开发的全貌。对于小型 Web 商店和初创公司的 Web 开发者来说,他们面临的挑战和约束更是独特。在 Web 应用开发中,他们需要找到自己的定位,充分发挥自己的优势。总体而言,作者希望读者能够对自己的 Web 开发实践充满信心。了解并接受自己的约束可能是取得成功的关键。
自从我离开 Mozilla,全身心投入 Web 开发工作后,我发现了一些令我惊讶的事情。与我之前作为浏览器工程师的认知相比,Web 开发实际上是一个相当复杂且富有挑战性的领域。而且,Web 开发人员普遍都非常聪明,他们所采用的框架和技术并非如我们之前所轻视的那样不堪。
与此同时,我也发现了一些 Web 开发人员对浏览器和 Web 的看法,这些观点在我作为前浏览器工程师和标准编辑的角度看来,存在一些疑问。
以下是我所观察到的一些令我惊讶的事情。
Web 浏览器工程师对 Web 开发非常了解
我曾天真地认为,作为浏览器工程师,我们对 Web 的了解一定比其他任何人都要深入。毕竟,我们每天都在编写构成 Web 平台的代码。
问题在于,编写 Web 浏览器是一项艰巨的任务。
大多数浏览器工程师都专注于特定的领域,对某些领域有着非常深入的了解,而对其他领域的知识可能只是停留在表面。此外,浏览器平台的工程师们主要使用 C++ 和 Rust 编写代码,只有极少数的 JavaScript 测试用例。他们所面对的是一个庞大的代码仓库,其中大部分工作都是由其他人负责的。
因此,在日常工作中,Web 浏览器工程师并不会与 webpack 对抗,也不会去深入理解全页的 TypeScript 错误。他们也不会考虑如何让 iOS 上的 Safari 表现得更像其他浏览器,或者在大规模的 CSS 中挣扎。他们更不会去评估最新的 SSR/SSG/island 框架是否值得投入使用,也不会为了更优化的分块而重构庞大的 JS 代码库,也没有在 GitHub 上因为某个依赖的最新版本破坏了他们的应用而提出沮丧的问题,也没有试图让所有工具在 ESM 与 CJS 之间达成一致,也没有因为选择了正确的状态管理方法还是应该第十次重写整个东西而夜不能寐。
简而言之,由于他们的工作重点和职责范围,他们对于真实世界的 Web 开发所面临的挑战和问题的了解,可能远不如 Web 开发人员所期望的那样深入。
尽管如此,致力于浏览器开发者工具和浏览器前端开发的工程师们通常会更加关注这些问题,并且他们每天都在使用 JavaScript 进行开发。然而,他们仍然与常规的 Web 开发存在一定的距离。例如,他们只需要针对单个浏览器引擎的平台特性进行开发,通常只需要针对单个浏览器版本进行工作(能够使用新的和令人兴奋的功能而不用担心兼容性是非常棒的),不需要担心捆绑大小,服务器,脱机状态,或许多其他使 Web 开发变得困难的问题。
显然,一些 Web 浏览器工程师也会参与业余项目,但这些业余项目的限制与在一家初创公司的情况截然不同。在初创公司,Web 应用的成功与否直接关系到公司的生死存亡。
在我职业生涯的早期,我曾从事平面设计和 Web 开发方面的工作,甚至在加入 Firefox 开发团队之前,我曾在大阪的一家 Web 开发公司工作过一段时间,并参与了一些 Web 应用的制作。然而,当我离开 Mozilla,全心投入到 Web 开发领域时,我对它的快速发展以及我对它的理解程度感到震惊。
作为一名 Web 浏览器工程师的经验对 Web 开发非常有价值,主要是因为我了解去哪里寻找资源、向谁寻求帮助以及如何提交错误报告。然而,如果我认为成为 Web 浏览器工程师就自动使我具备了 Web 开发的能力,那我就是在自欺欺人。
在我在 Mozilla 的日子里,Firefox OS 时代无疑是我最愉快的时光。那时候,我们有一个内部团队专注于构建真实世界的移动 Web 应用。作为平台团队,我们的首要任务是调试这些应用,确保它们能够成功运行。
在这个过程中,我发现 transitionend 事件有时并不可靠,这导致 Web 应用程序出现错误,甚至过于复杂。因此,我提出并实现了 transitioncancel 事件,并引入了 Web 动画的 Animation.finished Promise。
然而,即使与 Web 开发人员紧密合作,也无法让我真正准备好再次成为全职的 Web 开发人员。在很大程度上,浏览器工程师和 Web 开发人员是处于两个截然不同的世界中,这也许并不像我们所想象的那样,都是 Web 开发人员超级英雄。
制定 Web 规范的人对 Web 开发非常了解
是的,那些致力于 Web 标准和规范制定的人,特别是浏览器工程师,通常对 Web 开发有深入的了解。早在 2012 年,Brendan Eich 就曾指出,“制定标准就像制定法律一样,绝对是制香肠的过程” ,引用了 John Godfrey Saxe 的名言:
法律就像香肠一样,我们对制定过程的了解程度与对它的尊重程度成反比。
作为一名 Web 开发人员,很容易将那些致力于 Web 标准和规范制定的人想象成拥有无限智慧的群体。他们能够根据每个提案的技术优点和对行业需求的深刻理解,做出冷静而理性的决策。
然而,这种美好的幻想通常会在你参与的第一个工作小组会议中破灭。尽管大家的出发点都是最好的,但有时决策至少在一定程度上是基于某个人的魅力或强烈的个性,这取决于当时在房间里的人是谁、大家有多疲劳,甚至可能因为某人需要完成晋升材料而急于推出某个功能。
这听起来可能有些愤世嫉俗,但请让我进一步澄清两点。
首先,这些工作小组的人员都是善良、出色的人,他们通常也意识到自己的局限性,并尽力寻求 Web 开发人员的反馈。不幸的是,到目前为止,我还没有看到哪个小组在这方面取得了很大的成功。例如,虽然有 Twitter/X 的投票机制,但这些投票往往只有前沿的 Web 开发人员参与,而且容易被投票者的个人观点所影响。
其次,我对 WHATWG 规范(如 HTML 和 DOM)的经验并不多,这些规范的决策过程似乎是异步进行的(“在面对面会议期间做出的任何决定都应被视为非约束性”——来自 WHATWG meetings),然而,我的印象是他们似乎能够做出更好的决策。像 Anne van Kesteren、Simon Pieters 和 Domenic Denicola 这样的人可能比地球上其他任何人更了解 Web 技术。但即使如此,这并不等同于他们完全了解 Web 开发的实际情况和挑战。
Web 开发人员对 Web 开发非常了解
作为一名浏览器工程师,发布新的平台功能无疑是一种令人满足的体验。当我的工作成果被 Smashing Magazine 和 CSS Tricks 等知名技术媒体报道,并在 Twitter/X 上引发广泛讨论时,很容易让人误以为全世界都已经知道了这一伟大的新进展。
然而,几年前的某一天,Mozilla 日本团队的一些成员决定在东京进行一项特别的调查,我们采访了一些当地的 Web 开发人员,了解他们对最新开发工具的看法和使用情况。
结果令人惊讶。
我们发现许多开发人员对十年前推出的新 CSS 功能一无所知。更令人沮丧的是,即使我们告诉他们这些功能,他们似乎并不感到兴奋。他们表示,使用 jQuery 和 WordPress 已经能够很好地完成工作,对此心存感激。
相反,他们更关心的是一些实际问题,比如:“在响应式设计模式下为客户展示网站时,如果没有 iPhone 模型来模拟设备视图,客户很难理解他们所看到的是该网站在手机上的预览效果。我真的需要那个 iPhone 模型。”
作为一个参与制定新 Web 标准的浏览器工程师,我对这些开发人员面临的现实问题深感失望。但我更深刻地认识到,他们在交付网站和 Web 应用的过程中所面临的限制和挑战。
与从事浏览器开发或资金充裕的硅谷初创公司的人不同,许多 Web 开发人员在小公司工作,面临着巨大的压力,需要快速交付项目以满足客户需求,然后迅速转向下一个项目以维持生计。他们没有时间去探索即将推出的新技术,而是更倾向于寻找他们已经熟悉的经过验证的解决方案。
浏览器并非专门为运行单页面应用而设计
从浏览器开发回归到 Web 开发,我发现关于浏览器工作方式的某些观点令人惊讶。
在从事动画开发时,我发现许多人误以为动画 “在 GPU 上运行”。实际上,浏览器可以将部分动画卸载到单独的进程或线程中,使用 GPU 来更新动画并合成每一帧。然而,这并不意味着所有动画都完全在 GPU 上运行。相比之下,有些观点则更为离谱,如 “浏览器不是为运行单页面应用(SPA)而设计的”。
有一种观点认为,最初的浏览器主要是从网络加载内容,逐步进行布局和渲染,并且针对这一过程进行了大量优化。动态内容的出现相对较晚,因此优化程度可能较低。
然而,我从事浏览器开发近二十年的时间里,并不完全认同这一观点。Firefox 的前端和开发者工具实际上就是一个 SPA。尤其是开发者工具,它们使用 React 和 Redux 编写,各个方面都体现了 SPA 的特点。
关于浏览器在处理通过 JavaScript 进行的复杂和长寿命 DOM 树的动态更改方面存在缺陷的观点,这与浏览器的发展趋势相矛盾。
尽管有人可能会提出移动端浏览器并未针对 SPA 进行优化的观点,但实际上,这并不意味着浏览器在处理 SPA 方面存在根本缺陷。例如,在 Android 上,Firefox 从使用 HTML 渲染的浏览器外壳切换到了本地浏览器外壳以提高性能。我无法评论导致这一变化的特定性能限制是什么,但当时的一篇博客 表明这与改善应用启动时间和平移和滚动性能有关,这两者都不表明浏览器在处理 SPA 方面比其他架构更差。
“好吧,也许浏览器可以处理复杂的长寿命 DOM 树,进行频繁的动态更改,但 SPA 往往具有大型 JS 捆绑包,下载和解析速度较慢,阻塞了初始渲染。” 这是一个合理的论点,但它主要关注的是捆绑包大小和初始渲染的阻塞问题,而不是浏览器是否适合运行 SPA。实际上,这个问题同样适用于普通的 WordPress 站点。
多页面应用将取代单页面应用
在探讨 SPA(单页面应用)和 “编写 Web 应用程序的唯一真实方式” 时,近期关于 “浏览器无法处理 SPA” 的一种观点是 “MPA(多页面应用)将取代 SPA”。
我对 MPA 持有相当积极的态度。更具体地说,作为一名与众多动画规范密切相关的人,我对 视图转换规范 感到十分兴奋。在 Mozilla,特别是在 Firefox OS 时期,我们一直致力于推动这一 提案 的实现。我十分赞赏 Jake 等人最终使这一规范成为现实。
视图转换规范最初是专为 SPA 设计的,但现已适应了 MPA 的工作方式,并为多页面站点带来了更加愉悦的用户体验。
然而,基于 “SPA 是不好的” 这一思想,似乎有一种趋势认为 MPA 是未来的发展方向,而 SPA 将逐渐被淘汰。
与前文中的观点不同,我对这一看法的惊讶并非基于我在浏览器开发上的工作经验,而是基于我最近在 Web 应用程序方面的工作经验。
首先,我们需要明确什么是 MPA。
在我理解中,与 SPA 的特点 —— 拥有一个或两个长寿命的 DOM 树,经常由脚本频繁更新 —— 不同,MPA 主要是通过导航到从网络提供的不同 HTML 资源来更新内容。这些资源不必是最顶层的导航,例如,可以通过导航到 <iframe> 来实现。同样,SPA 可能使用 `` 来进行分块,但内容的更新方式通常存在区别。
根据这个定义,Google Docs 是一个 SPA,因为虽然每个文档都作为单独的资源提供,但大多数时候,用户与通过 JavaScript 不断更新的单个文档进行交互。YouTube 可能被认为是 MPA,但实际上可能是作为 SPA 实现的,通过平滑内容变化、拦截导航并通过脚本替换内容。
然而,对于 MPA 将取代所有 SPA 的想法,我感到惊讶:Figma 或 Web 上的 Photoshop 将如何作为 MPA 工作?或者 Slack、Discord、Google Maps 等应用又该如何实现?
目前,我正处于开发一款以离线优先的移动 Web 应用程序的过程中,该程序可以将数据存储在本地并同步到服务器。为了站在 Web 技术的前沿,我研究了如何采用 MPA。
在简要阐述观点时,我们应考虑到保持预期用户体验的重要性。对于具有独立导航面板和离线优先要求的移动 Web 应用程序,引入 ``,将功能划分到单独的 HTML 请求中(而非单独的脚本块请求)以及预渲染某些块是合理的解决方案。然而,这样做将使复杂性显著增加(例如,双向同步首先变成三向同步),并可能带来更多的错误、延迟和功能发布缓慢等问题。
鉴于应用尚未发布,这一点上的论据可能显得较为薄弱。由于无法实际查看应用程序,因此请相信我的观点。我确实已经尝试过其他架构,但根据我对此特定应用程序的了解,这并非正确的架构选择。因此,对于提出 everything 应该采用 MPA 的建议,我感到十分惊讶。
所有网站都应该在没有 JavaScript 的情况下运行
在探讨 Web 开发最佳实践时,构建一个在无 JavaScript 环境下仍能正常运行的站点无疑是一个值得追求的目标。这样的做法能够确保站点在失去 JavaScript 功能时仍能保持良好的降级体验,避免 JS 阻塞初始渲染,并确保在各类浏览器中的正常运行。然而,这一目标有时被过于教条化,甚至有观点认为 “所有站点都应该在没有 JavaScript 的情况下工作”。
我理解,如果你的站点能够在无 JavaScript 环境下正常工作,那么这个结论可能看似合理。然而,对我而言,这种观点似乎过于狭隘。
正如我之前提到的 Figma 和 Photoshop for Web,以及浏览器的开发者工具和 Parapara Animation,很难想象这些工具和应用程序在没有 JavaScript 的情况下如何正常运作。
因此,在追求无 JavaScript 站点的同时,我们也需要认识到并非所有站点和应用都适合或能够在无 JavaScript 环境下运行。关键在于确保站点在失去 JavaScript 功能时仍能提供良好的用户体验,并尽可能地避免功能上的缺失。
在无障碍性方面,Mozilla 的专家分享了关于键盘导航的经验,强调 Tab 导航应保持相对粗糙,即使用 Tab 键导航至控制组(如工具栏),再使用箭头键在该组内移动。这种 “粗略” 的导航方式能够提高用户在应用程序中的移动速度,避免用户需要通过每个控件逐一使用 Tab 键进行导航。WAI(Web Accessibility Initiative)将此称为“roving tabindex”。
然而,实现这种粗粒度的键盘导航需要依赖 JavaScript。若要使基于箭头键的导航具备二维特性,则需更多的 JavaScript 代码。虽然我们期待有一天平台能够填补这一空白(期待 focusgroup 的进展),但目前,我们应坦然地利用客户端 JavaScript 提升应用程序的无障碍性。
我认为,有些站点应当更加积极地运用 JavaScript。
以 Eleventy 为例,其文档在很大程度上避免了使用客户端 JavaScript。由于 Eleventy 支持多种模板语言,它为每种语言都提供了代码示例。遗憾的是,它并未记录用户选择的语言,导致用户若非默认语言,则需在每个代码示例上更改选项卡。若在此处加入一些客户端 JavaScript,将显著提升用户体验。
更新(2024 年 1 月 11 日):根据最新反馈,Eleventy 似乎已采纳建议并进行 修复。
Web 开发不应该需要构建步骤
尽管本文的大部分内容源自 2022 年,但在整理过程中,我忍不住加入了一些近期让我深感惊讶的想法。
在 Web 开发教条主义的列车上,我们抵达了最后一站,一个观点再次浮现在我脑海中,它虽然已经出现多次,但仍然让我感到惊讶。我最近看到的一个版本大致是这样的:“我们如此盲目和固执,以至于我们最终拥有了一个非常复杂的工具链,但我们实际上应该能够在完全没有构建步骤的情况下发布 Web 应用。”
作为一名长期使用编译型语言的专业人士,我对无需构建步骤的愿景感到惊讶。编译器工程师所展现的精湛技艺令我惊叹不已。他们是真正的天才,通过巧妙的优化技术,将平凡的代码转化为卓越的性能。如果可能的话,我希望在我的 Web 开发中能够更多地运用这种编译器的魔法。显然,JavaScript 本身存在挑战,因为静态确定操作的副作用可能非常困难,但我相信在编译时优化 JavaScript 方面仍有很大的探索空间。
Web 开发人员似乎在优化图像资产和在合适的情况下预生成静态 HTML 页面方面达成了共识,但为什么在优化代码资产方面存在抵制情绪?为什么要将计算和 I/O 推迟到运行时,而不是在构建时完成一次?此外,我不想每次请求时都向每个用户发送我那长达一兆字节的针对 iOS Safari 的诅咒。也许 2024 年将是客户端 Rust/WASM 前端框架崭露头角的一年,如果是这样,我们最好习惯有一个构建步骤!
我的博客不能代表整体 Web 开发的情况。
“Web 开发的整体情况”。从浏览器工程师转变为 Web 开发人员的过程中,我发现许多关于 Web 开发的观念其实源于人们根据自己的经验进行的推断,而这些经验与我所经历的并不重合。自从我四年前离开 Mozilla 以来,我大部分时间都专注于开发 Web 应用,同时也在博客上投入了大量时间。令人惊讶的是,这两者在工具、架构或所使用的 Web 平台特性方面几乎没有交集。就像博客和应用分别代表了 Web 开发领域中截然不同的方向一样。
我的 Web 应用主要基于 TypeScript 编写,而我的博客几乎不使用客户端 JavaScript。我的应用通过双向数据同步变得相当复杂,而我的博客是静态的、只读的。我的应用使用 webpack 进行模块打包,使用 Playwright 进行端到端测试,采用一个组件框架和状态管理库。相比之下,我的博客并没有使用这些工具和技术。如果你主要与其中一个领域打交道,很容易认为这就是 Web 开发的全部。然而,事实上,Web 开发可能比我们想象的要更加多元化和丰富。
结论
除了上述观念外,还有一些其他的观念也让我感到惊讶。但上述内容的共同主题是,人们很容易假设自己的 Web 经验能够代表整个 Web 开发领域。
从浏览器开发转向 Web 开发是一次令人惊叹的体验,因为它比我知道的要广泛和深刻得多。我对 Web 开发者产生了更深的敬意,尤其是那些在小型 Web 商店和初创公司工作的人。他们的 Web 应用的成功与否直接关系到他们的生计。
如果你正是这样的一名开发者,我希望通过阅读这篇文章,你能确信,即使浏览器工程师、标准编辑和其他 Web 开发者坚持采用特定的方法,你对自己的约束有着更深入的了解,并且你可能能够做得很好。
原文链接:
https://birtles.blog/2024/01/06/weird-things-engineers-believe-about-development
评论