Why is document.write considered a “bad practice”?

Why is document.write considered a “bad practice”?

I know document.write is considered bad practice; and I’m hoping to compile a list of reasons to submit to a 3rd party vendor as to why they shouldn’t use document.write in implementations of their analytics code.
Please include your reason for claiming document.write as a bad practice below.

Solutions/Answers:

Solution 1:

A few of the more serious problems:

  • document.write (henceforth DW) does not work in XHTML

  • DW does not directly modify the DOM, preventing further manipulation (trying to find evidence of this, but it’s at best situational)

  • DW executed after the page has finished loading will overwrite the page, or write a new page, or not work

  • DW executes where encountered: it cannot inject at a given node point

  • DW is effectively writing serialised text which is not the way the DOM works conceptually, and is an easy way to create bugs (.innerHTML has the same problem)

Far better to use the safe and DOM friendly DOM manipulation methods

Solution 2:

There’s actually nothing wrong with document.write, per se. The problem is that it’s really easy to misuse it. Grossly, even.

In terms of vendors supplying analytics code (like Google Analytics) it’s actually the easiest way for them to distribute such snippets

  1. It keeps the scripts small
  2. They don’t have to worry about overriding already established onload events or including the necessary abstraction to add onload events safely
  3. It’s extremely compatible

As long as you don’t try to use it after the document has loaded, document.write is not inherently evil, in my humble opinion.

Solution 3:

Another legitimate use of document.write comes from the HTML5 Boilerplate index.html example.

<!-- Grab Google CDN's jQuery, with a protocol relative URL; fall back to local if offline -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/libs/jquery-1.6.3.min.js"><\/script>')</script>

I’ve also seen the same technique for using the json2.js JSON parse/stringify polyfill (needed by IE7 and below).

<script>window.JSON || document.write('<script src="json2.js"><\/script>')</script>

Solution 4:

It can block your page

document.write only works while the page is loading; If you call it after the page is done loading, it will overwrite the whole page.

This effectively means you have to call it from an inline script block – And that will prevent the browser from processing parts of the page that follow. Scripts and Images will not be downloaded until the writing block is finished.

Solution 5:

Pro:

  • It’s the easiest way to embed inline content from an external (to your host/domain) script.
  • You can overwrite the entire content in a frame/iframe. I used to use this technique a lot for menu/navigation pieces before more modern Ajax techniques were widely available (1998-2002).

Con:

  • It serializes the rendering engine to pause until said external script is loaded, which could take much longer than an internal script.
  • It is usually used in such a way that the script is placed within the content, which is considered bad-form.

Solution 6:

Here’s my twopence worth, in general you shouldn’t use document.write for heavy lifting, but there is one instance where it is definitely useful:

http://www.quirksmode.org/blog/archives/2005/06/three_javascrip_1.html

I discovered this recently trying to create an AJAX slider gallery. I created two nested divs, and applied width/height and overflow: hidden to the outer <div> with JS. This was so that in the event that the browser had JS disabled, the div would float to accommodate the images in the gallery – some nice graceful degradation.

Thing is, as with the article above, this JS hijacking of the CSS didn’t kick in until the page had loaded, causing a momentary flash as the div was loaded. So I needed to write a CSS rule, or include a sheet, as the page loaded.

Obviously, this won’t work in XHTML, but since XHTML appears to be something of a dead duck (and renders as tag soup in IE) it might be worth re-evaluating your choice of DOCTYPE…