5 ms·
Whilst the spec certainly allows you to ignore closing of a whole range of elements, it's not necessarily the wisest of choices to make. The parser does actuall
by shakna 4y ago
Whilst the spec certainly allows you to ignore closing of a whole range of elements, it's not necessarily the wisest of choices to make. The parser does actually get slower when you fail to close your tags in my experience.
Unscientific stats from a recent project where I noticed it:
+ Document is about 50,000 words in size. About 150 words to a paragraph element, on average.
+ Converting the entire thing to self-closing p elements added an overhead of about 120ms in Firefox on Linux, before initial render.
+ Converting the entire thing to self-closing p elements added an overhead of about 480ms in Chrome on Linux, before initial render.
+ Converting the entire thing to self-closing p elements added an overhead of about 400ms in Firefox on Android, before initial render.
+ Converting the entire thing to self-closing p elements added an overhead of about 560ms in Chrome on Android, before initial render.
+ The time differences appeared to be linearly increasing, as the document grew from 20,000 to 50,000 words.
+ Curiously, Quirks Mode also increased the load times by about 250ms on Firefox and 150ms on Chrome. (Tried it just because I was surprised at the massive overhead of removing/adding the tag endings.)
The most common place this was going to be opened was Chrome on Android, and a whopping half-second slower to first render is going to be noticeable to the end user. For some prettier mark up.
Whilst you can debate whether that increased latency actually affects the user, a decreased latency will always make people smile more. So including the end tags is a no-brainer. Feel free to write it without them - but you _might_ consider whether your target is appropriate for you to generate them before you serve up the content.
- toqy 4y ago> For some prettier mark up. But then if you run it through Prettier it'll add all the closing tags for you :)
- throwaway894345 4y agoIf you’re running it through a processor, why it just write markdown and call it a day?
- hombre_fatal 4y agoWell, one simply formats the source file as you write it. The other requires a infile -> outfile build step that's more complex. Whether the latter is worth it tends to depend on other things than parse time.
- throwaway894345 4y agoWhy would I care if one is merely “formatting” or not? If I have to run a tool either way, I would prefer one that accepts a user-friendly input language and decouples content from presentation.
- anjbe 4y agoHow does Markdown decouple content from presentation?
- throwaway894345 4y agoYou typically write your content in markdown and merge it with HTML templates and CSS.
- hombre_fatal 4y agoBecause transforming an .md file into an .html file is a lot more invasive (though taken for granted here I think) than just writing the .html file. It's a build step where there wasn't one before. I'm not saying it's never worth it.
- galaxyLogic 4y agoIs there a standard definition for the "Markdown" -language? There are several for HTML different versions and it is standardized that you can omit some closing tags and some tags altogether. The benefit of writing in a standardized language is that later you or anybody can run tools against your sources that check for conformity. So that is why I prefer HTML. But I would like to hear your opinion on what is the best mark-down dialect currently?
- deleted 4y ago[deleted]
- jokoon 4y agoAre more strict html parsers/renderers, and aren't they faster?
- hombre_fatal 4y agoLenient parsers still benefit from strict input because it lets them avoid lookaround/backtracking.
- vbezhenar 4y agoWhat do you mean by lookaround/backtracking? You're inside <p>. You encounter another <p>. You can't nest one <p> inside another <p>, so you close current <p> and open new <p>. That's about it. I fail to see where do you need any kind of backtracking.
- hombre_fatal 4y agoWell, even in this one example, imagine parser combinators which often mean backtracking the inner <p> so that you can commit to the `openTag('p')` parser. Or your logic may be 'consume all tags that aren't <p>` which is a lookahead. A better example here is whether you are lenient and accept unescaped html entities like "<" vs "<". If you require it to be escaped "<" or if all entities in your inputs are always escaped, then your text parser never has to backtrack. But if you are lenient, your text parser can do catastrophic levels of backtracking if there is a single "<" somewhere (unless you are careful). Imagine input that starts off "<a small mouse once said". If could be quite a while before your parser knows it's not an anchor open tag.
- shakna 4y ago> Are more strict html parsers/renderers, and aren't they faster? Are what more strict? You're missing a subject there. At a guess, you're referencing the differences between Chrome/Firefox rendering times? And are surprised that Chrome is always slower? In the same completely unscientific stat taking, I found that Chrome was significantly faster at parsing the HTML head element of a document than Firefox, and that difference was enough for Chrome to pull ahead of Firefox in overall rendering times for smaller pages. (Chrome was about 30% of Firefox's time spent in the head.) However, Firefox was faster at parsing the body, and as I had a larger-than-usual body (50k words is not your average webpage), Firefox was overall faster.
- myfonj 4y agoWell this sounds like really interesting observation. May I ask where exactly were the original closing tags located and how the stripped source looked like? I can imagine there _might_ be some differences among differently formatted code: e.g. I'd expect <p>Content<p>Content[EOF fig1] to be (slightly) slower, than <p>Content</p><p>Content</p>[EOF fig2] (most likely because of some "backtracking" when hitting `<p[>]`), or <p>Content</p> <p>Content</p>[EOF fig3] (with that that small insignificant `\n` text node between paragraph nodes), what should be possibly faster than "the worst scenarios": <p>Content <p>Content[EOF fig4a] or even <p> Content <p> Content [EOF fig4b] with paragraph text nodes `["Content\n","Content]"` / `["\nContent\n","\nContent\n]"`, where the "\n" must be also preserved in the DOM but due white-space collapsing rules not present in the render tree (if not overridden by some non-default CSS) but still with backtracking, that <p>Content </p> <p>Content </p>[EOF fig5] should eliminate (again, similarly to fig2 vs fig1). (Sorry for wildly biased guesswork, worthless without measurements.)
- shakna 4y agoIt was just paragraphs of text. p, strong, em, and q mingled at most. No figures or images or anything of the like to radically shift DOM computations. That the effect can even be seen is probably due to the scale of the document, as I noted it's a little larger than most things. All paragraphs had a blank line between them, both with and without the p end tag. The p opening tag was always at the top-left, with no gap between it and the content. So, for example: <p>Cheats open the doorway for casual play. They make it easier for disabled players to enjoy the same things as their peers, and allow people to skip parts of a game that <em>they bought</em> that they find too difficult.</p> <p>Unfortunately, cheats are going away, because of extensive online play, and a more corporate approach to developing games that despises anything hidden.</p> Versus: <p>Cheats open the doorway for casual play. They make it easier for disabled players to enjoy the same things as their peers, and allow people to skip parts of a game that <em>they bought</em> that they find too difficult. <p>Unfortunately, cheats are going away, because of extensive online play, and a more corporate approach to developing games that despises anything hidden. (You can also discount CSS from having a major effect. Less than a hundred lines of styles, where most rules are no more complicated than: `p { font-family: sans-serif; }`. No whitespace rules.) However, if you wanted to look at this in a more scientific way - it should be entirely possible to generate test cases fairly easily, given the simplicity of the text data I saw my results with.
- niconii 4y agoI can't verify your numbers. As far as I can tell, loading a ~900,000 word document with no other differences than including or excluding </p> has about the same load time, though there's too much variance from load to load for me to really give definitive numbers. Are you sure you converted it properly? I'd expect those kinds of numbers if your elements were very deeply nested by mistake (e.g. omitting tags where it's not valid to do so), but I don't see why leaving out </p> should be so slow. Try these two pages: https://niconii.github.io/lorem-unclosed.html https://niconii.github.io/lorem-unclosed.html https://niconii.github.io/lorem-closed.html https://niconii.github.io/lorem-closed.html
- shakna 4y agoFor five runs, on the same hardware with the same load: + Unclosed: 4.00s, 3.91s, 3.59s, 4.45s, 3.93s + Closed: 3.90s, 2.74s, 3.9s, 2.05s, 3.39s Though I'd note that the newline you have immediately following the paragraph, even when closing, would probably reduce the backtracking effect. And having no explicit body or head element would probably cause some different rendering patterns as well.
- niconii 4y agoWere the five unclosed runs before the five closed runs? I could see that making a difference vs. interleaving them, if the hardware needs to "warm up" first. For me, on Firefox on Linux (I know it's the one with the smallest difference, but I don't have the others on hand, sorry), using the "load" time at the bottom of the Network tab, with cache disabled and refreshing with Ctrl+F5, interleaving the tests: - Unclosed: 1.38s, 1.49s, 1.45s, 1.52s, 1.48s - Closed: 1.47s, 1.37s, 1.48s, 1.49s, 1.35s The one with </p> omitted takes about 0.032s longer on average going by these numbers, but that's about 2 frames of extra latency for a page almost twice the length of The Lord of the Rings. Regarding the page itself, I tried to keep everything else as identical between the two versions as possible, including the DOM, hence why I wrote the </p> immediately before each <p>. As for backtracking, I'm not sure what you mean. The rule for the parser is simply "If the start tag is one from this list, and there's an open <p> element on the stack, close the <p> element before handling the start tag."
- 4y ago
- hsbauauvhabzb 4y agoThat’s interesting, but surely relying on user agent to ‘fill in the gaps’ is error prone? Surely transpiling prior or during render would be more resilient than trusting browser behaviour
- lolinder 4y agoIf you're in a situation where resilience against odd browser quirks matters, you probably shouldn't be writing HTML like this anyway. This style is fine for writing HTML for a blog. For any kind of application, it would be a nightmare to try to maintain. Every time the author introduced a shorthand, they had to clarify that it works only in specific situations. The result of those qualifiers is that you will have to have some code written in the more verbose style anyway. Context switching between those styles and having to decide whether the shorthand works in any given case just isn't worth it on a large project that you'll be making changes to over time.
- chrismorgan 4y agoHTML parsing is exhaustively defined, so there’s not any filling of gaps, but only rules to be aware of. If you don’t know those rules, this may be error-prone, but if you do, it’s not, and things like the start and end tag omissions discussed in the article are quite straightforward rules to learn.