01:04
<GPHemsley>
nn nn nn nn nn nn nn nn nn (alright!)
04:38
<inian>
Hey, Synchronous XHR requests on the main thread got deprecated recently.
04:38
<inian>
I was using them to analyse JavaScript where some dynamic values were sent to the server and the program execution continued based on the values returned by the server. Of course, this was just to analyse JS and not for a user-facing website. Is there any other alternative for carrying out such analyses where the further program execution depends on the result of the XHR call without a sychronous XHR?
04:50
<caitp>
inian: you can block useful functionality until a promise is fullfilled, for example
04:51
<caitp>
show a loading spinner or splash screen until that happens
09:25
<annevk>
Request.prototype.abort() -- I can think of three states a Request object can be in. 1) Before passed to fetch(). 2) After passed to fetch(). 3) Exposed to SW (similar to before passed to fetch(), but subtly different in state).
09:25
<annevk>
I think only in 2) should it actually do something. Making it work in 3) seems confusing, invoking preventDefault() seems like a better alternative.
09:25
<annevk>
Am I missing something?
13:47
<annevk>
So the problem with articles introducing these application frameworks is that the critique is never really backed up by evidence. E.g. http://calendar.perfplanet.com/2013/diff/ claims "Attaching event listeners to DOM nodes is painfully slow and memory-consuming." as justification for event delegation. Now we want event delegation at some point with native support, but I always thought that was mostly for convenience...
13:48
<annevk>
The recent Flipboard article simply claimed that the DOM was slow. And everyone echoes the sentiment, but it never gets really concrete.
13:56
<caitp->
well, it's not like there aren't aspects of it which are correct
13:59
<caitp->
people touch the DOM, cause unwanted/unexpected layout, hear about the cost of crossing between JS and native code, hear "we can't optimize calls to native code", think about creating a bunch of new event listeners in memory for every important node they care about instead of just one, etc
13:59
<caitp->
it doesn't mean it's all true, but you can see how people come to those conclusions
14:00
<caitp->
then you have people writing 3 line benchmarks to prove their case
14:00
<caitp->
or drawing a correlation between MMR vaccines and autism based on a sampling of 12 kids
14:01
<caitp->
people are funny like that
14:01
<caitp->
preconceived notions, confirmation bias, and a tiny bit of fact
14:09
<annevk>
Sure, but I need the facts :-)
14:13
<gsnedders>
My favourite benchmarks are those where we can LICM the whole benchmark. Why run your benchmark multiple times anyway? That's pointless!
14:16
<annevk>
LICM?
14:16
<Ms2ger>
loop invariant code motion
14:17
<annevk>
ah
14:17
<annevk>
Decided to ask the author: https://twitter.com/annevk/status/566234156754288640
14:17
<annevk>
If native event delegation would be a big help, we should just go ahead and do it
14:18
<wanderview>
annevk: why do we want abort() on Request instead of passing a timeout parameter to fetch()?
14:20
<wanderview>
it just seems like something more related to the actual fetch() operation, and not all the places Request object is used
14:20
<wanderview>
I guess having the abort() on the fetch() returned Promise would be ideal
14:23
<wanderview>
I guess that doesn't exist, though
14:23
wanderview
reproduces the issue conversation in his head.
14:25
<gsnedders>
annevk: basically JS VMs are getting better and better at entirely optimizing out benchmarks
15:02
annevk
waits for wanderview to resolve
15:06
wanderview
aborted.
15:07
<annevk>
hah, that doesn't exist :p
15:08
<annevk>
wanderview: so another idea Hixie had was to have a message channel between the API initiating the request and the FetchEvent in the service worker; that also seems like something you'd put on Request
15:14
<wanderview>
annevk: personally I like defining the timeout as a value that the fetch algorithm interprets instead of an external method called by arbitrary script
15:15
<wanderview>
as the one issue commented pointed out... you really want an inter-packet timeout... not a total request deadline
15:23
<annevk>
wanderview: don't we also want a generic way to abort though?
15:23
<annevk>
wanderview: e.g. if you no longer need something
15:24
<annevk>
wanderview: in any event, even if we don't have abort(), there's still the problem that sometimes we might want methods on Request to proxy somewhere and that falls apart with how fetch() works
15:32
<wanderview>
annevk: I think you need some object representing the fetch operation itself... Request is not that object
15:32
<wanderview>
since it can be used for other things, cloned, etc
15:33
<wanderview>
annevk: can we inherit Promise?
15:34
<annevk>
wanderview: I don't think we want to
15:34
<annevk>
wanderview: if you get declarative constructs around Promise, any subclass of it would be disadvantaged
15:36
<wanderview>
annevk: what about a duck-type compatible object that exposes the underlying promise if needed as .promise?
15:37
<annevk>
wanderview: I don't see how that would be different from a subclass
15:37
<annevk>
wanderview: declarative syntax would still work with the subclass, it's just that the extras are not available (which is why you want to have those elsewhere, not on a subclass)
15:37
<wanderview>
annevk: well... not direct prototype chained... and gives access to the promise if there is a promise-specific operation to perform
16:02
<wanderview>
annevk: with a simple method like fetch() that returns a promise, though... I don't see where you stick those extras, though
16:19
<annevk>
MikeSmith: https://www.w3.org/Bugs/Public/show_bug.cgi?id=26338 has spam in last comment added
16:19
<annevk>
wanderview: one thing some languages have is apparently that you can go from let x = fetch() to let x, y = fetch()
16:19
<annevk>
wanderview: but that seems unrealistic
16:20
<wanderview>
annevk: isn't es(something) adding de-structuring like that?
16:20
<annevk>
wanderview: that leaves you with the value fetch() does return or whatever you pass to fetch()
16:20
<annevk>
wanderview: yeah, but it would require returning [x, y] which would break existing code
16:21
<annevk>
wanderview: you can't return multiple values
16:22
<annevk>
Also, that doesn't really help with the <img>.request.port.postMessage(...) case
16:26
<annevk>
https://github.com/krisselden/simple-dom is nice
16:26
<annevk>
I wonder why they support comments
16:37
<darobin>
annevk: I suspect they might support comments so that when the simple-dom gets inserted into the real DOM, you can debug and find your kittens
16:37
<darobin>
also, perhaps conditional comments could matter in some cases
17:22
<wanderview>
annevk: could we pass an "abort promise" to fetch()... if it resolves or rejects, then the fetch should abort
17:29
<annevk>
wanderview: that's an interesting idea
17:30
<annevk>
wanderview: how would we solve the messaging use case though?
17:30
<annevk>
wanderview: or modifying the Request post-fetch in some kind of HTTP/2 scenario
17:30
<annevk>
(e.g. changing priority on the fly)
17:30
<wanderview>
annevk: make promisses transferable? (to be honest I didn't look at the messaging use case"
17:31
<annevk>
wanderview: the messaging use case is primarily about letting an API endpoint (such as <img> or fetch()) communicate with the service worker handling its fetch
17:32
<annevk>
wanderview: by handing the API endpoint and its FetchEvent a port each
17:32
<wanderview>
annevk: that seems orthogonal to aborting a fetch() call?
17:33
<annevk>
wanderview: oh it is, and modification post-fetch is too, but what they have in common is that they need a way to be exposed
17:34
<wanderview>
annevk: the serviceworker script could tie the onmessage event handler to its "abort promise"... although I guess discouraging globals on SWs makes that harder
17:35
<annevk>
I'm not sure how you would tie to that promise to be honest
17:35
<wanderview>
annevk: the onmessage event handler in SW could deliver a message with attributes like fetchevent: { respondedWith: someResponse } or something
17:35
<annevk>
It's a bidirectional communication channel
17:39
<annevk>
Let's start again, these are the use cases I have for Request:
17:39
<annevk>
1) request.abort()
17:39
<annevk>
2) request.port.postMessage(...) / request.port.onmessage = ...
17:40
<annevk>
3) request.changePriority(...) (and similar things, where you want to change something about an ongoing fetch)
17:41
<wanderview>
yea, I don't like any of those on the request object... we really need a handle to an object representing the on-going fetch
17:42
<annevk>
Now an alternative solution for 1) and 3) would be some kind of promise you pass in, but that would not work for HTML: https://www.w3.org/Bugs/Public/show_bug.cgi?id=26533 not sure about 2)
17:42
annevk
wonders if Domenic has any ideas
17:43
<wanderview>
annevk: could we set a "FetchState" object on the request while its in process?
17:43
<Domenic>
that sounds similar to the cancelation token idea C# uses
17:43
<wanderview>
fetch injects the state object onto the request... and then removes it when its no longer being operated on by the fetch
17:43
<Domenic>
(well, the abort promise idea does, I am still reading downward)
17:44
<annevk>
wanderview: you mean we augment it for a short period of time?
17:44
<annevk>
wanderview: why not just have the API there and only enable it while fetch() is ongoing?
17:44
<wanderview>
annevk: yea
17:45
<wanderview>
same effect I think... stateful APIs like this kind of suck for the dev, though... don't they?
17:45
<wanderview>
I mean my idea sucks too
17:45
<annevk>
https://lists.w3.org/Archives/Public/public-webapps/2015JanMar/0607.html
17:46
<Domenic>
I dunno, maybe we should just solve cancellable promises
17:46
<annevk>
wanderview: it's a bit weird that you cannot reuse the Request during that period of time
17:46
<annevk>
Domenic: that doesn't solve 2/3 though
17:46
<Domenic>
Ah I see
17:46
<annevk>
wanderview: but that's maybe not too bad
17:47
<annevk>
wanderview: but yeah, having some kind of "fetch in progress flag" and exposing that was my idea
17:50
<wanderview>
annevk: what about fetch functions like abortFetch(someRequest)... and does the thing if an active fetch that matches the request is in progress?
17:51
<annevk>
wanderview: that sounds like it requires global lookup
17:51
<annevk>
"is someRequest in your registry?" "oh, please kill it for me"
17:51
<wanderview>
annevk: yes... but the UA could in theory make it happen from any context... vs trying to get the one active Request object to the right place in the dev's code... when we clone it, etc
17:51
<Domenic>
What about fetch({ ..., modifyInProgressFetch(abort, setPriority, port) })
17:51
<annevk>
However, now that you mention it, we might need to keep such a registry, but I'm not sure if we want to expose it
17:53
<annevk>
Domenic: callback I take it? Interesting idea
17:53
<Domenic>
annevk: yeah I guess you'd call back with it immediately
17:53
<Domenic>
kind of like an awkward way of smuggling out multiple return values :-/
17:53
<annevk>
it's the Domenic pattern(tm) https://blog.domenic.me/the-revealing-constructor-pattern/
17:53
<Domenic>
yeppp
17:54
<Domenic>
it seems a bit nicer to put those on Request, I don't really understand the cloning stuff though
17:54
<Domenic>
(or at least it has leaked out of my head since last time)
17:55
<annevk>
currently when you pass a Request to fetch() we transfer the stream (if any) and copy the rest (stripping bits we don't like, such as synchronous flag)
17:55
<annevk>
if the Request did not have a stream you can pass it to fetch() many times
17:55
<annevk>
iirc
17:56
<wanderview>
the callback could be issued on each clone...
17:56
<wanderview>
feels complex to me, though
17:56
<annevk>
I think changing the design of Request to make it aware of it being passed to fetch() would be better
17:58
<annevk>
Oh right, the problem with that is that fetch() only copies from Request what it likes, so we would either have to mutate the Request object, or something else?
17:58
<annevk>
:-(
18:00
<wanderview>
annevk: I still kind of like having fetch stick something on request.. and then script can use that... Request.appendActiveFetch(new ActiveFetch(...))... myRequest.activeFetch.forEach(function(af) { af.abort(); }....
18:00
<wanderview>
when fetch clones a response, it would call appendActiveFetch on the new one Request clone, etc...
18:03
<annevk>
wanderview: I think it would be saner for fetch() to mutate rather than clone and set a flag
18:12
<hemanth_>
does it not makes sense for the arrow function to throw an error on call(), apply(), and bind() as they do not augment the value of `this`?
18:12
<Domenic>
I do agree the cloning seems bad
18:12
<Domenic>
cloning the stream could happen but the entire object seems unnecessary
18:12
<hemanth_>
Some version of FF was throwing an error, the latest one does not
18:15
<wanderview>
well... we can't just clone the body stream until we finish integrating streams into fetch
18:15
<wanderview>
or I guess do some special one off logic in fetch
18:55
<annevk>
wanderview: I'm starting to think that the right thing is to just make Request a one-off everywhere
18:55
<annevk>
wanderview: and if you want to reuse it, better clone it first
19:05
<wanderview>
cd
19:06
wanderview
can't handle two keyboards...
19:30
<Domenic>
tyoshino________: when do you sleep!? haha
22:50
<Hixie>
anyone know if anyone has looked at how many event listeners typical pages have?