惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News and Events Feed by Topic
GbyAI
GbyAI
博客园 - Franky
宝玉的分享
宝玉的分享
Blog — PlanetScale
Blog — PlanetScale
Google DeepMind News
Google DeepMind News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
人人都是产品经理
人人都是产品经理
Microsoft Azure Blog
Microsoft Azure Blog
The Register - Security
The Register - Security
腾讯CDC
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
I
InfoQ
The Cloudflare Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Engineering at Meta
Engineering at Meta
MongoDB | Blog
MongoDB | Blog
有赞技术团队
有赞技术团队
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
F
Full Disclosure
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Vercel News
Vercel News
博客园 - 【当耐特】
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
Schneier on Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Project Zero
Project Zero
量子位
M
MIT News - Artificial intelligence
Stack Overflow Blog
Stack Overflow Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
美团技术团队
Attack and Defense Labs
Attack and Defense Labs
C
Cybersecurity and Infrastructure Security Agency CISA
T
The Blog of Author Tim Ferriss
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Troy Hunt's Blog
Google Online Security Blog
Google Online Security Blog
罗磊的独立博客
P
Proofpoint News Feed
Schneier on Security
Schneier on Security
Spread Privacy
Spread Privacy
S
SegmentFault 最新的问题
L
LINUX DO - 最新话题
Simon Willison's Weblog
Simon Willison's Weblog
爱范儿
爱范儿
博客园 - 聂微东
A
About on SuperTechFans
PCI Perspectives
PCI Perspectives
D
Docker

Henri Sivonen’s pages

Parin vuoden tutkimattomuus crates.io: Rust Package Registry Asiakirjatonta toimintaa It’s not wrong that "🤦🏼‍♂️".length == 7 Koulutartuntojen tilastointimenettely Perusteasiakirjoja hallussapitämättä ikärajoitettu Asiantuntijat ja nukkuva vallan vahtikoira Koronapassilausunto Suppealla tietopohjalla ohimeneväksi väitetty Text Encoding Menu in 2021 The Text Encoding Submenu Is Gone An HTML5 Conformance Checker Not Part of the Technology Stack Browser Technology Stack Bogo-XML Declaration Returns to Gecko A Look at Encoding Detection and Encoding Menu Telemetry from Firefox 86 Why Supporting Unlabeled UTF-8 in HTML on the Web Would Be Problematic Rust Target Names Aren’t Passed to LLVM Toimintamalli Activating Browser Modes with Doctype Johtopäätöksiä mallin rakenteesta Tehtävänmäärittelyä kirjoittamatta ja kuolemia laskematta laumasuojamallinnettu Character Encoding Menu in 2014 Erillissuosituksen tarpeettomuudesta yleissuosituksen poikkeukseksi? STM:n maskiaikajana Rust 2021 Oma-aloitteisesti mallinnettu Kokopinovaatimuksin kilpailutettu chardetng: A More Compact Character Encoding Detector for the Legacy Web Varauksia paisutellen tiedotettu Perusteasiakirjoitta tiedotettu Always Use UTF-8 & Always Label Your HTML Saying So IME Smoke Testing The Validator.nu HTML Parser About the Hiragino Fonts with CSS It’s Time to Stop Adding New Features for Non-Unicode Execution Encodings in C++ Rust 2020 The Last of the Parsing Quirks Rust 2019 a Web-Compatible Character Encoding Library in Rust How I Wrote a Modern C++ Library in Rust Using cargo-fuzz to Transfer Code Review of Simple Safe Code to Complex Code that Uses unsafe A Rust Crate that Also Quacks Like a Modern C++ Library #Rust2018 No Namespaces in JSON, Please A Lecture about HTML5 Julkisesti luotettu varmenne ikidomainille TLS:ää (SSL:ää) varten -webkit-HTML5 Lists in Attribute Values The Sad Story of PNG Gamma “Correction” If You Want Software Freedom on Phones, You Should Work on Firefox OS, Custom Hardware and Web App Self-Hostablility HTML5 Parser Improvements ARIA in HTML5 Integration: Document Conformance (Draft, Take Two) Schema.org and Pre-Existing Communities Lowering memory requirements by replacing Schematron HTML5 Parsing in Gecko: A Build Introducing SAX Tree NVDL Support in Validator.nu HOWTO Avoid Being Called a Bozo When Producing XML An Unofficial Q&A about the Discontinuation of the XHTML2 WG Thoughts on HTML5 Becoming a W3C Recommendation Four Finnish Banks Training Users to Give Banking Credentials to Another Site Unimpressed by Leopard Sergeant Semantics The Content Sink Inheritance Diagram – 2006-06-30 What is EME? About Points and Pixels as Units The Performance Cost of the HTML Tree Builder Social Media Impression Management The spacer Element Is Gone Openmind 2006 Performance Mistake XHTML and Mobile Devices WebM-Enabled Browser Usage Share Exceeds H.264-Enabled Browser Usage Share on Desktop (in StatCounter Numbers) HTML5 Parser-Based View Source Syntax Highlighting Vendor Prefixes Are Hurting the Web Accept-Charset Is No More Dualroids Writing Structural Stylable Document in Mozilla Editor ISO-8859-15 on haitallinen Hourglass The Scientific Method According to Hixie Maemo Source Code Karpelan lukkovertaus ontuu Digitaalisesta arkistoinnista ARIA in HTML5 Integration: Document Conformance (Draft) XHTML—What’s the Point? (Draft, incomplete) Mac OS X Browser Comparison HOWTO Spot a Wannabe Web Standards Advocate An Idea About Intermediate Language Trees and Web UI Generation Thoughts on Using SSL/TLS Certificates as the Solution to Phishing Bureaucracy Meets the Web Europe Day HOWTO Establish a 100% Literacy Rate What to Do with All These Photos? Charmod Norm Checking Validator Web Service Interface Ideas DTDs Don’t Work on the Web EFFI’s Day in Court Speaking at XTech
About about:blank
Henri Sivonen · 2019-09-19 · via Henri Sivonen’s pages

about:blank is probably the hardest Web page to load. In fact, it is so hard that in order to turn the HTML5 parser on by default in Firefox last year, we decided to special-case about:blank to use the old parser in Firefox 4.

In Firefox, about:blank is sometimes parsed from a stream and sometimes its DOM is generated without running a parser. The problem that prevented us from using the HTML5 parser for about:blank is that a bunch of test cases assume that when about:blank is parsed from a stream, the whole operation happens as a single event loop task. These tests aren’t really testing about:blank behavior, but since the test cases are Gecko-specific they inevitably have accidental dependencies on delicate Geckoisms that real Web pages wouldn’t depend on.

The HTML5 parser parses streams off the main thread, so getting anything parsed involves at least two event loop tasks on the main thread and a spin in between. First a task for setup and later another task for handling the data that the parser thread handed back to the main thread. This is OK for parsing streams from the network, because data from the network takes multiple event loop spins to arrive anyway. However, it was a major problem with data: URLs in test cases and it still is a problem with about:blank in test cases.

We want to remove the old HTML parser from the code base entirely after Firefox 4, so special-casing about:blank to use the old parser is not a reasonable long-term solution. Since Gecko’s behavior differs in subtle ways from other browsers, it’s probably a bad idea to implement a special pseudo-parser for replicating the old Gecko behavior exactly. Instead, it would make sense to see what other browsers are doing, standardize the least bizarre but still Web-compatible behavior and implement that.

Unfortunately, it’s not clear what the least bizarre but still Web-compatible behavior is. It seems that IE has had special behavior for about:blank in the window.open case practically forever while IE’s iframe behavior is refreshingly reasonable. Other browsers appear have generalized the special behavior to apply to a all browsing contexts. However, Gecko has done it differently from the others. WebKit used to handle things more like iframes in IE but has moved to a more complex direction.

I tested the behavior of loading about:blank on one hand and another (same-origin) URL on the other hand into an iframe and into a window.open-created browsing context (with pop-up blocker turned off). Since I was aware of significant implementation differences between the traditional window.open case that opens a window and browser prefs that target window.open into a new tab, I tested both cases.

I identified eight different behavior. For ease of presentation, I first list the behaviors and then show a table of which browser has which behavior in which case.

Sync
An about:blank document is created synchronously into the browsing. A load event is fired for it synchronously (or not observable in the window.open case).
Sync plus single-task
An about:blank document is created synchronously into the browsing context. A load event is not fired for it. A task is queued for loading another about:blank document into the browsing context. This second document has its DOM built during the one task, so no bodyless state of the DOM is observable. A load event fires for this second about:blank.
Sync plus async other
An about:blank document is created synchronously into the browsing context. A load event is not fired for it. Later task queue tasks incrementally build the DOM for the non-about:blank document into the browsing context as data arrives from the network. A load event fires for this second document.
Sync plus async other no load
An about:blank document is created synchronously into the browsing context. A load event is not fired for it. Later task queue tasks incrementally build the DOM for the non-about:blank document into the browsing context as data arrives from the network. No load event fires for this second document in a way observable from the outside.
Empty plus async
The browsing context first has an empty (bodyless) document. Later task queue tasks build the DOM for destination document into the browsing context. Load event fires after.
Cache-dependent premature load
If the target document is not cached: The browsing context first has an empty (bodyless) document. Later task queue tasks build the DOM for destination document into the browsing context. Load event fires after. If the target is cached: Load event fires first. The browsing context has no document when that happens. After window.open returns, the browsing context already has the DOM of the target document in it.
Cache-dependent no load
If the target document is not cached: The browsing context first has an empty (bodyless) document. Later task queue tasks build the DOM for destination document into the browsing context. Load event fires after. If the target is cached: After window.open returns, the browsing context already has the DOM of the target document in it. No load event fires.
Racy
Most often the same behavior as “Sync”. Other times like “Empty plus async”.
iframe about:blank iframe other URL window.open about:blank into tab window.open other URL into tab window.open about:blank into window window.open other into URL window
Firefox 4 Sync plus single-task Sync plus async other Sync plus single-task Sync plus async other Sync plus single-task Sync plus async other
Chrome 10 Sync Sync plus async other Sync Sync plus async other
Safari 5 Sync Empty plus async Sync Empty plus async Sync Empty plus async
Opera 11 Sync Sync plus async other Sync Sync plus async other no load Sync Sync plus async other no load
IE6 Empty plus async Empty plus async Racy Empty plus async
IE9 Empty plus async Empty plus async Sync Cache-dependent premature load Racy Cache-dependent no load

I hope this research can be used for assessing whether the current HTML5 draft makes sense on this topic. Even though the behavior “Sync” seems to be prevalent in the table, I’m rather worried about ever making the load event fire synchronously, so I’m hoping we don’t end up having to do that.

My own judgment is leaning towards the following:

  • When loading any URL in a window.open-created browsing context, initially create the DOM of about:blank there synchronously, since all browsers seem to do roughly that.

  • Since synchronous events are bad and Firefox gets away with not firing load synchronously for about:blank, never fire the load event synchronously.

  • Fire a load event asynchronously for the document that is the destination of the navigation.

  • If about:blank is the destination of navigation for window.open, use the initial synchronously-created DOM without overwriting it.

  • If about:blank is the destination of navigation for an iframe create the DOM synchronously ASAP as with window.open.

I am not sure what to think of the case where about:blank is not the initial destination of navigation for an iframe. Creating a synchronous placeholder about:blank DOM would make the browsing context code the same as in the window.open case and would provide an early document.body that scripts could accidentally poke without poking null. On the other hand, setting up such a DOM first and then letting the DOM be blown away by a later network task means that the presence of element nodes in the DOM would be racy relative to the network and to script getting appended to the DOM in the same parser task that appended the iframe. In that sense, the IE/Safari behavior would be nicer.