zoukankan      html  css  js  c++  java
  • 只在需要的时候 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 请求。

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

  • 相关阅读:
    python安装教程
    protobuf安装教程
    PlantUML安装教程
    题解-CF1140E Palindrome-less Arrays
    FST
    线段树
    题解-CF677D Vanya and Treasure
    最短路
    后缀自动机
    虚树
  • 原文地址:https://www.cnblogs.com/Jeely/p/11130370.html
Copyright © 2011-2022 走看看