Skip to content

The "simple bind" does not actually seem to improve performance at all #8866

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
baybal opened this issue Sep 30, 2018 · 1 comment
Closed

Comments

@baybal
Copy link

baybal commented Sep 30, 2018

What problem does this feature solve?

There is a helper function bundled in Vue.js:

/**

  • Simple bind, faster than native
    */
    function bind (fn, ctx) {
    function boundFn (a) {
    const l = arguments.length;
    return l
    ? l > 1
    ? fn.apply(ctx, arguments)
    : fn.call(ctx, a)
    : fn.call(ctx)
    }
    // record original fn length
    boundFn._length = fn.length;
    return boundFn
    }

The "bind is slow" myth has not been true for quite some time. Native bind should be faster on any any much recent browser. And arrow functions should be even faster as long as there is no need to reuse these functions somewhere else.

Please refer to the benchmark https://jsperf.com/bind-is-slow

I think there should be a bigger review of other helper functions, to see if the case for their use is still there in modern browses.

What does the proposed API look like?

Can we replace "simple bind" with native bind?

@Justineo
Copy link
Member

The code you provided seems to be out-dated. Actually Vue now prefers native bind already.

vue/src/shared/util.js

Lines 176 to 205 in 79cabad

/**
* Simple bind polyfill for environments that do not support it... e.g.
* PhantomJS 1.x. Technically we don't need this anymore since native bind is
* now more performant in most browsers, but removing it would be breaking for
* code that was able to run in PhantomJS 1.x, so this must be kept for
* backwards compatibility.
*/
/* istanbul ignore next */
function polyfillBind (fn: Function, ctx: Object): Function {
function boundFn (a) {
const l = arguments.length
return l
? l > 1
? fn.apply(ctx, arguments)
: fn.call(ctx, a)
: fn.call(ctx)
}
boundFn._length = fn.length
return boundFn
}
function nativeBind (fn: Function, ctx: Object): Function {
return fn.bind(ctx)
}
export const bind = Function.prototype.bind
? nativeBind
: polyfillBind

See #7408.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants