#58 Declined
Repository
macfreek macfreek
Branch
default
Repository
birkenfeld birkenfeld
Branch
default

Local search support for Chrome.

Author
  1. macfreek avatarmacfreek
Reviewers
Description

This fixes issues #505, #723, and #782

Comments (5)

  1. Georg Brandl repo owner

    There was an argument against this way of doing it, if I could remember it...

    Maybe the page load will block until the whole searchindex is retrieved? It can be quite big for large projects like CPython...

  2. macfreek author

    That seems a possible and valid reason. Some measurements confirms this (all measurements have been done 7 times and averaged):

    I compare the following times:

    • Download times for searchindex.js
    • Time when DOMContentLoaded is triggered
    • Time when page onload() event is fired
    • Total time to download the webpage

    Either before and after the proposed patch.

    For these scenario's (Edit: for searching "Exception" in the Python 3.2 documention):

    • Pages are online, not cached
    • Pages are online, but pages are cached by webbrowser
    • Pages are offline (local copy)

    Scenario: Pages are online, not cached

                       searchindex.js     DOMContentLoaded   onload() event     Total load time
    JQuery inclusion:   830 ± 160 ms       910 ± 370 ms       950 ± 400 ms      2450 ± 400 ms
    HTML inclusion:     970 ± 240 ms      1570 ± 260 ms      1640 ± 250 ms      2430 ± 280 ms
    

    Scenario: Pages are online, but pages are cached by webbrowser

                       searchindex.js     DOMContentLoaded   onload() event     Total load time
    JQuery inclusion:    74 ± 40 ms        550 ± 130 ms       710 ± 190 ms      1450 ±  90 ms
    HTML inclusion:     160 ± 90 ms        900 ± 170 ms       970 ± 180 ms      1630 ± 200 ms
    

    Scenario: Pages are offline (local copy)

                       searchindex.js     DOMContentLoaded   onload() event     Total load time
    JQuery inclusion:    96 ± 23 ms *      152 ±  6 ms *      165 ±  8 ms *     1160 ± 30 ms *
    HTML inclusion:      95 ± 17 ms        440 ± 30 ms        460 ± 40 ms       1190 ± 40 ms
    

    So the page load time of searchindex.js, and the total time before the whole page is rendered is the same. But the parsing of searchindex.js happens at a later stage, so that the page onload() event occurs significantly (300-600 ms) earlier.

    (The results marked with a star * are those which do not load at all in the Chrome browser.)

    I would say that the ideal solution would be to detect a failed load of JQuery, and in that case, include the page with HTML. However, I have no clue if this is possible: including the HTML fragment with Javascript may also be subject to the same-origin-policy restriction in Chrome. I haven't tried that yet.

  3. macfreek author

    Good news: it is possible to create a script-tag in Javascript which is not subject to the same-origin-policy.

    Here is how:

    <script id="searchindexloader" type="text/javascript"></script>
    <script type="text/javascript">
      var sil = document.getElementById("searchindexloader");
      sil.src = "searchindex.js";;
    </script>
    

    This is plain JavsScript; Likely there are similar ways to achieve this with jQuery too. (I haven't found them yet, as I'm not a jQuery expert). At least this works, and has the important benefit that it works on all browsers. I strongly recommend to use this method, at least as a fail-over method.

    The timing of this fail-over method is actually somewhere between the current jQuery method and the plain HTML inclusion method:

                       searchindex.js     DOMContentLoaded   onload() event     Total load time
    JQuery inclusion:    96 ± 23 ms *      152 ±  6 ms *      165 ±  8 ms *     1160 ± 30 ms *
    HTML inclusion:      95 ± 17 ms        440 ± 30 ms        460 ± 40 ms       1190 ± 40 ms
    Proposed solution:   28 ±  5 ms        149 ±  8 ms        470 ± 60 ms       1250 ± 160 ms
    

    As you can see the page renders soon (the DOMContentLoaded time) while the building of the search result list starts later (the onload() event time). The total page load time is not affected.

    If you think the time is good enough, feel free to use the above code. If you prefer the jQuery method, I strongly suggest to use this method as a fail-over, so that the code does also work in Chrome. Here is how:

    <script id="searchindexloader" type="text/javascript"></script>
    <script type="text/javascript">
      var url = "searchindex.js";
      $.ajax({type: "GET", url: url, data: null, 
            dataType: "script", cache: true,
            success: function(data, textStatus, jqXHR) {
              if (jqXHR.status == 0) {
                var sil = document.getElementById("searchindexloader");
                sil.src = url;
              }
            },
            error: function(jqXHR, textStatus, errorThrown) {
              var sil = document.getElementById("searchindexloader");
              sil.src = url;
            }
      });
    </script>
    

    (For some reason, the success function was called, despite that the URL failed to load. I added the fail-over method also to the error function, since I'm not sure if the behaviour has changed in jQuery 1.5 -- the source I used for testing still had jQuery 1.4, and I know there have been some changes to these error functions in jQuery 1.5.).

    Thanks for listening, and let me know what method you prefer, in case you like me to prepare an actual patch. (I'm sure a better programmer than I am can find a way to make this work with jQuery, perhaps even without the empty HTML script tag.)

    Happy 2013!

Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.