本文转载自 Pascal Klau,他是一名来自德国南部的实习生,他讨厌不必要的 HTTP 请求,也不爱吃西兰花。Pascal 将说明使用 polyfill 服务的一种方式,在这种方式下你可能可以完全不必使用它。

现状

我们想要用ES6 语法来写 JavaScript。然而由于我们需要兼容老版本的浏览器,那些浏览器不支持 ES6,我们需要解决这个问题。

有一个标准的做法是:写 ES6 代码 → 将所有代码编译成 ES5 的(比如通过 Babel)→ 再将编译后的代码加载到浏览器执行。

这可能已经不再是最有效率的方式了。因为用这种方式,我们强制最新的浏览器运行旧代码,实际上它们完全可以运行最新的代码。它们支持 ES6,我们难道不能直接给它们 ES6 代码吗?

改进方式

有一个 polyfill 项目叫做 Polyfill.io API,它可以通过 polyfill 方式在客户端执行 ES6 代码。

它也实现了一些 HTML 特性的 polyfill,比如 <picture> 元素。

下面是他们网站的描述:

Polyfill.io 读取每个请求的 User-Agent(UA) 头,并生成适合于该浏览器的 polyfill ,基于你的应用所使用的特性发回必要的代码。[...]

Financial Times 在开发和维护这个项目,所以我们能确信这个项目可以持续更新下去,不会死掉。

有一点需要明白:Polyfill.io 没有提供语法糖支持。比如 类、增强的对象字面量,以及箭头函数之类的特性。对那些代码,你仍然需要进行编译。

配置 Polyfill.io

Adding Polyfill.io to your project can be this simple. Add the CDN-hosted script to your page:

要添加 Polyfill.io 到你的项目里非常简单。将托管在 CDN 的脚本添加到你的页面上:

`<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>`

运行脚本将返回 UA 和你想要的特性。

UA detected: chrome/56.0.0
Features requested: default

修改请求参数

它提供了一堆选项 来自定义你要返回的特性。

Features

该参数指定需要 polyfill 的浏览器特性。多个特性名之间用逗号分隔。允许使用的特性明在 浏览器和特性 页中列出。

`<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=fetch"></script>`

在 Safari 10 下,脚本返回内容如下:

Features requested: fetch

- setImmediate, License: CC0 (required by "Promise", "fetch")
- fetch

如果一个特性,比如 fetch 依赖于另一个特性比如 Promise,Polyfill.io 会自动加载依赖。

Flags

  • always - Polyfill 将始终被包含,不管 UA 中指出的浏览器是否已经支持该特性。
  • gated - 通过特性检测来判断 Polyfill,只有在浏览器原生 API 不支持这些特性的情况下才返回并执行 Polyfill。
`<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=fetch&flags=gated"></script>`

Callback

Polyfill 脚本加载完成之后要执行的函数名。这是最简单的在 polyfill 加载完成后触发你自己的代码的方式,这样 polyfill 服务可以更容易通过 async 和 defer 属性被异步加载。

存在的问题

听起来很好,但是仍然不完美。

最新的浏览器不需要加载 ES5 代码了,但是还需要通过服务器请求来检测是否需要 polyfill。

这非常困扰我,因此我正在做一个小项目来改进它。

一个更好的方式

配置 dynamic polyfill

我创建了一个叫做 dynamic-polyfill 的 npm 包。它在发起任何服务端请求前检测特性是否已经被原生支持。

它的配置看起来如下:

import polyfill from 'dynamic-polyfill'

polyfill({
fills: 'fetch, Promise',
options: 'gated', // default: null
minify: false, // default: true
afterFill() {
main()
}
}) function main() {
// app code here
}

简单来说,它的执行过程如下:

检测 [window.fetch, window.Promise] 是否存在。

如果存在,运行 afterFill() 回调。

如果它们不存在,创建一个 <script> 标签,并且包含 async 属性,将 Polyfill.io 链接插入,用参数中提供的选项去请求,并在它加载完成后执行 afterFill() 回调。

注意: 现在还没有支持全部选项,只有那些最重要的项被支持。

脚本很小

由于这个模块在压缩后不到 1KB 大小,而且没有任何依赖,对项目使用来说成本超低。

结论

为最新的浏览器写不过时和有效率的 JavaScript,让 Polyfill.io 去处理老版本的的浏览器,如果不必要,别发起额外的 HTTP 请求。

什么,都激动得热泪盈眶了?快,赶紧擦擦。 :)

最新文章

  1. C#求斐波那契数列第30项的值(递归和非递归)
  2. VIPM 发布功能总结
  3. 【Bug】看不见的分隔符: Zero-width space
  4. Java 中的 request 和response 区别
  5. 20145330第十周《Java学习笔记》
  6. 记录javascript 验证字符串布尔类型 及url 参数获取
  7. Http 与 Socket 区别
  8. 删除用不到的linux内核
  9. HDU --2665
  10. python数据类型和3个重要函数
  11. Hadoop: HDFS 格式化时,出现 &ldquo;ERROR namenode.NameNode: java.io.IOException: Cannot create directory /usr/hadoop/tmp/dfs/name/current&rdquo;
  12. sql server 更新两个表的某个字段
  13. UNIX 高手的 10 个习惯
  14. Docker入门到实践
  15. eclipse在mac上的快捷键
  16. websocket 的客户端 websocket-sharp
  17. unity, 在image effect shader中用_CameraDepthTexture重建世界坐标
  18. java里面main函数为什么要用static修饰
  19. rtp header
  20. 20155338课程设计个人报告——基于ARM实验箱的Android交友软件的设计与实现

热门文章

  1. object and namespace
  2. Django项目:CRM(客户关系管理系统)--75--65PerfectCRM实现CRM课程分数排名
  3. linux 获取外网ip地址
  4. 901. Online Stock Span [短于线性的时间统计单个元素的Span ]
  5. sql 书写顺序
  6. UOJ#80. 二分图最大权匹配 模板
  7. linux上源码安装python
  8. JavaScript创建对象的几种方式总结
  9. Hackerrank--Prime Sum
  10. java -cp ../../DESUtil/ Hello,用-cp指定classpath