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? |