向我解释 Twitter 源代码的前 10 行

Avatar of Anand Chowdhary
Anand Chowdhary

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 200 美元的免费积分!

在过去的几周里,我一直在为我的租赁家具公司 Pabio 招聘高级 全栈 JavaScript 工程师。 由于我们是一个远程团队,我们在 Zoom 上进行面试,我观察到一些开发者在现场编码或白板面试中表现不佳,即使他们很擅长这项工作。 因此,我们进行了一个小时的技术讨论,我问他们关于 Web 指标、可访问性、浏览器大战以及其他类似的网络主题的问题。 我一直喜欢问的一个问题是:“向我解释 Twitter 源代码的前十行左右。”

我认为这是一个简单的测试,可以告诉我很多关于他们基础前端知识的深度,这篇文章列出了最好的答案。

为了提供背景信息,我共享我的屏幕,打开 Twitter.com 并单击查看源代码。 然后我要求他们逐行解释,帮助我理解 HTML,他们可以随意说多或少。 我还放大文本以使其更易读,因此您看不到整行,但可以了解大概。 以下是它的样子

Screenshot of source code from Twitter.

请注意,由于我们的技术讨论是一个对话,我不指望任何人给出完美的答案。 如果我听到一些正确的关键词,我知道候选人了解这个概念,我会尽力引导他们走上正轨。

第 1 行:<!DOCTYPE html>

每个文档源代码的第一行非常适合这个面试,因为候选人对 DOCTYPE 声明的了解程度与他们的工作经验年限密切相关。 我仍然记得我在 Dreamweaver 时代使用过长的 XHTML DOCTYPE 行,就像 Chris 在他 2009 年的文章 “常用的 DOCTYPES” 中列出的那样。

完美答案: 这是文档类型 (doc-type) 声明,我们始终将其放在 HTML 文件的第一行。 您可能认为此信息是多余的,因为浏览器已经知道响应的 MIME 类型是 text/html; 但是 在 Netscape/Internet Explorer 时代,浏览器需要完成一项艰巨的任务,即从多个竞争版本中确定要使用哪个 HTML 标准来呈现页面。

这尤其令人讨厌,因为每个标准都生成不同的布局,因此采用此标签是为了简化浏览器的操作。 以前,DOCTYPE 标签很长,甚至包含规范链接(有点像今天的 SVG),但幸运的是,简单的 <!doctype html> 在 HTML5 中得到了标准化,并且至今仍在使用。

也接受: 这是 DOCTYPE 标签,用于让浏览器知道这是一个 HTML5 页面,应该按照这种方式呈现。

第 2 行:<html dir="ltr" lang="en">

源代码中的这行可以告诉我候选人是否了解可访问性和本地化。 令人惊讶的是,在我的面试中,只有少数人了解 dir 属性,但它是关于屏幕阅读器的良好切入点。 几乎每个人都能弄清楚 lang="en" 属性,即使他们以前从未使用过它。

完美答案: 这是 HTML 文档的根元素,所有其他元素都在此元素内部。 在这里,它有两个属性,方向和语言。 direction 属性的值为从左到右,用于告诉用户代理内容的方向; 其他值为从右到左(用于阿拉伯语等语言),或者只是 auto,这将由浏览器自行确定。

language 属性告诉我们此标签内部的所有内容都是英文; 您可以将此值设置为任何语言标签,甚至区分 en-usen-gb,例如。 这对于屏幕阅读器来说也很有用,因为它们可以知道要宣布哪种语言。

第 3 行:<meta charset="utf-8">

完美答案: 源代码中的 meta 标签用于提供有关此文档的元数据。 character set (char-set) 属性告诉浏览器要使用哪个字符编码,Twitter 使用标准的 UTF-8 编码。 UTF-8 很棒,因为它具有许多字符点,因此您可以在源代码中使用各种符号和表情符号。 将此标签放在代码开头很重要,这样浏览器在遇到此行时不会已经开始解析太多文本; 我认为规则是在文档的前 1 千字节中放置它,但我认为最佳做法是在 <head> 的开头放置它。

作为旁注,Twitter 似乎为了性能原因省略了 <head> 标签(减少要加载的代码),但我仍然喜欢将其明确声明,因为它为所有元数据、样式等提供了一个清晰的容器。

第 4 行:<meta name="viewport" content="width=device-...

完美答案: 源代码中的此 meta 标签用于在小型屏幕(如智能手机)上正确调整网页大小。 如果您还记得最初的 iPhone 演示,史蒂夫·乔布斯在那个只有 4.5 英寸的小屏幕上展示了整个纽约时报网站; 当时,这是一个惊人的功能,您需要捏住屏幕放大才能真正阅读。

现在,网站的设计都是响应式的,width=device-width 告诉浏览器将设备的 100% 宽度用作视窗,这样就不会出现水平滚动,但您甚至可以指定特定像素值的宽度。 标准的最佳做法是将初始缩放比例设置为 1,并将宽度设置为 device-width,以便用户仍然可以随意放大缩小。

源代码截图没有显示这些值,但需要了解:Twitter 还应用了 user-scalable=0,顾名思义,它禁用缩放功能。 这对可访问性不利,但使网页感觉更像是原生应用程序。 它还设置了 maximum-scale=1 以达到相同目的(您可以使用最小和最大比例将缩放能力限制在这些值之间)。 一般来说,设置完整宽度和初始缩放比例就足够了。

第 5 行:<meta property="og:site_name" content="Twitt...

大约 50% 的候选人了解 Open Graph 标签,对这个问题的良好答案表明他们了解 SEO。

完美答案: 此标签是 Open Graph (OG) 元标签,用于网站名称 Twitter。 Open Graph 协议 由 Facebook 制定,目的是简化链接展开并 以漂亮的卡片布局显示其预览; 开发人员可以添加各种作者信息和封面图片,以实现花哨的共享。 事实上,如今使用 Puppeteer 等工具自动生成 Open Graph 图片也很常见。 (CSS-Tricks 使用一个 WordPress 插件 来完成此操作。)

另一个有趣的旁注是,meta 标签通常具有 name 属性,但 OG 使用非标准的 property 属性。 我想这就是 Facebook 的作风? 标题、URL 和描述 Open Graph 标签有点多余,因为我们已经为它们提供了常规的 meta 标签,但人们为了安全起见会添加它们。 如今,大多数网站都使用 Open Graph、其他元标签以及页面内容的组合来生成丰富的预览。

第 6 行:<meta name="apple-mobile-web-app-title" cont...

大多数候选人不知道这一点,但经验丰富的开发者可以谈论如何为 Apple 设备优化网站,例如 apple-touch-icon 和 Safari 固定标签 SVG。

完美答案: 您可以在 iPhone 的主屏幕上固定一个网站,使其感觉像是原生应用程序。 Safari 不支持渐进式 Web 应用程序,而且您实际上无法在 iOS 上使用其他浏览器引擎,因此如果您想要那种原生体验,您别无选择,而 Twitter 当然喜欢这种体验。 因此,他们添加了此内容来告诉 Safari 此应用程序的标题为 Twitter。 下一行类似,控制应用程序启动时状态栏的外观。

第 8 行:<meta name="theme-color" content="#ffffff"...

完美答案: 这是 Apple 状态栏颜色元标签的正确 Web 标准等效项。 它告诉浏览器对周围的 UI 进行主题设置 Android 上的 Chrome 和桌面上的 Brave 都做得很好。 你可以在内容中放置任何 CSS 颜色,甚至可以使用 media 属性仅为特定媒体查询显示此颜色,例如,以支持深色主题。 你也可以在 Web 应用清单中定义此属性和其他属性。

第 9 行:<meta http-equiv="origin-trial" content="...

我采访的每个人都不知道这一点。 我认为你只有对标准跟踪中发生的所有新事物有深入了解才会知道这一点。

完美答案: 原点试验使我们能够在我们的网站上使用新的和实验性的功能,用户代理会跟踪反馈并将其报告给 Web 标准社区,而无需用户选择加入功能标记。 例如,Edge 针对双屏和可折叠设备原语进行了原点试验,这很酷,因为你可以根据可折叠手机是打开还是关闭来创建有趣的布局。

也接受: 我不知道这个。

第 10 行:html{-ms-text-size-adjust:100%;-webkit-text...

几乎没有人知道这一点;只有当你了解 CSS 边缘情况和优化时,你才能弄清楚这一行。

完美答案: 假设你没有移动响应式网站,你在小屏幕上打开它,浏览器可能会调整文本大小使其更大,以便更容易阅读。 CSS text-size-adjust 属性可以使用 none 值禁用此功能,或者指定浏览器允许将文本放大到某个百分比。

在这种情况下,Twitter 表示最大值为 100%,因此文本大小不应大于实际大小;他们这样做是因为他们的网站已经是响应式的,他们不想冒浏览器使用更大的字体大小破坏布局的风险。 这是应用于根 HTML 标签的,因此它适用于其内部的所有内容。 由于这是一个实验性的 CSS 属性,因此需要供应商前缀。 此外,此 CSS 之前缺少 <style>,但我猜想这是在上一行中被压缩了,我们没有看到它。

也接受: 我不知道这个特定属性,但 -ms-webkit- 分别是 Internet Explorer 和基于 WebKit 的浏览器需要的供应商前缀,用于非标准属性。 当 CSS3 发布时,我们曾经需要这些前缀,但当属性从实验性变为稳定或被采用到标准跟踪时,这些前缀就会消失,取而代之的是标准化的属性。

额外 — 第 11 行:body{margin:0;}

Twitter 源代码中的这行特别有趣,因为你可以接着问关于重置网页和规范网页之间区别的问题。 几乎每个人都知道正确答案的某个版本。

完美答案: 由于不同的浏览器具有不同的默认样式(用户代理样式表),因此你需要覆盖它们以重置属性,以便你的网站在不同设备上看起来相同。 在这种情况下,Twitter 告诉浏览器删除 body 标签的默认边距。 这仅仅是为了减少浏览器之间的不一致,但我更喜欢规范样式而不是重置样式,即在浏览器之间应用相同的默认值,而不是完全删除它们。 人们曾经使用 * { margin: 0 },这完全是过度杀伤,对性能也不利,但现在通常导入类似 normalize.cssreset.css(甚至 更新的版本)并从那里开始。

更多行!

我总是喜欢玩浏览器检查器工具,看看网站是如何制作的,这就是我想到这个主意的方法。 即使我自认为是语义 HTML 方面的专家,但每次做这个练习我都会学到一些新东西。

由于 Twitter 主要是一个客户端的 React 应用,所以源代码中只有几十行。 即使这样,也有很多东西可以学习! Twitter 源代码中还有几行很有趣,我把它留给读者作为练习。 你能在面试中解释其中的多少?

<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="Twitter">

…告诉浏览器用户可以添加 Twitter 作为搜索引擎。

<link rel="preload" as="script" crossorigin="anonymous" href="https://abs.twimg.com/responsive-web/client-web/polyfills.cad508b5.js" nonce="MGUyZTIyN2ItMDM1ZC00MzE5LWE2YmMtYTU5NTg2MDU0OTM1" />

…有许多有趣的属性可以讨论,特别是 nonce

<link rel="alternate" hreflang="x-default" href="https://twitter.com/" />

…用于国际着陆页。

:focus:not([data-focusvisible-polyfill]){outline: none;}

…用于在不使用键盘导航时删除焦点轮廓(此处对 CSS :focus-visible 选择器进行了填充)。