响应式设计现在被广泛认为是构建新网站的主要方法。有充分的理由:响应式设计工作流程是为不同设备屏幕尺寸和分辨率构建定制视觉体验的最有效方法。
然而,响应式设计只是构建丰富、引人入胜的移动体验的冰山一角。

响应式网站的性能问题
性能是网站最重要的功能之一,但经常被忽视。许多开发人员都面临着性能挑战 - 为了创建高性能网站,你需要花费大量时间优化网站的后端。更需要花费时间去 了解浏览器的工作原理,以便尽可能快地渲染页面。
在创建响应式网站时,性能挑战更加困难,因为你只有一套标记,用于所有类型的设备。你遇到的一个问题是响应式图像问题 - 如何确保为 Retina Macbook Pro 设计的大图像不会在旧款 Android 手机上下载?如何防止桌面广告在小屏幕设备上渲染?
我们经常在完美条件下进行测试 - 使用快速计算机、快速互联网和靠近服务器,因此很容易忽视性能问题。为了让你了解这个问题的严重程度,我们对一些顶级响应式电子商务网站进行了分析,结果表明,平均响应式网站首页包含 **87.2 个资源**,由 **1.9 MB 的数据** 组成。
可以通过手动调整网站来解决响应式性能问题,但是手动进行性能优化既复杂又重复,因此非常适合创建工具。通过捕获,我们希望使创建高性能自适应网络体验变得尽可能容易。
介绍捕获
捕获是我们开发的一个客户端 API,它可以让开发人员在任何资源开始加载之前完全控制 DOM。对于响应式网站来说,根据设备的条件控制要加载的资源是一个挑战:所有当前的解决方案都需要你对现有的网站进行重大更改,要么使用服务器端用户代理检测,要么强迫你打破语义网络标准(例如,将 src
属性更改为 data-src
)。
我们控制资源的方法是捕获源标记,使其无法被浏览器解析,然后在禁用资源的情况下重建文档。
能够在客户端控制资源让你对网站的性能拥有前所未有的控制权。
捕获是 Mobify.js 1.1 的一项关键功能,Mobify.js 1.1 是我们用于使用客户端模板创建移动和平板网站的框架。在我们 2.0 版本中,我们重新设计了 Mobify.js,使其成为一个更模块化的库,可以在任何现有的网站中使用,捕获是其主要功能。
响应式图像问题的解决方案
人们解决响应式图像问题的一种方法是修改现有的后端标记,将所有 img
元素的 src
更改为类似 data-src
的内容,并在更改后添加 <noscript>
备用方案。这样做的原因在 这篇 CSS-Tricks 文章 中有所讨论 -
“指向马匹图像的 src 将在图像被浏览器解析后立即开始下载。**没有实际的方法可以阻止它**“.
有了捕获,这种情况就不再存在了。
例如,假设你有一个 img
元素,你想为带有 Retina 屏幕的设备修改它,但你不想让 src
属性中的原始图像加载。使用捕获,你可以执行以下操作
if (window.devicePixelRatio && window.devicePixelRatio >= 2) {
var bannerImg = capturedDoc.getElementById("banner");
bannerImg.src = "retinaBanner.png"
}
因为我们可以在任何资源加载之前访问 DOM,所以我们可以在图像下载之前动态地替换图像的 src
。后者的示例非常基础 - 一个更好的示例是突出显示捕获功能的强大之处,以演示 picture
填充的完美实现。
图片填充
Picture 元素是 W3C 用于处理自适应图像的官方 HTML 扩展。有 填充程序可以让你在今天使用 Picture 元素,但它们都不能完美地填充 - 目前实施的最佳填充程序需要在 img
元素周围添加 <noscript>
标签,以支持没有 Javascript 的浏览器。使用捕获,你可以完全避免这种混乱。
打开示例,并确保在 Web 检查器中打开网络选项卡,以查看哪些资源被下载
以下是示例源代码中的重要代码段
请注意,有一个使用 src
属性的 img
元素,但浏览器只下载了正确的图像。你可以在这里查看此示例的代码(请注意,填充程序仅在示例中可用,而不是在库本身中 - 至少目前是这样的)
并非所有网站都使用修改过的 src
属性和 <noscript>
标签来解决响应式图像问题。如果你不想依赖于修改 src
或为网站的每个图像添加 <noscript>
标签,那么另一种选择是使用服务器端检测来替换图像、脚本和其他内容。不幸的是,这种解决方案也存在很多挑战。
当唯一需要担心的设备是 iPhone 时,使用服务器端用户代理检测很容易,但是随着大量新设备的推出,维护一个包含所有设备信息(如屏幕宽度、设备像素比等)的字典是一项非常痛苦的任务;更不用说有些东西你无法通过服务器端用户代理检测,例如实际的网络带宽。
你还可以用捕获做什么?
解决响应式图像问题是捕获的绝佳用例,但还有很多其他用例。以下是一些更有趣的示例
标记中的媒体查询用于控制资源加载
在这个示例中,我们使用图像和脚本属性中的媒体查询来确定哪些图像和脚本将加载,只是为了让你了解你可以用捕获来做什么。你可以在这里找到此示例
使用模板完全重写页面
Mobify.js 1.1 的主要功能是客户端模板,它可以在响应式设计无法提供足够灵活性或更改后端过于痛苦和乏味时,完全重写现有网站的页面。当你需要快速建立移动网站时,它特别有用。这不再是 Mobify.js 的主要功能,但仍可以使用捕获来实现。
查看这个基本示例
在这个示例中,我们获取了现有页面的一部分,并将它们用于呈现给浏览器的全新标记中。
用生气的猫填充你的页面
当然,没有什么比用生气的猫替换页面中的所有图像更有用!当然,要以高性能的方式进行 ;-)。
再次打开 Web 检查器,你会看到网站上的原始图像没有下载。
性能
那么有什么问题呢?使用捕获会降低性能吗?是的,会,但我们认为,通过控制资源可以获得的性能提升超过了捕获带来的轻微损失。在首次加载时,库(以及主可执行文件,如果没有连接在一起)必须下载并执行,而这里的加载时间将根据设备的往返延迟而有所不同(范围从大约 ~60 毫秒到 ~300 毫秒)。但是,由于库被缓存以及即时 (JIT) 编译器使编译效率更高,因此每次后续请求的损失至少会减少一半。 你可以自己运行测试!
我们还尽力将库的大小保持在最小限度 - 在发布这篇博文时,库的最小化 gzip 压缩大小为 4 KB。
为什么要使用捕获?
我们创建了 Capturing,以赋予前端开发人员更多对性能的控制权。其他解决方案无法解决这个问题的原因是,前端和后端的职责变得越来越交织在一起。后端的职责应该是生成语义化的 Web 标记,而前端的职责应该是从后端获取标记,并以最佳方式在设备上进行视觉呈现,并以高性能的方式进行处理。响应式设计解决了第一个问题(以视觉方式呈现数据),而 Capturing 则有助于解决下一个问题(通过使用前端技术(例如确定屏幕大小和带宽以控制资源加载)来提高网站性能)。
如果您想继续遵守语义 Web 的规则,并且想要一种简单的方式来控制前端的性能,我们强烈建议您 查看 Mobify.js 2.0!
如何开始使用 Capturing?
访问我们的 快速入门指南,了解有关如何使用 Capturing 设置的说明。
下一步是什么?
我们已经开始了 Mobify.js 2.0 的官方开发者预览,其中只包含 Capturing 部分,但我们将继续添加更多有用的功能。
要添加的下一个功能是自动调整图像大小,允许您根据浏览器窗口的大小动态下载图像,而无需修改现有标记(除了插入一小段 JavaScript 代码!)。
我们还计划创建其他只能通过 Capturing 解决的 polyfill,例如 新的 HTML5 模板标签。
我们期待您的反馈,并且我们很高兴看到其他开发人员将如何使用我们新的 Mobify.js 2.0 库!
关于 Shawn Jansepar
@shawnjan8 Shawn 是 Mobify 的软件工程师,他在 Mobify.js 开源库和 Mobify Cloud 上工作。他喜欢在前端和后端进行开发,并专注于用户体验。当他不在开发时,您可能会发现他在打曲棍球/玩电子游戏、吃饭或旅行。Shawn 拥有西蒙弗雷泽大学的计算机科学理学士学位。
关于 Robert Nyman [名誉编辑]
Mozilla Hacks 的技术布道师和编辑。发表关于 HTML5、JavaScript 和开放 Web 的演讲和博客文章。Robert 是一位坚定的 HTML5 和开放 Web 信徒,自 1999 年起就一直从事 Web 前端开发工作 - 在瑞典和纽约市。他还经常在 http://robertnyman.com 上发布博客文章,并热爱旅行和结识新朋友。
34 条评论