[HN Gopher] Safari Technology Preview Release Notes
       ___________________________________________________________________
        
       Safari Technology Preview Release Notes
        
       Author : clairity
       Score  : 71 points
       Date   : 2022-05-13 14:57 UTC (8 hours ago)
        
 (HTM) web link (developer.apple.com)
 (TXT) w3m dump (developer.apple.com)
        
       | cyral wrote:
       | For anyone curious, there are a ton of selectors here that you
       | may have never heard of before here:
       | https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-clas...
        
         | clairity wrote:
         | while many of those other pseudo-classes are useful, :has() is
         | a next level of usefulness, as are :is()/:where() and :not().
         | combining these together gives you far-reaching selector
         | capabilities.
         | 
         | safari also now has lch colors and the color() function, which
         | make theming more flexible.
         | 
         | and the color-contrast() function just landed in firefox beta!
         | 
         | edit: subgrid in firefox is pretty nifty too.
        
           | Klathmon wrote:
           | I don't think I've ever been excited for a CSS feature as
           | much as I am for `:has` and `:where`!
        
       | andrethegiant wrote:
       | I wish outline could respect border-radius like in other
       | browsers.
        
         | lucsky wrote:
         | This has been a known bug for 14 (FOURTEEN) years
         | (https://bugs.webkit.org/show_bug.cgi?id=20807). I have lost
         | hope at this point.
        
         | realusername wrote:
         | Don't know if they fixed the buggy border-radius on videos
         | either.
        
       | simonw wrote:
       | I wish there was a convention to favor paragraphs over sentences
       | in release notes.
       | 
       | Understanding most of these release notes requires an extremely
       | deep understanding of WebKit and the relevant web standards.
       | 
       | I'd love to see projects invest more effort in expanding these
       | out. Imagine how much more valuable this document would be if
       | each of the bullet points (or just the most important bullet
       | points) had a couple more sentences clarifying what it meant.
       | 
       | (This is one of the reasons I've started trying to publish
       | annotated versions of the release notes for my own projects:
       | https://simonwillison.net/tags/annotatedreleasenotes/ )
        
         | jyrkesh wrote:
         | I completely agree, but as someone who's owned publishing for
         | changelogs on large-ish, often super technical OSS projects, it
         | can be very difficult to explain some of the concepts needed to
         | grok a bugfix or low-level design change even in the span of a
         | couple paragraphs. And more importantly, that context needs to
         | be written by the engineer involved in the change, which means
         | more context == less code work.
         | 
         | That being said, I think some projects do it extremely well. My
         | gold standard for a while has actually been the OSS Dolphin
         | emulator for Gamecube/Wii. They write incredible progress
         | reports[1] every 1-2 months that give phenomenal context on how
         | they found the bug, why it matters, how it works, and what they
         | did to fix it.
         | 
         | Another great example is VS Code[2]. Their context tends to be
         | around changes that are more UX-oriented, but it's still a
         | great way to understand what new value you're getting on every
         | new release.
         | 
         | [1]: https://dolphin-emu.org/blog/2022/02/08/dolphin-progress-
         | rep...
         | 
         | [2]: https://code.visualstudio.com/updates/v1_67
        
           | tentacleuno wrote:
           | Check out the TypeScript release notes if you like
           | extensively documented notes :-)
        
         | WalterGR wrote:
         | > https://simonwillison.net/tags/annotatedreleasenotes/
         | 
         | Those are amazing. Well done.
        
         | [deleted]
        
       | SquareWheel wrote:
       | I didn't realize Safari already had support for cascade layers.
       | I'm really excited for the reduction in specificity that will
       | allow once frameworks and themes get on board.
        
         | clairity wrote:
         | i've been using :where() to reduce specificity in recent
         | projects. it's not quite the same as cascade layers, but
         | provides a lot of benefit now for modern browsers (support goes
         | back about 2 years).
        
       | [deleted]
        
       | londons_explore wrote:
       | > Removed the 1ms minimum for setTimeout
       | 
       | This one is big - it finally means there are no arbitrary delays
       | when using setTimeout to add something to the next iteration of
       | the javascript main event loop.
        
         | wdb wrote:
         | Never knew this limitation existed
        
           | bryanrasmussen wrote:
           | only in Safari evidently, so it's really a bug fix on their
           | part.
        
             | jkrems wrote:
             | Until very recently it was a thing in all browsers, with a
             | variety of lower bounds depending on which browser. It was
             | meant to prevent accidental busy-loops when developers
             | forgot the set the time parameter IIRC.
        
               | bryanrasmussen wrote:
               | hmm, I can't recall ever noticing it but probably I
               | didn't because it didn't come up or more likely because
               | if I want immediate I explicitly set 0, but anyway the
               | ticket https://trac.webkit.org/changeset/291998/webkit/
               | says
               | 
               | >This patch removes the 1ms minimum for setTimeout. The
               | HTML spec makes no mention of such a minimum, and Firefox
               | and Chrome do not enforce this minimum
               | 
               | so I guess it was other browsers with the varying
               | minimums, or these two removed it earlier.
        
         | [deleted]
        
         | tzs wrote:
         | A bit OT, but setTimeout this reminds me of something I've
         | wondered about.
         | 
         | Suppose you want to make some DOM change, and then when that
         | change has actually been rendered so that the user can see it
         | you want to do something else.
         | 
         | How do you actually wait for a DOM change to show up?
         | 
         | I first ran into this many years ago when I wanted clicking on
         | a table column header to change the sorting of the table with
         | the sort happening client side. The table was big enough that
         | it could take a few seconds to sort, and this was before
         | JavaScript had any true asynchronous computing mechanisms so
         | the page would be unresponsive during the sort. I wanted to
         | change some text near the table to "Sorting...please wait", do
         | the sort, then clear the text.
         | 
         | A Stack Overflow answer said to use setTimeout of 0, and do the
         | sort in the callback. In the pseudocode below, indentation
         | means something done in the callback of the last function above
         | with less indentation and the callback parameter will be
         | omitted in the function that sets the callback.
         | 
         | So that Stack Overflow answer said do this.
         | set_wait_message()       setTimeout(0)
         | sort_table_and_clear_wait_message()
         | 
         | It said that browsers all special cased 0 timeout and took it
         | to mean run when the browser finishes all current pending
         | processing, which included all DOM changes that JavaScript had
         | made but that have not yet rendered.
         | 
         | I tested it on all the major browsers back then, on Windows,
         | Linux, and Mac, and it indeed worked. Great.
         | 
         | But then a few years later I needed it again...and this time it
         | did not work. Timeout 0 callbacks in Firefox were now always
         | running the sort before the DOM updated. I tried double timeout
         | 0:                 set_wait_message()       setTimeout(0)
         | setTimeout(0)           sort_table_and_clear_wait_message()
         | 
         | That sometimes did the trick but sometimes did not.
         | 
         | Stack Overflow and some Googling suggested that the idea should
         | still be sound, but rather than setTimeout one should use
         | window.requestAnimationFrame (rAF) or
         | window.requestIdleCallback (rIC).
         | 
         | On Firefox, those gave similar results to the double timeout 0.
         | On Chrome, where single timeout 0 still worked, rIC worked the
         | same as timeout 0, but rAF seemed to always run the callback
         | code before the DOM update. On Safari timeout 0 and rAF worked,
         | and Safari at the time did not have rIC. On Edge, both timeout
         | 0 and rAF seemed to work, and edge did not have rIC.
         | 
         | I then tested double rAF and double rIC. Both of those seemed
         | reliable on Firefox and Chrome. And since Safari, and Edge all
         | have rAF, and even single rAF seems to work there, double rAF
         | works on them too.
         | 
         | So, as of about 4 years ago when I last looked into this this
         | seems the way to update the DOM, wait for the update to be
         | visible, and then do something:
         | make_DOM_changes()       window.requestAnimationFrame()
         | window.requestAnimationFrame()           // DOM changes are
         | visible
         | 
         | But is this actually guaranteed? Or just an accident of current
         | implementations?
         | 
         | PS: here's a test page to play with this:
         | https://pastebin.com/n26iVs7d The various buttons in the bottom
         | section increment the count shown at the top then do a slow
         | task. If it takes a second for the count to update then the
         | slow task was not deferred until after the DOM update.
        
           | svachalek wrote:
           | It makes sense, in theory the message should paint in the
           | first animation frame but if you got in there before it you
           | may sort before that happens. So you are requesting to wait
           | for the frame after that. I'm sure there's some way it's not
           | "guaranteed" because it seems nothing in front end is
           | guaranteed without some asterisks, but this is the most
           | logically correct solution I've seen.
        
           | Sillzen wrote:
           | >Suppose you want to make some DOM change, and then when that
           | change has actually been rendered so that the user can see it
           | you want to do something else.
           | 
           | >How do you actually wait for a DOM change to show up?
           | 
           | I believe that use case would be covered by
           | MutationObserver[0].
           | 
           | [0] https://developer.mozilla.org/en-
           | US/docs/Web/API/MutationObs...
        
           | floydnoel wrote:
           | I use this, it works well ime: https://gist.github.com/jwilso
           | n8767/db379026efcbd932f64382db...
        
           | jakub_jo wrote:
           | Invoking `getComputedStyle` should also do the trick:
           | https://developer.mozilla.org/en-
           | US/docs/Web/API/Window/getC...
        
             | londons_explore wrote:
             | getComputedStyle causes a layout to occur, but doesn't
             | guarantee that rendering is actually done.
        
         | ash_gti wrote:
         | There is queueMicrotask (https://developer.mozilla.org/en-
         | US/docs/Web/API/queueMicrot...) to queue onto the end of the
         | current iteration and you can use an `await 0;` to cycle the
         | event loop as well.
        
       | ramesh31 wrote:
       | Excited to finally have a parent selector, but this feels like a
       | major footgun that will promote brittle DOM specific CSS.
        
         | culturestate wrote:
         | _> this feels like a major footgun that will promote brittle
         | DOM specific CSS_
         | 
         | I can't say I've really considered this in any depth, but my
         | _very first_ thought when I saw :has() was "finally, I can fix
         | those last stupid bugs in my HN userstyle."
         | 
         | So...you may be on to something.
        
         | WalterGR wrote:
         | :has() sounds amazing on the surface. I'd be interested in a
         | good advantages / disadvantages overview if anyone _:has()_ a
         | link.
         | 
         | Edit: Useful: https://caniuse.com/?search=has
        
           | clairity wrote:
           | there are a bunch of good articles out there on :has() now,
           | like this one: https://www.smashingmagazine.com/2021/06/has-
           | native-css-pare...
           | 
           | i've been experimenting with it on safari tech preview, and
           | it really lets you do many things that were previously
           | impossible or unacceptably brittle. i love it.
           | 
           | same with container queries. have been experimenting, it's
           | really nice compared to page grids and breakpoint hell.
        
             | nicoburns wrote:
             | Ohhh, I didn't know that container queries are finally
             | being implemented. I'd given up on them as something that
             | would be great but didn't look like they were going to
             | happen.
        
           | arrakeen wrote:
           | it's extremely useful for defining ublock origin rules
        
             | WalterGR wrote:
             | So far I've only used it in TamperMonkey. Between your
             | comment and culturestate's[0], you may be on to something.
             | 
             | [0] https://news.ycombinator.com/item?id=31369223
        
       | scottlamb wrote:
       | I see mention of Media Source Extensions (MSE) in these release
       | notes. Good to see they're improving it, I guess. But my
       | understanding [1] is that while Safari on Desktop and iPad
       | support MSE, Safari on iPhone does not. Does anyone know why this
       | restriction exists and if it's likely to be removed? I'd expect
       | these to be substantially the same codebase so the restriction
       | confuses me.
       | 
       | I saw folks speculating about business reasons for this
       | restriction, which confuses me. It seems like HLS provides
       | broadly similar functionality, so I'm not sure how many
       | determined folks are entirely stopped from doing something by
       | Apple's technology choice, or steered toward a native app, or
       | whatever Apple supposedly wants instead. This just makes things
       | unnecessarily painful for small projects.
       | 
       | [1] backed up by https://caniuse.com/mediasource
        
         | jsmith45 wrote:
         | I'd put down a lot of money on this being an artificial
         | limitation, and not a technical issue.
         | 
         | If I had to guess, it is that they have hyper-optimized the
         | pipeline for HLS for battery consumption. Streaming video is
         | one of the most power hungry things people do with their phone
         | that laymen often don't think is power hungry. (Unlike say 3d
         | games, or GPS).
         | 
         | If the MSE path is less optimized (and it is, simply by nature
         | of having JavaScript in the loop handling the video segments),
         | which drains the battery faster, but sites like Twitch,
         | Youtube, and Facebook switch to using MSE, then now the iPhone
         | battery life numbers look worse.
        
           | scottlamb wrote:
           | Fair point; I can see them making the choice for that reason.
           | But I'm not sure it's actually _true_ that HLS is more
           | optimal:
           | 
           | * On the one hand, the MSE path makes all the data flow
           | through Javascript. At least that means chunks must be
           | garbage-collected. I can see it meaning an extra copy or two
           | also.
           | 
           | * On the other hand, doesn't HLS require polling and extra
           | round trips? You fetch the .m3u8 manifest repeatedly, and
           | then fetch the media segments it indicates. If you want
           | lowest possible latency, well, it's 1.5 trips higher than
           | necessary, as well as requiring extra network requests
           | (costing battery for wake-ups and a bit of bandwidth/radio
           | time). As compared to a WebSocket where the server pushes
           | segments as soon as they're available.
           | 
           | In an application of mine, I've thought about writing web
           | worker code to basically create a HLS API for my service from
           | the real, WebSocket-based API. Then it'd work on iPhone. Of
           | course, this means everything would flow through Javascript,
           | totally defeating what advantage HLS has and requiring
           | (device-internal, fortunately) polling.
        
             | lstamour wrote:
             | > As compared to a WebSocket where the server pushes
             | segments as soon as they're available.
             | 
             | This didn't become a requirement for LL-HLS according to
             | this blog post, but you could build the same push technique
             | using HLS and HTTP/2 to push data to the client before it
             | needs to ask for it:
             | https://www.theoplayer.com/blog/impact-of-apple-ll-hls-
             | updat... (or as suggested in the post, provide hint URLs
             | for where the next block will be...)
             | 
             | Apple's official docs on LL-HLS: https://developer.apple.co
             | m/documentation/http_live_streamin...
             | 
             | Edit: the full spec is at
             | https://datatracker.ietf.org/doc/html/draft-pantos-hls-
             | rfc82... and doesn't appear to mention push directly but
             | does require HTTP2.
             | https://www.akamai.com/blog/performance/-using-ll-hls-
             | with-b... Mentions more details but I don't have time to
             | read them now.
             | 
             | I expect folks are looking at this very closely, but the
             | current protocol obviously lets the client be in full
             | control over what gets sent, which would be somewhat lost
             | if relying exclusively on HTTP2 server-initiated push...
             | For example, clients can request separate caches of low and
             | high bitrate media to always ensure they have something to
             | play back in time...
        
               | scottlamb wrote:
               | Oh, I missed EXT-X-PRELOAD-HINT, [1] thanks. That seems
               | like a significant improvement, in that the client can do
               | a hanging GET and have the server respond when the media
               | segment exists, avoiding that transit latency. Still has
               | to send extra requests. (I guess the silver lining there
               | is that this is a flow control mechanism, so the server
               | won't keep sending more data if the client isn't keeping
               | up with previous data. My custom WebSocket protocol
               | doesn't really do flow control right now, beyond what TCP
               | does.)
               | 
               | [edit: another problem: multiple simultaneous hanging
               | GETS are really awkward with HTTP/1.1 due to connection
               | limits. You have to shard the domain name (which causes
               | problems with cookie auth). Or you really need to use
               | HTTP/2 or HTTP/3.]
               | 
               | I'm really confused by the HTTP/2 push thing that article
               | mentioned. My general understanding of HTTP/2 push is
               | that the clients implement it by adding the pushed data
               | to their cache and nothing more. (Or don't implement it
               | at all. IIRC Chrome dropped support.) If the client later
               | needs that URL, it loads more quickly. But there's no JS
               | API for doing something as soon as a push is received.
               | Maybe Safari has a special hook in their HLS
               | implementation that bypasses the polling delay if the
               | media segment is pushed, but if so, I don't know where
               | that's documented, and it's a surprising behavior. Or
               | maybe they gave up on the idea? Dunno.
               | 
               | The whole HLS spec seems arcane compared to a protocol in
               | which the server pushes data over a WebSocket. Even MSE
               | is more complicated than I'd like. I'd rather try
               | WebCodecs, but only Chrome supports it AFAIK. [2]
               | 
               | I suppose the cool kids use WebRTC for live video
               | instead, but my use case is an NVR, where I'd like a
               | uniform way of handling playback and live. I don't think
               | WebRTC really does playback.
               | 
               | [1] https://datatracker.ietf.org/doc/html/draft-pantos-
               | hls-rfc82...
               | 
               | [2] https://github.com/Fyrd/caniuse/issues/5641
        
         | robertoandred wrote:
         | What specifically is not supported on iPhones?
        
           | scottlamb wrote:
           | MSE is _entirely_ unsupported on iPhones. window.MediaSource
           | is undefined. https://github.com/scottlamb/moonfire-
           | nvr/issues/121
        
       ___________________________________________________________________
       (page generated 2022-05-13 23:01 UTC)