只在需要的时候 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前端性能优化进阶——完结篇
前言 在之前的文章 如何优化网站性能,提高页面加载速度 中,我们简单介绍了网站性能优化的重要性以及几种网站性能优化的方法(没有看过的可以狂戳 链接 移步过去看一下),那么今天我们深入讨论如何进一步优化 ...
随机推荐
- 基于在树上走的DP问题
笔者已经很久没有打过题解了,如果打题解,就总是要连着一个知识点来打题解. 最近做过一共两道这样的题目.笔者认为这样的题有较强的可拓展性,比较有意义. 所以就打一篇博客. 问题概述 先说说这是个什么样的 ...
- substring() 方法用于提取字符串中介于两个指定下标之间的字符。
substring() 方法用于提取字符串中介于两个指定下标之间的字符. 语法 stringObject.substring(start,stop) 参数 描述 start 必需.一个非负的整数,规定 ...
- javascript中json对象与json字符串
var data = "{'name':'张山','age':20}"; //转换字符串为json对象: var jsondata = JSON.parse(data); //转换 ...
- PAT甲级——A1030 Travel Plan
A traveler's map gives the distances between cities along the highways, together with the cost of ea ...
- Spring-session整合到Redis
闲来无事,学习一下spring的session管理,作为一个初学者,我了解到了如下内容: 1.为何要用Spring-session 在传统单机web应用中,一般使用tomcat/jetty等web容器 ...
- 关于mapreduce 开发环境部署和jar包拷贝问题
1.mapreduce开发应当在linux里面的eclipse不然容易出现问题. 2.把eclipse拷贝到linux环境中,然后需要拷贝hadoop-eclipse-plugin-2.3.0.jar ...
- Jquery手机下拉刷新,下拉加载数据
一.Jquery手机下拉刷新,下拉加载数据.附加有源码 <!DOCTYPE html> <html> <head> <title>手机</titl ...
- /etc/inittab配置文件详解
init的进程号是1,从这一点就能看出,init进程是系统所有进程的起点,Linux在完成核内引导以后,就开始运行init程序,init程序需要读取设置文件/etc/inittab.inittab是个 ...
- Django运行错误常见问题及解决方法1
如果不是在JetBrains PyCharm 2017.2里创建的想在JetBrains PyCharm 2017.2里运行.可以在 编辑结构 进行配置正常使用
- 20190819 [ B ]-沫
这次考试很懵,于是我记录了考试过程. 这是B场,比较简单,A场比赛题解请去 下面直接展开=.= 考试过程: 先看三道题, T1,我一下就想到了内个等比数列.于是慌了,我当时是水果的. T2,没思路 T ...