html5shiv
html5shiv copied to clipboard
Documentation
Hey there,
I’ve been following the development of HTML5 shiv, shimprove, innerShiv, IEPP etc. right from the beginning but stopped when jQuery integrated the innerShiv. Since we had problems with jQuery’s approach, today I tried to catch up and dive into the current html5shiv again. I have to admit I found it very hard to get a clue about the project. While html5shiv originally started as a one-liner several years ago, it grew to a complex and sophisticated project.
Compared to the innerShiv, additional checks, caches and exceptions were added. Don’t get me wrong, I do not want to question them, I trust your decisions. I’m sure they are necessary for robustness and performance. I also know the problem itself is complex and the html5shiv is basically a clever but ugly hack. But for me it’s difficult to evaluate this script for production use given there is little explanation of implementation details. It took me long to figure out how the basics of the script works. Sure, I see what it’s doing, but I’m wondering why it’s done like this. A feature list and a good code documentation would definitely help.
Stupid question, but which cases does this script try to cover and which are not covered? There are several code comments which allude to the problems you faced. For example, I saw that some elements are skipped. In practise, var form = document.createElement('form'); form.innerHTML = '<section>…</section>;' won’t work as expected. That’s okay, I’m sure you did this for good reasons. I just would have expected to be informed about that in the README because I would likely run into such issues in production code.
While the original innerShiv is an “unobtrusive” helper function, this project overwrites createElement and createDocumentFragment. I consider myself an experienced JavaScripter, but I cannot estimate the possible consequences. Apparently this has a performance impact you already try to address by caching, loop unrolling etc. Nonetheless I’m wondering whether I really want to overwrite these natives. This seems to solve some problems while introducing new ones. It’s hard to make an informed decision given that there are no in-depth articles about that topic. (Are there any?)
I took me some time to figure out that the original html5shiv which “registers” HTML5 element types via document.createElement (and frag.createElement) is located at the point where createDocumentFragment is overwritten (correct me if I’m wrong). Of course it’s your decision to write dense and highly-optimized code. I know this is jdalton’s performance optimization style as seen on lodash, for example. This is great for browser engines and end users who just link to the script without having a clue about what it actually does. But this “code obsfuscation” is practically unreadable for other JavaScript devs who need to know what this script is doing under the hood. This conflict could be solved by better code comments and additional documentation, I think.
Regards, Mathias
Of course it’s your decision to write dense and highly-optimized code. I know this is jdalton’s performance optimization style as seen on lodash, for example. This is great for browser engines and end users who just link to the script without having a clue about what it actually does. But this “code obsfuscation” is practically unreadable for other JavaScript devs who need to know what this script is doing under the hood.
OT: It's just templates and it's super documented and constructed in a way so that methods like _.each can be inspected via console.log(_.each).
Compare Underscore's throttle to Lo-Dash's throttle or any of the other 50+ optimized methods (of which only ~16 are compiled) and you'll find that most of the methods are simplified to reduce abstraction and make it easier to follow for other devs who need to know what the script is doing under the hood. In that way I hope to avoid WTF in the code like this gem in Underscore. When is a function value ever falsey? (hint: never)
+1 to everything OP said. This has been a significant concern for us as well.
@jdalton: Good to see the comments were added, they weren’t present when I had looked into the source some weeks ago. That’s the right direction.
Yap +1 for moar documentation.
+1
No need to vote on this. It's quite obvious, we indeed need more documentation. :-)
@molily
Some informations on the upcoming docu. I'm currently working on writing tests to stabilize the API. 'This has to be done, before I can work on the documentation.
With version 3.0 we have added the possibility to shiv different documents. Through our performance optimizations, this feature was busted.
The form.innerHTML thing is now fixed.
About the createElement/createDocumentFragment monkey patch. html5shiv is designed as a drop-in ready to use solution. In most cases everything will work as expected. While we had a lot of trouble at the beginning, it seems that this obtrusive technique is quite robust now. But we have some known unfixable issues with this.
In case you have full control over your JS and you are an experienced developer, my advice is to opt-out from monkey patching createElement and use an unobtrusive approach like innerShiv, where needed. Next version of html5shiv will have a helper to create a shived documentFragment/element without patching the original methods.
That’s great news, thanks, @aFarkas
AFarkas just landed a bunch of awesome documentation the API and its internals: a8a677e Jon also contributed some great stuff. I just added a bit about the relation to other projects especially since you called that out @molily
@jonathantneal re-reading molily's comment about we could probably use a few more code comments, like near the unrolling and why exactly we are overriding the native methods.