freactive
freactive copied to clipboard
Create polyfills for supporting older browsers
Good polyfills for things like requestAnimationFrame
, addEventListener
, etc. to support older browsers where feasible
Om uses
(if (exists? js/requestAnimationFrame)
(js/requestAnimationFrame #(render-all state))
(js/setTimeout #(render-all state) 16))
so I think it fits most cases.
(def request-animation-frame
(if (exists? js/window.requestAnimationFrame)
js/window.requestAnimationFrame
#(js/window.setTimeout % 16)))
addEventListener
polyfill could be borrowed from Dommy:
(if (.-addEventListener elem)
(.addEventListener elem (name actual-type) canonical-f)
;; For IE < 9
(.attachEvent elem (name actual-type) canonical-f))))
(if (.-removeEventListener elem)
(.removeEventListener elem (name actual-type) canonical-f)
;; For IE < 9
(.detachEvent elem (name actual-type) canonical-f))))
Sounds good. Would you want to make a pull request so you'll get credit? ;)
We could also try to capture vendor prefixes and make sure there's a performance timestamp (although I'm not really sure this part is necessary): https://gist.github.com/timhall/4078614
I think attachEvent might need the "on" prefix: http://stackoverflow.com/questions/2657182/correct-usage-of-addeventlistener-attachevent.
I also intend to allow people to optionally plug-in goog.events or another handler system if they want a well tested event subsystem. For instance one could require freactive.gevents
and then call use-goog-events!
We could also just do this by default - but possibly some would complain about increased size...?
Yes, I will make pull request after we come to agree of preferred solution. What about size increase on using google events — it is to be tested, may be it will be negligible.
We could also try to capture vendor prefixes and make sure there's a performance timestamp (although I'm not really sure this part is necessary): https://gist.github.com/timhall/4078614
I think this solution is overengineering with doubtful value. We must not rely on any particular fps — so we don't need precise timing. Also, if our render cycle is too heavy then it seems that logic is quite heavy too and we want to give it 16ms to proceed, not to shrink its time. And, if our render cycle is heavy, we should remember that setTimeout polyfill does not stop rendering when tab is inactive (requestAnimationFrame does), so we don't want to make high cpu load when inactive, so empirical 16ms pause is also good in this case
I think attachEvent might need the "on" prefix
Yes, but now I think that we have no necessity to support attachEvent. IE8 has too many problems aside of this one to drop its support, and IE9+ has addEventListener, so we have no problems with it.
So I agree with what you're saying about precise timing. We could just try to pull in the vendor prefixes and if not, use the setTimeout with 16ms like Om.
#17 polyfill arrived ;-) i will investigate plugging of google closure events these days and then report back, m.b. in a new issue or pull request
Okay, sounds good. I think that polyfill looks pretty good so I'm going to go ahead and merge it.
I did :advanced
compile of example from freactive readme using addEventListener
vs goog.events/listen
ul@cybercraft ~/S/f/bench> du *
176K goog-frk.min.js
172K native-frk.min.js
goog.events adds about 4K, which is about 2.3%. I think it is not much, especially keeping in mind that it is minimal example, real app will be bigger. Also, we can make it pluggable. What is the best way to make this? Allow to pass listen!
and remove-event-listener!
(hmmm... m.b. unlisten!
will be more consistent & short?) as parameters to mount?
Cool. How much is that gzipped?
We can just have a separate namespace that calls set! on the listen! var - not very Clojure-like I know, but I think it's okay.
On Sunday, November 23, 2014, Ruslan Prokopchuk [email protected] wrote:
I did :advanced compile of example from freactive readme using addEventListener vs goog.events/listen
ul@cybercraft ~/S/f/bench> du * 176K goog-frk.min.js 172K native-frk.min.js
goog.events adds about 4K, which is about 2.3%. I think it is not much, especially keeping in mind that it is minimal example, real app will be bigger. Also, we can make it pluggable. What is the best way to make this? Allow to pass listen! and remove-event-listener! (hmmm... m.b. unlisten! will be more consistent & short?) as parameters to mount?
— Reply to this email directly or view it on GitHub https://github.com/aaronc/freactive/issues/4#issuecomment-64130328.
ul@cybercraft ~/S/f/bench> du *
48K goog-frk.min.js.gz
44K native-frk.min.js.gz
delta is the same =)
Is that your whole project?
On Sunday, November 23, 2014, Ruslan Prokopchuk [email protected] wrote:
ul@cybercraft ~/S/f/bench> du * 48K goog-frk.min.js.gz 44K native-frk.min.js.gz
delta is the same =)
— Reply to this email directly or view it on GitHub https://github.com/aaronc/freactive/issues/4#issuecomment-64132591.
No, it is example from freqctive README. Give 5 minutes, I will post benchmark using my project codebase.
Hmmm... I'm already using goog.events
for routing, so size doesn't changed with listen switch. After removing events from routing it... also without change, m.b. one of dependencies uses goog.events
:
ul@cybercraft ~/M/m/bench> du -b *
474370 goog.js
474373 native.js
ul@cybercraft ~/M/m/bench> gzip *
ul@cybercraft ~/M/m/bench> du -b *
121756 goog.js.gz
121757 native.js.gz
So, I looks like freactive by itself isn't that heavyweight right now.
On Sunday, November 23, 2014, Ruslan Prokopchuk <[email protected] javascript:_e(%7B%7D,'cvml','[email protected]');> wrote:
Hmmm... I'm already using goog.events for routing, so size doesn't changed with listen switch. After removing events from routing it... also without change, m.b. one of dependencies uses goog.events:
ul@cybercraft ~/M/m/bench> du -b * 474370 goog.js 474373 native.js ul@cybercraft ~/M/m/bench> gzip * ul@cybercraft ~/M/m/bench> du -b * 121756 goog.js.gz 121757 native.js.gz
— Reply to this email directly or view it on GitHub https://github.com/aaronc/freactive/issues/4#issuecomment-64133392.
created PR #21 as goog.events
topic continuation
Core.async uses goog.async.nextTick:
https://github.com/google/closure-library/blob/master/closure/goog/async/nexttick.js
https://github.com/clojure/core.async/blob/422f8b25f0c4d5e3aea5113436c735e553422be7/src/main/clojure/cljs/core/async/impl/dispatch.cljs#L29
See the comments in goog.async. Works down to IE6.
HTH
https://github.com/google/closure-library/blob/master/closure/goog/async/nexttick.js#L15
/**
* @fileoverview Provides a function to schedule running a function as soon
* as possible after the current JS execution stops and yields to the event
* loop.
*
*/
requestAnimationFrame
has a little bit another purpose
Doh. Ignore this then. I was too quick with the post. Sorry for the noise.
No problem, you are welcome!
Let me try this again. This should be it:
https://github.com/google/closure-library/blob/master/closure/goog/async/animationdelay.js
Yes, looks like it is the one, thank you. @aaronc, what do you think?