WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
NEW
265386
Streaming HTML only works in iframe elements. Safari waits to buffer all HTML before rendering.
https://bugs.webkit.org/show_bug.cgi?id=265386
Summary
Streaming HTML only works in iframe elements. Safari waits to buffer all HTML...
Nathan Knowler
Reported
2023-11-27 09:03:32 PST
Created
attachment 468769
[details]
Deno Server which streams HTML. Run with `deno run --allow-net deno-server-streaming-html.js`. Safari doesn’t seem to be streaming HTML at all, except for `<iframe>` elements. Right now, it appears to buffer all the HTML before rendering anything. To reproduce you will need a web server that supports streaming. The attached example uses Deno (1.38.2). When run locally, it’ll serve HTTP/1.1 and adds the correct `Transport-Encoding: chunked` header. I have a hosted variation of the example which is being served with Deno Deploy:
https://shadowroot-streams.deno.dev
. It also uses the Declarative Shadow DOM. That example uses HTTP/2 and correctly doesn’t use the `Transport-Encoding` header since it’s incompatible with HTTP/2. In short, Deno’s streaming the content correctly and Deno Deploy supports HTML streaming. Note: the attached example admittedly doesn’t have a tonne of HTML in the first chunk, but that doesn’t seem to matter at all for streaming into an `<iframe>` element. Other browsers are also able to stream this fine.
Attachments
Deno Server which streams HTML. Run with `deno run --allow-net deno-server-streaming-html.js`.
(743 bytes, text/javascript)
2023-11-27 09:03 PST
,
Nathan Knowler
no flags
Details
Source code of the hosted Deno server which streaming to the Declarative Shadow DOM.
(1.85 KB, text/javascript)
2023-11-27 09:05 PST
,
Nathan Knowler
no flags
Details
View All
Add attachment
proposed patch, testcase, etc.
Nathan Knowler
Comment 1
2023-11-27 09:05:10 PST
Created
attachment 468770
[details]
Source code of the hosted Deno server which streaming to the Declarative Shadow DOM.
Radar WebKit Bug Importer
Comment 2
2023-11-27 09:39:50 PST
<
rdar://problem/118837578
>
Konnor Rogers
Comment 3
2024-09-25 14:05:37 PDT
To add to this, the problem is very specific. Safari seems to need about 512bytes of HTML to start streaming, otherwise it will remain buffered as noted here:
https://lamplightdev.com/blog/2024/01/10/streaming-html-out-of-order-without-javascript/
*BUT* the problem is even more speific than "512 bytes", Safari seems to want 512 bytes of displayable HTML. That is, any element in the `<head>` is ignored, any element that is default hidden IE: `<script>`, `<template>`, HTML comments, etc are all ignored. Even `<canvas>` with text in it is ignored. The "easiest" way of triggering HTML streaming seems to be with a height / width of 0 div, with no overflow. Like this: ```html <body> <div style="height: 0; width: 0; overflow: hidden;" hidden> {{ 512 bytes of data }} </div> <!-- stream the rest --> </body> ``` This seems to be Safari / WebKit specific and is a pretty big gotcha.
Konnor Rogers
Comment 4
2024-09-25 14:11:44 PDT
Sorry, `<div hidden>` actually causes it to still buffer. So you need to use aria-hidden instead. ```html <body> <div style="height: 0; width: 0; overflow: hidden;" aria-hidden="true"> {{ 512 bytes of data }} </div> <!-- stream the rest --> </body> ```
Konnor Rogers
Comment 5
2024-09-25 14:57:01 PDT
As it turns out, the first element in the body doesn't seem to count. So its even worse than that. The above code will not stop buffering. But it will work if you inject it into the shadowroot of the body. Here's the secret incantation Joel Drapper came up with to skirt Safari's HTML streaming. To note, Safari expects 512 characters, and not 512 bytes, so there's 512 escape sequences for zero width white space. ```html <!DOCTYPE html> <html> <head></head> <body> <template shadowrootmode="open"> <span aria-hidden="true" style="-webkit-user-select: none; user-select: none;"> ​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ </span> </template> </body> </html> ```
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug