Web 性能是一个非常复杂的主题。 有总请求数、页面重量、首次渲染时间、可交互时间、首次输入延迟等指标。 需要考虑异步请求、渲染阻塞和优先级下载等事项。 我们经常讨论性能预算和性能文化。
第一个文档从服务器下载的方式是一个热门话题。 这就是大多数与后端相关的性能讨论进入画面的地方。 它催生了像JAMstack这样的架构,至少我们不用担心index.html
速度慢。
图像有自己的性能故事(格式!自适应图像!)。 字体也是(FOUT'n'friends!)。 CSS 也一样(谈论渲染阻塞!)。 服务工作者可以在各个层级参与。 当然,JavaScript 可能是最常讨论的性能反派。 所有这些都与最重要的通用性能概念相平衡:感知性能。 前端开发人员在性能方面已经有很多责任。 80% 是普遍认可的数字,在我看来是合理的。
让我们暂时假设我们要构建一个网站,并且不要进行服务器端渲染。 相反,我们要加载一个空文档,并尽快启动数据 API 调用,然后使用该数据渲染网站。 如今这并非罕见的情况。 您可以想象,>我们现在有了另一个主要问题:处理加载体验。
前几天我对此进行了思考。 这是一个例子
客户端渲染太有趣了。 看看这种糟糕的加载体验。 页面本身并不慢,但加载方式很奇怪。 前端开发人员必须精通的东西。 pic.twitter.com/sMcD4nsL98
— Chris Coyier (@chriscoyier) 2018 年 10 月 30 日
我想说这种加载体验非常糟糕,而且我使用的是最好的硬件和互联网连接。 这并不算灾难,而且肯定有成千上万的人每天都在成功使用这个网站。 也就是说,它不像你想象的未来时代的高预算网站那样感觉快速、流畅或特别好。
部分原因可能是因为该页面没有进行服务器端渲染。 无论出于何种原因(我们无法从外部得知),他们并没有这样做。 这可能是开发人员效率、安全问题、重写过程中的临时状态……谁知道呢!(这可能不是无知。)
我们该怎么办? 好吧,我认为这是一个稍微有点新的问题,出现在前端开发中。 我们告诉浏览器:“嘿,我们搞定了。 我们将根据我们的 API 向我们提供内容以及我们的前端框架何时决定进行操作,以无序的方式加载所有内容。” 我可以理解这种观点,认为这不是理想的做法,我们放弃了浏览器非常擅长做的事情,而是自己做了一些做得不如他们好的事情。 但是,正如我在这里稍微解释过的那样,世界很复杂。
实际上发生的事情是,这些前端框架意识到了这个问题,并正在采取措施来帮助管理它。 今年四月,Dan Abramov 推出了 React Suspense。 它似乎是一个工具,可以帮助我们这些前端开发人员管理一个想法,即我们现在需要处理比以往更多的加载状态问题。
大约 14 分钟后,他开始介绍使用占位符组件、缓存等获取数据。 当然,这个问题并不局限于 React,但为了保持一致性,以下是由 Andrew Clark 进行的一次会议演讲,我很快就感同身受(但最终使用了相同的演示等)
仅仅是等待显示加载指示器一会儿就能在很大程度上消除加载时的卡顿感。
Mikael Ainalem 在最近的一篇文章中指出了这一点,闪烁的加载指示器的简史。 他更清楚地解释了我试图说的话。
这种发展背后的一个原因是我们所见过的异步编程的变化。 异步编程比以前容易多了。 大多数现代语言都很好地支持动态加载数据。 现代 JavaScript 已包含 Promise,并且 ES7 带来了 async 和 await 关键字。 使用 async/await 关键字可以轻松获取数据并在需要时处理数据。 这意味着我们需要更进一步地思考如何向用户显示数据正在加载。
此外,他还提供了一些解决方案!
查看 Pen 闪烁的加载指示器,作者是 Mikael Ainalem (@ainalem),网站是 CodePen。
我们必须在这方面做得更好。
简单来说:除非网站是一个完整的 Web 应用,否则请避免使其臃肿并充满 AJAX 内容。
如果是 Web 应用呢?
奇怪的是……我还记得十年前第一次激动不已,因为我感觉自己终于设计出了一个半具挑战性的加载体验。 它涉及动态内容、一些分散的异步小部件、一些高影响力的内容图片(一些位于自动运行的轮播中),以及大量复杂的闪亮灯光效果,位于文本下方(在 CSS 渐变出现之前),并且在上面叠加了更多图片。 其中一些方面朝着不同的方向拉扯。 一些图片大小是严格控制的,因此在各个方面都很适合硬编码尺寸,但动态内容的变化足够大,需要构建一些扩展/收缩容差。 当时,我认为最多同时下载 6 个文件,并且所有这些大型图片和几个内容块都没有从服务器端传递。 关于图片,有些图片对于文本可读性和理解至关重要(以背景图片和图标形式存在),而有些图片与任何内容一样重要,如果缺少会留下很大的空白区域(或者突然推到其他位置)。 异步小部件及其内容当然也存在类似的问题,并引发了一些问题:你是显示空占位符、加载占位符,还是后来被称为骨架状态的东西,还是在内容准备就绪之前不显示任何内容,然后突然跳动地出现? 设计师是否能同意我在处理高影响力视觉元素时所做出的选择,并将它们作为加载时的渐进增强来应用?
从那以后,它变得确实更具挑战性了,尽管在数量上比在基本问题空间上更具挑战性。 在工具方面,而不是在基本解决方案空间方面。 毕竟,网络上的排队分发问题以及客户端必须通过该网络加载自身部分的问题是互联网和 Web 的基本问题。 与过去 20 年之前大多数带有 GUI 的软件不同,您无法预先启动。 用户在首次访问之前不会下载您的网站——您只有一次机会来完善未缓存的加载体验,否则很多人都会离开。
我不知道。 我看到这样的体验,并且确切地知道在不强制使用客户端渲染、React 和 Webpack 的情况下我会怎么做,尽管我做出了关于它的假设,因为我看到了它现在的加载方式……如果我不是被同事强迫只使用客户端渲染、React 和 Webpack 的话。 这些都没有错,但是它们结合在一起的方式以及它们在这里的最新状态——再加上 Web 设计师被挤出这个行业——让它变得更加困难(至少对我来说,也许如果这种情况正在恶化,对于很多人来说……但因人而异)。
只有我一个人认为对极致性能的喧嚣毫无意义吗? 当然,没有人愿意等待 10 秒钟来加载页面。 但是我忍不住认为,让页面在 < 2 秒内变得可交互就足够快了——对于 80% 的人来说肯定足够快了——并且试图优化超过这个范围基本上是毫无意义的,而且这部分时间可以更好地花在其他地方。
我希望 CSS 可以解决其中的一些问题(假设浏览器能足够快地加载它),但是像容器的 min-height 这样简单的东西在很大程度上可以防止卡顿。 更不用说占位符背景颜色或其他不需要太多努力的技术了。