只在需要的时候 Polyfill 你的 JavaScript 代码
本文转载自 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 请求。
什么,都激动得热泪盈眶了?快,赶紧擦擦。 :)
只在需要的时候 Polyfill 你的 JavaScript 代码的更多相关文章
- 136.只出现一次的数字 leetcode ^运算符 JavaScript解法
leetcode上的一道题简单题 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. 你可以不使用额外空间 ...
- 【Leetcode】【简单】【136. 只出现一次的数字】【JavaScript】
题目描述 136. 只出现一次的数字 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. 你可以不使用额外 ...
- 关于下拉刷新你是否真的非常理解还是只会搬砖?附 Android 实例子源代码文件下载地址380个合集
1,推荐几篇非常有用的博文 原创写的真的非常好 主要讲解原理,整体布局三部分组成以及设置padding等等作用, 下拉的具体实现 滑动到底部具体加载以及判断手势事件,再次推荐作者的 详细讲解 建议先看 ...
- 只需几行 JavaScript 代码,网页瞬间有气质了!
最近在网上闲逛,发现一个特别好玩的 JavaScript 库,叫 RoughNotation.干嘛用的呢?就是在网页上给文字加标注,比如下划线.方框.高亮文字背景等,不过是手写风格的!截图给大家感受下 ...
- MyEclipse 2016 CI 4新增BootStrap模板
Live Preview with CodeLive 目前CodeLive还只有Live Preview这一个功能,在后续的版本中会陆续添加新功能. 新增Bootstrap模板 在模板面板中选择相应的 ...
- 构建通过 Database.com 提供技术支持的 PhoneGap 应用程序
要求 其他必要产品 Database.com account 用户级别 全部 必需产品 PhoneGap Build 范例文件 Database.Com-PhoneGap-Sample 在这篇文章中, ...
- Servlet第六篇【Session介绍、API、生命周期、应用】
什么是Session Session 是另一种记录浏览器状态的机制.不同的是Cookie保存在浏览器中,Session保存在服务器中.用户使用浏览器访问服务器的时候,服务器把用户的信息以某种的形式记录 ...
- Servlet第六篇【Session介绍、API、生命周期、应用、与Cookie区别】
什么是Session Session 是另一种记录浏览器状态的机制.不同的是Cookie保存在浏览器中,Session保存在服务器中.用户使用浏览器访问服务器的时候,服务器把用户的信息以某种的形式记录 ...
- Web前端性能优化进阶——完结篇
前言 在之前的文章 如何优化网站性能,提高页面加载速度 中,我们简单介绍了网站性能优化的重要性以及几种网站性能优化的方法(没有看过的可以狂戳 链接 移步过去看一下),那么今天我们深入讨论如何进一步优化 ...
随机推荐
- 微信小程序之组件的集合(六)
这个将是最后一篇关于小程序的记录了,课程接近尾声,最后一个是关于用户的page页面,看看这个页面中有哪些值得学习的地方! 一.page中my开发 这个主要是展示用户喜欢的杂志,以及用户的信息,需要创建 ...
- Trie树 模板
普通Trie: struct TRIE{ ],tot,end[MAXN]; TRIE(){tot=;} void insert(char *s){//s为要插入的字符串 int len=strlen( ...
- 洛谷 P2886 [USACO07NOV]牛继电器Cow Relays
题面 解题思路 ## floyd+矩阵快速幂,跟GhostCai爷打赌用不用离散化,最后完败..GhostCai真是tql ! 有个巧妙的方法就是将节点重新编号,因为与节点无关. 代码 #includ ...
- c++继承知识点小结
继承的概念 继承是c++中一个重要的概念.继承是指,我们可以使用一个类来定义另一个类,在创建这个类时,我们就不需要重新编写数据成员与成员函数,这可以大大方便我们编写代码和维护代码的效率. 当我们使用一 ...
- windows下 将tomcat做成服务,并于oracle后启动
一.将tomcat做成服务 1.下载解压版的tomcat 6.*, 设置java.tomcat的环境(这个就不说了). 2.运行->cmd->到tomcat安装目录的bin目录: 3.运行 ...
- PHP 缓存详解
为什么要使用缓存 一个网站或者一个应用的标准流程是浏览器向应用服务器发出请求,应用服务器做一些计算和逻辑判断之后再请求数据库,数据库收到请求后在经过计算将数据返回给应用服务器,应用服务器再次计算后把数 ...
- 2018-10-31-C#-程序内的类数量对程序启动的影响
title author date CreateTime categories C# 程序内的类数量对程序启动的影响 lindexi 2018-10-31 14:7:6 +0800 2018-10-1 ...
- Leetcode438.Find All Anagrams in a String找到字符串中所有字母异位词
给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引. 字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100. 说明: ...
- MySQL系列(六)--索引优化
在进行数据库查询的时候,索引是非常重要的,当然前提是达到一定的数据量.索引就像字典一样,通过偏旁部首来快速定位,而不是一页页 的慢慢找. 索引依赖存储引擎层实现,所以支持的索引类型和存储引擎相关,同一 ...
- linux操作系统清除报错Disk /dev/mapper/ddf1_4c53492....
现象描述 Disk /dev/mapper/ddf1_4c5349202020202010000055000000004711471100000a28p1: 666.0 GB, 66600088934 ...