构建更精简的 jQuery
jQuery 已经超过五年了!在这段时间里,它随着浏览器、网站、设备、开发者和用户一起发展。它也,嗯,增长了不少。 jQuery 添加了许多有用的功能,但它也积累了一些我们不希望永远支持的累赘。在具有高速连接的台式电脑上可能不是问题,但我们希望 jQuery 也是移动设备的良好解决方案。
除了我们不断追求更高性能之外,我们对即将发布的版本的优先事项是减小压缩后的文件大小。当每个新功能或错误修复都必须保留所有现有功能和行为时,这很难做到。因此今天,我们想开始讨论如何通过弃用一些功能来精简 jQuery API。以下是我们的弃用指南
- 我们认为该功能不代表当前使用 jQuery 的最佳实践。
- 该功能已被证明在实际使用中不受欢迎、令人困惑、效率低下或无效。
- 增强功能或解决其局限性不切实际或不可行。
- 在将来某个时间删除它可以带来显著的可用性、大小或性能优势。
弃用只是一个您可以参与其中的过程的第一步。我们的目标是
- 解释弃用特定功能的原因,如上所述。
- 在弃用和删除之间至少提供一个主版本号,通常更多。
- 为弃用的功能提供替代方案,以便迁移不会很痛苦。
- 倾听社区关于弃用和删除的反馈。
有时,就像 1.7 版本中的 event.layerX/layerY 一样,如果我们认为立即删除该功能比保留它更省事,我们会做出更短通知的重大变更。这些将有希望成为罕见的例外。
1.7 版本弃用
考虑到这些因素,我们认为以下功能从 1.7 版本开始被弃用。继续使用这些功能的现有代码仍然可以工作,但建议使用替代方案以更好地兼容未来的版本。
.live() 和 .die():我们仍然收到许多错误报告,并看到用户对 .live() 方法的怪癖感到困惑。现在,常见的 issue 已经记录在更新后的 API 页面上。我们强烈建议在新的代码中使用 .on() 或 .delegate(),因为它们是更好的 API。鉴于其广泛使用,我们不太可能在 1.8 中删除此 API,但请尽快更新您的代码。
非标准事件属性:作为我们提高事件处理程序性能的一部分,我们也弃用了一些从原生事件对象复制到 jQuery 事件对象的事件属性,并将它们在 1.8 中删除:attrChange、attrName、relatedNode 和 srcElement。与其通过event.NAME
访问它们,您可以在需要时通过event.originalEvent.NAME
访问它们。
$.ajax() Deferred 别名:在 1.5 版本中,我们在 jqXHR 对象上定义了 .error()/.success()/.complete() 作为 Deferred 的 .fail()/.done()/.always() 方法的别名。虽然这在当时看来是个好主意,但这使得 jqXHR 成为非标准的 Deferred。这不是好事。只要有可能,请优先使用 deferred/promise 方法名称,而不是 jqXHR 方法名称。我们在此方面仍有一些工作要做以提供完整的迁移路径,因此我们可能会继续在 1.8 之后支持这些别名。
deferred.isResolved() 和 deferred.isRejected():现在 Deferred 和 Promises 具有进度通知和方便的 .state() 方法,我们弃用了这些旧方法,并将它们在 1.8 中删除。使用 N-1 个布尔方法来获取 N 状态对象的 state 是“二十个问题”的残忍代码版本。基于 Deferred 的代码很少需要检查 state,现在返回的字符串对于调试场景(它经常被使用)更方便。
.attr(“value”) 在输入上:为了向后兼容,我们一直在这里返回当前值(如“当前在输入框中的内容”),而不是实际属性(HTML 中的value
属性值)。这使我们无法提供真正的属性值,而且令人困惑,因为 W3C 选择器作用于属性,而不是当前值。因此,我们弃用了这种行为,并将它在 1.8 中删除。始终使用.val()
方法获取输入元素的当前活动值。在我们无法重新获取属性之前,您可以使用$("selector")[0].getAttribute("value")
,除了 IE 6/7,那里它仍然会返回当前值。(我们的 1.8 解决方案将在所有浏览器上获取属性值,这也是我们迫切希望改变它的另一个原因。)
.closest(Array) 返回 Array:这个签名有点奇怪,它创建用于旧的活动事件代码,但它返回一个 Array,而不是一个 jQuery 对象。从 1.8 版本开始,我们计划删除它。.closest()
的其他签名将保留,不受影响。
.data(“events”):jQuery 将其与事件相关的 data 存储在一个名为(等一下)events
的 data 对象中,该对象位于每个元素上。这是一个内部 data 结构,因此在 1.8 中,它将从用户 data 命名空间中删除,因此它不会与同名的项目冲突。仍然可以通过jQuery._data(element, "events")
访问 jQuery 的事件 data,但请注意,这是一个未记录的内部 data 结构,不应修改。
$.sub() 作为插件:虽然$.sub()
可用于为插件创建无干扰区域,但它没有被 jQuery 核心使用,也没有被其他代码广泛使用,因此我们打算在 1.8 版本中将它转换为插件,以节省空间。
展望 jQuery 1.8
鉴于我们对精简 jQuery 的追求,1.8 中新功能的过滤器将非常严格。即使与性能相关的提案也需要在它们使用的空间或节省的空间之间权衡。可以通过插件、特殊事件、属性钩子或其他 jQuery 扩展机制实现的功能,很可能目前会留在核心之外。
这就引出了一个问题,我们可以在 1.8 中弃用什么,并最终删除以简化和优化库。这些东西不必完全消失;例如,它们可以移动到一个单独的插件中,并且仅在需要时包含。看看您如何使用 jQuery,并与您的同事讨论一下。
在几周内,我们将通过另一篇博客文章公开征求您关于 jQuery 1.8 的想法——所以现在就开始思考吧!
编辑:不,我们还没有,也无法删除 IE6 支持。正如 John Resig 在每次 jQuery 大会上所说,IE6 的大部分罪过也降临到 IE7 和 IE8 上,它们加起来仍然拥有超过三分之一的台式机浏览器市场份额。在我们能够同时干掉 IE7 和 IE8 之前,删除对 IE6 的支持是没有意义的。
做 Modernizr 做的事,让 jQuery 的核心非常精简,然后允许我们选择不同的功能/插件添加到包中,这些功能/插件将被合并到一个定制的 jquery js 文件中。jQuery 在移动设备上绝对可笑,我试过它,甚至官方演示也是个笑话……动画卡顿,而且不流畅……没有人可能使用 jQuery Mobile 并感到满意……
将 IE6 支持放入插件中是个好主意。
我同意将 IE 6/7/8 兼容性作为插件或不同的构建将对我们来说非常重要。
我们的一些应用程序是主流的,我们需要跨浏览器支持,即使我们很讨厌它。
但对于其他一些项目,我们有一群技术人员,他们非常欣赏使用现代浏览器的快速加载应用程序。
这个简单的功能会让我成为 jQuery 的坚定支持者,因为它的含义在于一个更好的网络。整套经济学某种程度上取决于这种选择。你真的可以在这里做出改变。
大多数人不会阅读博客,他们只是在 API 中查找东西。感谢你们的辛勤工作!
弃用和移除并不能解决任何问题,只会制造新的问题。如果必须进行模块化,也绝不应移除。我理解,如果有人在一个小型网站或页面上使用 jQuery,那么从一个版本到另一个版本发生的重大变更并不算什么大事。但对于一个大型的实现项目来说,会有数百甚至数千个使用通用页眉来设置要包含哪些 JS 文件的页面,情况就不一样了。如果你有一个大型的已部署网站,任何重大变更都需要进行修复工作,然后再进行大量的测试,才能重新认证和重新部署新版本(用户验收测试始终是工作量最大的部分)。
此外,人们迁移到新版本的原因并不仅仅是新功能,还包括错误修复和性能改进。除此之外,SOX/审计要求所有生产代码都必须得到供应商的完全支持,并且处于最新的版本/错误修复/安全修复级别。这样的决定意味着,当网站选择使用框架时,它会承担巨大的责任。我认为,如果你每六个月就引入重大变更,那么你将有很大的风险失去大量的开发者支持。
例如,.live() 的移除,为什么不保留它,而只是将其作为 .on() 的辅助函数?这样,你就可以接收 live 函数的参数,并用传递的参数调用 .on()。我认为,引入重大变更比在整体下载大小中添加几 KB 更为可怕。请记住,带宽和计算能力一直在不断提升。我也可以始终使用 jQuery Mobile 来处理移动设备。
微软已经声明 IE6 已经死了,它是一个生命周期结束的产品,不再提供支持。
继续支持已经死亡的产品会消耗开发者资源。
由于所有添加到库中的新函数都需要确保不会破坏任何现有功能,因此需要将测试资源从更重要的任务中转移出来。
将库固定在 <2.0 以支持 IE6,然后从 2.0 开始创建不含 IE6 的新库。
还要考虑这样一个事实:全世界有数百万 KB 的带宽浪费在 jQuery 支持 IE6 上,而实际上并不需要。
我认为 jQuery 2 应该:
1. 只支持 HTML5/CSS3/JS1.9
2. 为我们可怜的 IE 用户推广 ChromeFrame(是时候说再见了,IE10 或者再见了,IE,这样我们才能真正进行创新)
3. 使用 AMD 进行模块化支持
我现在正在为我们的企业客户宣传以上 3 点,我认为以目前的形式,jQuery 在这种环境下将变得越来越不相关。
我必须再次强调我们强烈希望拥有一个模块化的 jQuery,或者至少是一个没有遗留 IE 支持的 jQuery 版本……
虽然我理解在一些基于 Web 的应用程序中需要它,但也同样存在很多应用程序不需要支持 IE,更糟糕的是,人们也不希望随之而来的臃肿——以至于人们已经开始制作 jQuery 的替代方案来满足这种需求……
如果 jQuery 能站出来,掌控局面,为人们提供选择,而不是疏远越来越多的用户群,并将开发工作转移到其他地方,那就太好了。
+1 支持模块化。开发者应该能够自行决定库的哪些部分他们需要,哪些不需要,例如整个 ajax 块。对于最小化、未压缩的版本来说,91 KB 并不那么简洁。
“请不要放弃 IE6!对于一些项目来说,它仍然很重要。至少再给它一年时间!”
如果你需要 IE6 支持,只需使用旧版本的 jQuery。版本 1.8+ 无需对 IE6 进行特殊支持。我相信,一些热衷于开发企业内部网门户网站的开发者会愿意开发一个与 1.8+ 兼容的 IE6 插件,或者足够聪明,可以直接不使用 1.8+
我不明白为什么有些人如此担心移除/弃用功能。如果你需要这些功能,只需使用/坚持使用旧版本的 jQuery。如果它在你的网站上运行良好,那么现在它也会运行良好。如果你仍然为一个针对旧浏览器设计的网站进行开发和支持,那么升级到新版本毫无逻辑意义。这是一个无稽之谈。
我知道这已经是很久以前的话题了……但我支持它。
我并不需要它一定是模块化的,但拥有类似以下的包含文件会很棒:
jquery-2.0.js
jquery-1.4-support.js
jquery-ie6-support.js
太棒了,IE6 真烂!