How to keep the DOM small - The Discourse Way



  • This morning out of curiosity I had a quick look at the code of a Discourse topic page to see how pagination would be handled... this is what I found:

    <noscript data-path="/t/today-is-friday-the-13th/862/132"> <header class="d-header"> <div class="container"> <div class="contents"> <div class="row"> <div class="title span13"> <a href="/"><img src="//what.thedailywtf.com/uploads/default/1/5c18e037abe588a0.gif" alt="What the Daily WTF?" id="site-logo"></a> </div> </div> </div> </div> </header> <div id="main-outlet" class="container"> <!--​ preload-content: --> <h2> <a href="/t/today-is-friday-the-13th/862">Today is Friday, the 13th</a> </h2> <a href="/category/general">General</a> <hr/> <div class='creator'> <b>hardwaregeek</b> at June 13th, 2014 17:13 — #114 </div> <div class='post'> <p><aside class="quote" data-post="110" data-topic="862"><div class="title"> <div class="quote-controls"></div> <img width="20" height="20" src="/user_avatar/what.thedailywtf.com/faoileag/40/1999.png" class="avatar">faoileag said:</div> <blockquote><p>code that rejects posts that are off-topic</p></blockquote></aside></p>
    ...and a lot more of that.
    

    Yes. All the code for the paginated, non-javascript page is there in the <noscript> tag. Even when Javascript is available.

    I post this as a wtf, because the reason I was given when I was wondering why posts that went out of the viewport were unloaded from the DOM, was that this was done to minimize the memory footprint of the browser .

    So why not unload the <noscript> tag once the page has been loaded? One wonders.



  • Question from the peanut gallery: why is there a data element on the noscript tag? What possible use could there be for that?


  • BINNED

    @Arantor said:

    Question from the peanut gallery: why is there a data element on the noscript tag? What possible use could there be for that?

    It's obvious, isn't it? Since you know which page you're on, you can execute the onload event on the document looking for a <noscript> tag that matches the page URL and unload it from the DOM... waitaminute!

    To be fair, it might, might make some modicum of sense, given different crawler bots for different search engines, it might be a fair assumption that some bots do JS but don't trigger the scroll event properly, so in that case you need a duplicate for them.

    Then again, I'm pretty sure you can deactivate JS in robots.txt by disallowing the assets directories. And if onload triggers some of the posts will be duplicated. And... OK, I give up, WTF?



  • @Arantor said:

    Question from the peanut gallery: why is there a data element on the noscript tag? What possible use could there be for that?

    The front-end javascript doesn't care if the data-path attribute is passed in a noscript tag, the body tag or a div. So the noscript tag will probably just be a mule in this case.



  • Well, the specification for HTML5 data attribute actually states:

    These attributes are not intended for use by software that is independent of the site that uses the attributes.

    As in, no external application should be using the data attribute for anything, which includes search engines. So there's valid reasons for using it but on the noscript makes no sense. Which means it is probably a mule, but of all the elements in the tag soup, they use that one?

    That's practically invoking Alanis Morrisette.


  • Discourse touched me in a no-no place

    @faoileag said:

    So the noscript tag will probably just be a mule in this case

    The tag is a shoe?



  • @faoileag said:

    So why not unload the <noscript> tag once the page has been loaded? One wonders.

    I don't think browsers keep the <noscript> elements in memory if JavaScript is enabled.


  • Discourse touched me in a no-no place

    Just checked with Chrome. It's kept, but as unparsed text (pretty cheap).



  • @Daniel15 said:

    I don't think browsers keep the <noscript> elements in memory if JavaScript is enabled.

    Firefox does as well - I used Firebug to look at the DOM. And yes, the innerHTML is treated as plaintext there as well.


  • Banned

    @faoileag said:

    So why not unload the <noscript> tag once the page has been loaded?

    An oversight, it has very minimal impact compared to the JS object model, nonetheless should be unloaded, its just one line of code to junk it.



  • On a Javascript-enabled browser, <noscript>...</noscript> should add no more overhead to the page than an identical <!-- ... --> would. It's just a single element in the DOM whose contents the browser should ignore.



  • @anotherusername said:

    On a Javascript-enabled browser, <noscript>...</noscript> should add no more overhead to the page than an identical <!-- ... --> would. It's just a single element in the DOM whose contents the browser should ignore.

    Add <noscript>foobar!<b>FOOBAR</b>!barfoo</noscript> to the body of a page.
    Add

    <script>
    jQuery(document).ready(function(){
      var elems = document.getElementsByTagName('noscript');
      var noscriptelem = elems[0];
      console.log('noscriptelem=' + noscriptelem.innerHTML);
    });
    <script>
    

    See what happens.

    I get foobar!<b>FOOBAR</b>!barfoo dumped to the console.

    So no, the browser does not ignore the contents. The contents is not a structure in the DOM, but it is available as plaintext.


  • Discourse touched me in a no-no place

    What do you think the contents of a comment node are?



  • Nothing more. But even plaintext is stored and part of the DOM, that's all I said.



  • Fucking jQuery, man. I shouldn't have to install a framework to use your sample code. What's wrong with DOMContentLoaded or window.onload?

    Anyway, like the next guy said, it's essentially no different than a comment node. It is a node in the DOM, and it has contents, but the browser ignores its contents.

    How is your example any different from this:

    <!--​foobar!<b>FOOBAR</b>!barfoo-->
    <script type="text/javascript">
    document.addEventListener("DOMContentLoaded", function () {
      var elems = [document];
      for (var i = 0; i < elems.length; ++ i) {
        for (var j = 0; j < elems[i].childNodes.length; ++ j) {
          elems.push(elems[i].childNodes[j]);
        }
      }
      var commentNodes = elems.filter(function (elem) {
        return elem.nodeType == elem.COMMENT_NODE;
      });
      var commentNode = commentNodes[0];
      console.log("commentNode=" + commentNode.data);
    });
    </script>
    

    Yeah, it might be a little more trouble to pull a list of comment nodes out of the document than it is to get a list of all the noscript tags, but it works just the same.



  • @anotherusername said:

    Fucking jQuery, man.

    I ❤ jQuery.



  • What you do with jQuery in the privacy of your browser I do not wish to know. Sample code should be plain jane Javascript unless there's some very good reason to do it in jQuery, like if I asked "how do you do x in jQuery". Then you'd use jQuery.





  • And this is one of the reasons I despise StackOverflow. Almost any JavaScript problem will, at some point, acquire 'just do it in jQuery' as an answer even if it is totally the wrong answer for the question.


  • Banned

    @Arantor said:

    'just do it in jQuery'



  • Precisely my point. That's the sort of reason that I detest SO. I don't, however, carry @morbiuswilters' level of vitriolic hate though.


  • Banned

    Its really not that bad usually, this is an outlier pathological issue they had. Still very amusing / troubling.



  • Having a bunch of great tools doesn't mean that an idiot will know which one to use.


  • ♿ (Parody)

    That's what happens when you let people post stuff on your site.


  • Discourse touched me in a no-no place

    You should totally use jQuery to figure that out. Bing for “jQuery tool location plugin”…



  • Every topic on this site is technically "Meta"


  • Discourse touched me in a no-no place

    Except for Meta which is Parameta.

    (Hmm, that doesn't come out quite how I wanted…)



  • I understand your argumeta.



  • Isn't it more sort of metameta by now?


  • Banned

    This is now fixed FYI

    To be deployed soon:



  • fishnipples?



  • @TwelveBaud said:

    fishnipples

    Where can I request a new emoji?


Log in to reply