Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allowing cases where document.write is "ok" #18

Open
jakearchibald opened this issue Jan 31, 2019 · 9 comments
Open

Allowing cases where document.write is "ok" #18

jakearchibald opened this issue Jan 31, 2019 · 9 comments

Comments

@jakearchibald
Copy link

Ok ok, hear me out.

I'm assuming we're allowing developers to block document.write because injecting into the browser's streaming parser is a slow path, and can break things like look-ahead parsing.

https://jakearchibald.com/2016/fun-hacks-faster-content/ - here I use document.write in an about:blank iframe to hook into the streaming parser, but I'm pretty sure it doesn't negatively impact the parent page.

Maybe document.write should be allowed if document.open() is called either explicitly or implicitly during the life of the document. In spec terms, I think this means document.write should be allowed if the document open steps have run for this document.

@triblondon
Copy link

Perhaps it might be simpler in cases like this to just allow the document-write policy on the relevant origin.

@foolip
Copy link
Member

foolip commented May 22, 2019

I came here to file this issue, but I'd like to go further. Probably the most problematic aspect is the ability to document.write(<script src=script.js>)... which is parser-blocking and thus blocks the main thread on the fetch of script.js, much like sync XHR. https://wpt.fyi/results/html/webappapis/dynamic-markup-insertion/document-write/script_007.html is a simple demonstration of this.

https://developers.google.com/web/updates/2016/08/removing-document-write describes an intervention of parser-blocking scripts when a lot of conditions are met.

Should we have a policy for only the parser-blocking behavior of document.write?

@jakearchibald
Copy link
Author

That's what I was trying to define with:

Maybe document.write should be allowed if document.open() is called either explicitly or implicitly during the life of the document. In spec terms, I think this means document.write should be allowed if the document open steps have run for this document.

@foolip
Copy link
Member

foolip commented May 23, 2019

@jakearchibald I see, glad to hear you were also shooting for the same thing!

Trying to figure out what the most surgical restriction of bad document.write behavior would be I came across sync-script which is a policy for parser-blocking scripts.

If that policy also applies to document.write-added scripts, which I presume it does, then are there any remaining performance issues with document.write?

and thus blocks the main thread on the fetch of script.js, much like sync XHR

I made a mistake here, these scripts block the parser, but the document.write call returns before the script is fetched and timers still run, so it's not blocking the main thread, but is blocking important events. (Demo: https://software.hixie.ch/utilities/js/live-dom-viewer/saved/6940)

@foolip
Copy link
Member

foolip commented May 23, 2019

@clelland, looking at https://github.com/w3c/webappsec-feature-policy/blob/master/policies/document-write.md, I wonder if some of that isn't more about sync-script than document-write. It says:

anti-pattern, parser-blocking JavaScript API

However, is the parser-blocking behavior not covered by sync-script? Is there a problem with document.write in addition to that?

@Jamesernator
Copy link

Isn't one of the pros of Feature-Policy so that browsers can not even bother loading chunks of their engine when they see features aren't needed? And hence speed up performance of sites they know aren't using certain features.

This feels like that would defeat that, given engines would need to load it anyway as a call to document.open could still occur at any time.

I think it would be a way better idea to investigate solutions to the use cases of document.write and create a new API that solves them instead of weakening Feature-Policy.

@jakearchibald
Copy link
Author

Isn't one of the pros of Feature-Policy so that browsers can not even bother loading chunks of their engine when they see features aren't needed?

I don't know if that's the case here.

I think it would be a way better idea to investigate solutions to the use cases of document.write and create a new API that solves them instead of weakening Feature-Policy.

That's reasonable, but the new thing should be in place before the deprecation of the old thing.

@Jamesernator
Copy link

I don't know if that's the case here.

I can't imagine much by itself (although there seems to be interest in getting rid of it), however combined with other policies (e.g. sync-script/sync-xhr) I can imagine whole parts of the HTML parsing algorithm might be able to be turned off.

but the new thing should be in place before the deprecation of the old thing.

It's not clear to me if document.write is deprecated proper or not, nevertheless Feature-Policy is an opt-in mechanism, if you want to use document.write just don't include document-write 'none' in your Feature-Policy (or specify the domains allowed).

@foolip
Copy link
Member

foolip commented Jun 17, 2019

Basically what document.write does is to add text to the input stream of the parser just as if it had arrived on the network (and been decoded) so knowing it won't be called unfortunately wouldn't allow much simplification.

Given enough knowledge of unreachable code it's possible certain fast paths could be enabled, but I don't know that anyone has given this much thought.

@clelland clelland transferred this issue from w3c/webappsec-permissions-policy Dec 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants