authorgravatar for pierre@jow.frPierre Guilleminot <pierre@jow.fr> 2020-04-12 23:13:57+02:00
committergravatar for pierre@jow.frPierre Guilleminot <pierre@jow.fr> 2020-04-12 23:13:57+02:00
logf76d59ef761746a3ea73aa9296dec146672d1dc2
tree93bfc7cba6d6323233e0dc5816a9c768b261a7c6
parent8e9e126d41cbca619a2a4658fb38d10120388e8f

improve search perf: batching dom list mutations


1 files changed, 65 insertions(+), 53 deletions(-)

lib/std/special/docs/main.js+65-53
...@@ -256,13 +256,15 @@...@@ -256,13 +256,15 @@
256 if (fnObj.combined === undefined) fnObj.combined = allCompTimeFnCallsResult(calls);256 if (fnObj.combined === undefined) fnObj.combined = allCompTimeFnCallsResult(calls);
257 if (fnObj.combined != null) renderContainer(fnObj.combined);257 if (fnObj.combined != null) renderContainer(fnObj.combined);
258258
259 resizeDomList(domListFnExamples, calls.length, '<li></li>');259 var domListFnExamplesFragment = createDomListFragment(calls.length, '<li></li>');
260260
261 for (var callI = 0; callI < calls.length; callI += 1) {261 for (var callI = 0; callI < calls.length; callI += 1) {
262 var liDom = domListFnExamples.children[callI];262 var liDom = domListFnExamplesFragment.children[callI];
263 liDom.innerHTML = getCallHtml(fnDecl, calls[callI]);263 liDom.innerHTML = getCallHtml(fnDecl, calls[callI]);
264 }264 }
265265
266 domListFnExamples.innerHTML = "";
267 domListFnExamples.appendChild(domListFnExamplesFragment);
266 domFnExamples.classList.remove("hidden");268 domFnExamples.classList.remove("hidden");
267 } else if (instantiations != null) {269 } else if (instantiations != null) {
268 // TODO270 // TODO
...@@ -303,7 +305,7 @@...@@ -303,7 +305,7 @@
303 return;305 return;
304 }306 }
305307
306 resizeDomList(domListParams, docCount, '<div></div>');308 var domListParamsFragment = createDomListFragment(docCount, '<div></div>');
307 var domIndex = 0;309 var domIndex = 0;
308310
309 for (var i = 0; i < fields.length; i += 1) {311 for (var i = 0; i < fields.length; i += 1) {
...@@ -312,7 +314,7 @@...@@ -312,7 +314,7 @@
312 if (fieldNode.docs == null) {314 if (fieldNode.docs == null) {
313 continue;315 continue;
314 }316 }
315 var divDom = domListParams.children[domIndex];317 var divDom = domListParamsFragment.children[domIndex];
316 domIndex += 1;318 domIndex += 1;
317 var argTypeIndex = typeObj.args[i];319 var argTypeIndex = typeObj.args[i];
318320
...@@ -333,12 +335,15 @@...@@ -333,12 +335,15 @@
333 }335 }
334 divDom.innerHTML = html;336 divDom.innerHTML = html;
335 }337 }
338
339 domListParams.innerHTML = "";
340 domListParams.appendChild(domListParamsFragment);
336 domSectParams.classList.remove("hidden");341 domSectParams.classList.remove("hidden");
337 }342 }
338343
339 function renderNav() {344 function renderNav() {
340 var len = curNav.pkgNames.length + curNav.declNames.length;345 var len = curNav.pkgNames.length + curNav.declNames.length;
341 resizeDomList(domListNav, len, '<li><a href="#"></a></li>');346 var domListNavFragment = createDomListFragment(len, '<li><a href="#"></a></li>');
342 var list = [];347 var list = [];
343 var hrefPkgNames = [];348 var hrefPkgNames = [];
344 var hrefDeclNames = [];349 var hrefDeclNames = [];
...@@ -358,7 +363,7 @@...@@ -358,7 +363,7 @@
358 }363 }
359364
360 for (var i = 0; i < list.length; i += 1) {365 for (var i = 0; i < list.length; i += 1) {
361 var liDom = domListNav.children[i];366 var liDom = domListNavFragment.children[i];
362 var aDom = liDom.children[0];367 var aDom = liDom.children[0];
363 aDom.textContent = list[i].name;368 aDom.textContent = list[i].name;
364 aDom.setAttribute('href', list[i].link);369 aDom.setAttribute('href', list[i].link);
...@@ -369,6 +374,8 @@...@@ -369,6 +374,8 @@
369 }374 }
370 }375 }
371376
377 domListNav.innerHTML = "";
378 domListNav.appendChild(domListNavFragment);
372 domSectNav.classList.remove("hidden");379 domSectNav.classList.remove("hidden");
373 }380 }
374381
...@@ -401,9 +408,9 @@...@@ -401,9 +408,9 @@
401 });408 });
402409
403 if (list.length !== 0) {410 if (list.length !== 0) {
404 resizeDomList(domListPkgs, list.length, '<li><a href="#"></a></li>');411 var domListPkgsFragment = createDomListFragment(list.length, '<li><a href="#"></a></li>');
405 for (var i = 0; i < list.length; i += 1) {412 for (var i = 0; i < list.length; i += 1) {
406 var liDom = domListPkgs.children[i];413 var liDom = domListPkgsFragment.children[i];
407 var aDom = liDom.children[0];414 var aDom = liDom.children[0];
408 aDom.textContent = list[i].name;415 aDom.textContent = list[i].name;
409 aDom.setAttribute('href', navLinkPkg(list[i].pkg));416 aDom.setAttribute('href', navLinkPkg(list[i].pkg));
...@@ -414,6 +421,8 @@...@@ -414,6 +421,8 @@
414 }421 }
415 }422 }
416423
424 domListPkgs.innerHTML = "";
425 domListPkgs.appendChild(domListPkgsFragment);
417 domSectPkgs.classList.remove("hidden");426 domSectPkgs.classList.remove("hidden");
418 }427 }
419 }428 }
...@@ -454,29 +463,14 @@...@@ -454,29 +463,14 @@
454 return navLink(curNav.pkgNames, declNamesCopy);463 return navLink(curNav.pkgNames, declNamesCopy);
455 }464 }
456465
457 function resizeDomListDl(dlDom, desiredLen) {466 function createDomListFragment(desiredLen, templateHtml) {
458 // add the missing dom entries467 var templateHtmlContent = "";
459 var i, ev;468 for (var i = 0; i < desiredLen; i++) {
460 for (i = dlDom.childElementCount / 2; i < desiredLen; i += 1) {469 templateHtmlContent += templateHtml;
461 dlDom.insertAdjacentHTML('beforeend', '<dt></dt><dd></dd>');
462 }
463 // remove extra dom entries
464 while (desiredLen < dlDom.childElementCount / 2) {
465 dlDom.removeChild(dlDom.lastChild);
466 dlDom.removeChild(dlDom.lastChild);
467 }
468 }
469
470 function resizeDomList(listDom, desiredLen, templateHtml) {
471 // add the missing dom entries
472 var i, ev;
473 for (i = listDom.childElementCount; i < desiredLen; i += 1) {
474 listDom.insertAdjacentHTML('beforeend', templateHtml);
475 }
476 // remove extra dom entries
477 while (desiredLen < listDom.childElementCount) {
478 listDom.removeChild(listDom.lastChild);
479 }470 }
471 var domTemplate = document.createElement("template");
472 domTemplate.innerHTML = templateHtmlContent;
473 return domTemplate.content;
480 }474 }
481475
482 function typeIndexName(typeIndex, wantHtml, wantLink, fnDecl, linkFnNameDecl) {476 function typeIndexName(typeIndex, wantHtml, wantLink, fnDecl, linkFnNameDecl) {
...@@ -831,10 +825,10 @@...@@ -831,10 +825,10 @@
831 return operatorCompare(a.err.name.toLowerCase(), b.err.name.toLowerCase());825 return operatorCompare(a.err.name.toLowerCase(), b.err.name.toLowerCase());
832 });826 });
833827
834 resizeDomListDl(domListFnErrors, errorList.length);828 var domListFnErrorsFragment = createDomListFragment(errorList.length, "<dt></dt><dd></dd>");
835 for (var i = 0; i < errorList.length; i += 1) {829 for (var i = 0; i < errorList.length; i += 1) {
836 var nameTdDom = domListFnErrors.children[i * 2 + 0];830 var nameTdDom = domListFnErrorsFragment.children[i * 2 + 0];
837 var descTdDom = domListFnErrors.children[i * 2 + 1];831 var descTdDom = domListFnErrorsFragment.children[i * 2 + 1];
838 nameTdDom.textContent = errorList[i].err.name;832 nameTdDom.textContent = errorList[i].err.name;
839 var docs = errorList[i].docs;833 var docs = errorList[i].docs;
840 if (docs != null) {834 if (docs != null) {
...@@ -843,6 +837,8 @@...@@ -843,6 +837,8 @@
843 descTdDom.textContent = "";837 descTdDom.textContent = "";
844 }838 }
845 }839 }
840 domListFnErrors.innerHTML = "";
841 domListFnErrors.appendChild(domListFnErrorsFragment);
846 domTableFnErrors.classList.remove("hidden");842 domTableFnErrors.classList.remove("hidden");
847 }843 }
848 domSectFnErrors.classList.remove("hidden");844 domSectFnErrors.classList.remove("hidden");
...@@ -1022,45 +1018,51 @@...@@ -1022,45 +1018,51 @@
1022 }1018 }
10231019
1024 if (typesList.length !== 0) {1020 if (typesList.length !== 0) {
1025 resizeDomList(domListTypes, typesList.length, '<li><a href="#"></a></li>');1021 var domListTypesFragment = createDomListFragment(typesList.length, '<li><a href="#"></a></li>');
1026 for (var i = 0; i < typesList.length; i += 1) {1022 for (var i = 0; i < typesList.length; i += 1) {
1027 var liDom = domListTypes.children[i];1023 var liDom = domListTypesFragment.children[i];
1028 var aDom = liDom.children[0];1024 var aDom = liDom.children[0];
1029 var decl = typesList[i];1025 var decl = typesList[i];
1030 aDom.textContent = decl.name;1026 aDom.textContent = decl.name;
1031 aDom.setAttribute('href', navLinkDecl(decl.name));1027 aDom.setAttribute('href', navLinkDecl(decl.name));
1032 }1028 }
1029 domListTypes.innerHTML = "";
1030 domListTypes.appendChild(domListTypesFragment);
1033 domSectTypes.classList.remove("hidden");1031 domSectTypes.classList.remove("hidden");
1034 }1032 }
1035 if (namespacesList.length !== 0) {1033 if (namespacesList.length !== 0) {
1036 resizeDomList(domListNamespaces, namespacesList.length, '<li><a href="#"></a></li>');1034 var domListNamespacesFragment = createDomListFragment(namespacesList.length, '<li><a href="#"></a></li>');
1037 for (var i = 0; i < namespacesList.length; i += 1) {1035 for (var i = 0; i < namespacesList.length; i += 1) {
1038 var liDom = domListNamespaces.children[i];1036 var liDom = domListNamespacesFragment.children[i];
1039 var aDom = liDom.children[0];1037 var aDom = liDom.children[0];
1040 var decl = namespacesList[i];1038 var decl = namespacesList[i];
1041 aDom.textContent = decl.name;1039 aDom.textContent = decl.name;
1042 aDom.setAttribute('href', navLinkDecl(decl.name));1040 aDom.setAttribute('href', navLinkDecl(decl.name));
1043 }1041 }
1042 domListNamespaces.innerHTML = "";
1043 domListNamespaces.appendChild(domListNamespacesFragment);
1044 domSectNamespaces.classList.remove("hidden");1044 domSectNamespaces.classList.remove("hidden");
1045 }1045 }
10461046
1047 if (errSetsList.length !== 0) {1047 if (errSetsList.length !== 0) {
1048 resizeDomList(domListErrSets, errSetsList.length, '<li><a href="#"></a></li>');1048 var domListErrSetsFragment = createDomListFragment(errSetsList.length, '<li><a href="#"></a></li>');
1049 for (var i = 0; i < errSetsList.length; i += 1) {1049 for (var i = 0; i < errSetsList.length; i += 1) {
1050 var liDom = domListErrSets.children[i];1050 var liDom = domListErrSetsFragment.children[i];
1051 var aDom = liDom.children[0];1051 var aDom = liDom.children[0];
1052 var decl = errSetsList[i];1052 var decl = errSetsList[i];
1053 aDom.textContent = decl.name;1053 aDom.textContent = decl.name;
1054 aDom.setAttribute('href', navLinkDecl(decl.name));1054 aDom.setAttribute('href', navLinkDecl(decl.name));
1055 }1055 }
1056 domListErrSets.innerHTML = "";
1057 domListErrSets.appendChild(domListErrSetsFragment);
1056 domSectErrSets.classList.remove("hidden");1058 domSectErrSets.classList.remove("hidden");
1057 }1059 }
10581060
1059 if (fnsList.length !== 0) {1061 if (fnsList.length !== 0) {
1060 resizeDomList(domListFns, fnsList.length, '<tr><td></td><td></td></tr>');1062 var domListFnsFragment = createDomListFragment(fnsList.length, '<tr><td></td><td></td></tr>');
1061 for (var i = 0; i < fnsList.length; i += 1) {1063 for (var i = 0; i < fnsList.length; i += 1) {
1062 var decl = fnsList[i];1064 var decl = fnsList[i];
1063 var trDom = domListFns.children[i];1065 var trDom = domListFnsFragment.children[i];
10641066
1065 var tdFnCode = trDom.children[0];1067 var tdFnCode = trDom.children[0];
1066 var tdDesc = trDom.children[1];1068 var tdDesc = trDom.children[1];
...@@ -1074,17 +1076,19 @@...@@ -1074,17 +1076,19 @@
1074 tdDesc.textContent = "";1076 tdDesc.textContent = "";
1075 }1077 }
1076 }1078 }
1079 domListFns.innerHTML = "";
1080 domListFns.appendChild(domListFnsFragment);
1077 domSectFns.classList.remove("hidden");1081 domSectFns.classList.remove("hidden");
1078 }1082 }
10791083
1080 if (container.fields != null && container.fields.length !== 0) {1084 if (container.fields != null && container.fields.length !== 0) {
1081 resizeDomList(domListFields, container.fields.length, '<div></div>');1085 var domListFieldsFragment = createDomListFragment(container.fields.length, '<div></div>');
10821086
1083 var containerNode = zigAnalysis.astNodes[container.src];1087 var containerNode = zigAnalysis.astNodes[container.src];
1084 for (var i = 0; i < container.fields.length; i += 1) {1088 for (var i = 0; i < container.fields.length; i += 1) {
1085 var field = container.fields[i];1089 var field = container.fields[i];
1086 var fieldNode = zigAnalysis.astNodes[containerNode.fields[i]];1090 var fieldNode = zigAnalysis.astNodes[containerNode.fields[i]];
1087 var divDom = domListFields.children[i];1091 var divDom = domListFieldsFragment.children[i];
10881092
1089 var html = '<div class="mobile-scroll-container"><pre class="scroll-item">' + escapeHtml(fieldNode.name);1093 var html = '<div class="mobile-scroll-container"><pre class="scroll-item">' + escapeHtml(fieldNode.name);
10901094
...@@ -1107,15 +1111,17 @@...@@ -1107,15 +1111,17 @@
1107 }1111 }
1108 divDom.innerHTML = html;1112 divDom.innerHTML = html;
1109 }1113 }
1114 domListFields.innerHTML = "";
1115 domListFields.appendChild(domListFieldsFragment);
1110 domSectFields.classList.remove("hidden");1116 domSectFields.classList.remove("hidden");
1111 }1117 }
11121118
1113 if (varsList.length !== 0) {1119 if (varsList.length !== 0) {
1114 resizeDomList(domListGlobalVars, varsList.length,1120 var domListGlobalVarsFragment = createDomListFragment(varsList.length,
1115 '<tr><td><a href="#"></a></td><td></td><td></td></tr>');1121 '<tr><td><a href="#"></a></td><td></td><td></td></tr>');
1116 for (var i = 0; i < varsList.length; i += 1) {1122 for (var i = 0; i < varsList.length; i += 1) {
1117 var decl = varsList[i];1123 var decl = varsList[i];
1118 var trDom = domListGlobalVars.children[i];1124 var trDom = domListGlobalVarsFragment.children[i];
11191125
1120 var tdName = trDom.children[0];1126 var tdName = trDom.children[0];
1121 var tdNameA = tdName.children[0];1127 var tdNameA = tdName.children[0];
...@@ -1134,15 +1140,17 @@...@@ -1134,15 +1140,17 @@
1134 tdDesc.textContent = "";1140 tdDesc.textContent = "";
1135 }1141 }
1136 }1142 }
1143 domListGlobalVars.innerHTML = "";
1144 domListGlobalVars.appendChild(domListGlobalVarsFragment);
1137 domSectGlobalVars.classList.remove("hidden");1145 domSectGlobalVars.classList.remove("hidden");
1138 }1146 }
11391147
1140 if (valsList.length !== 0) {1148 if (valsList.length !== 0) {
1141 resizeDomList(domListValues, valsList.length,1149 var domListValuesFragment = createDomListFragment(valsList.length,
1142 '<tr><td><a href="#"></a></td><td></td><td></td></tr>');1150 '<tr><td><a href="#"></a></td><td></td><td></td></tr>');
1143 for (var i = 0; i < valsList.length; i += 1) {1151 for (var i = 0; i < valsList.length; i += 1) {
1144 var decl = valsList[i];1152 var decl = valsList[i];
1145 var trDom = domListValues.children[i];1153 var trDom = domListValuesFragment.children[i];
11461154
1147 var tdName = trDom.children[0];1155 var tdName = trDom.children[0];
1148 var tdNameA = tdName.children[0];1156 var tdNameA = tdName.children[0];
...@@ -1161,6 +1169,8 @@...@@ -1161,6 +1169,8 @@
1161 tdDesc.textContent = "";1169 tdDesc.textContent = "";
1162 }1170 }
1163 }1171 }
1172 domListValues.innerHTML = "";
1173 domListValues.appendChild(domListValuesFragment);
1164 domSectValues.classList.remove("hidden");1174 domSectValues.classList.remove("hidden");
1165 }1175 }
1166 }1176 }
...@@ -1768,7 +1778,7 @@...@@ -1768,7 +1778,7 @@
1768 if (ev.ctrlKey) name = "Ctrl+" + name;1778 if (ev.ctrlKey) name = "Ctrl+" + name;
1769 return name;1779 return name;
1770 }1780 }
1771 1781
1772 function onWindowKeyDown(ev) {1782 function onWindowKeyDown(ev) {
1773 switch (getKeyString(ev)) {1783 switch (getKeyString(ev)) {
1774 case "Esc":1784 case "Esc":
...@@ -1809,7 +1819,7 @@...@@ -1809,7 +1819,7 @@
18091819
1810 function startAsyncSearch() {1820 function startAsyncSearch() {
1811 clearAsyncSearch();1821 clearAsyncSearch();
1812 searchTimer = setTimeout(startSearch, 100);1822 searchTimer = setTimeout(startSearch, 10);
1813 }1823 }
1814 function startSearch() {1824 function startSearch() {
1815 clearAsyncSearch();1825 clearAsyncSearch();
...@@ -1881,25 +1891,27 @@...@@ -1881,25 +1891,27 @@
1881 }1891 }
18821892
1883 if (matchedItems.length !== 0) {1893 if (matchedItems.length !== 0) {
1884 resizeDomList(domListSearchResults, matchedItems.length, '<li><a href="#"></a></li>');
1885
1886 matchedItems.sort(function(a, b) {1894 matchedItems.sort(function(a, b) {
1887 var cmp = operatorCompare(b.points, a.points);1895 var cmp = operatorCompare(b.points, a.points);
1888 if (cmp != 0) return cmp;1896 if (cmp != 0) return cmp;
1889 return operatorCompare(a.decl.name, b.decl.name);1897 return operatorCompare(a.decl.name, b.decl.name);
1890 });1898 });
18911899
1900 var domListSearchResultsFragment = createDomListFragment(matchedItems.length, '<li><a href="#"></a></li>');
1892 for (var i = 0; i < matchedItems.length; i += 1) {1901 for (var i = 0; i < matchedItems.length; i += 1) {
1893 var liDom = domListSearchResults.children[i];1902 var liDom = domListSearchResultsFragment.children[i];
1894 var aDom = liDom.children[0];1903 var aDom = liDom.children[0];
1895 var match = matchedItems[i];1904 var match = matchedItems[i];
1896 var lastPkgName = match.path.pkgNames[match.path.pkgNames.length - 1];1905 var lastPkgName = match.path.pkgNames[match.path.pkgNames.length - 1];
1897 aDom.textContent = lastPkgName + "." + match.path.declNames.join('.');1906 aDom.textContent = lastPkgName + "." + match.path.declNames.join('.');
1898 aDom.setAttribute('href', navLink(match.path.pkgNames, match.path.declNames));1907 aDom.setAttribute('href', navLink(match.path.pkgNames, match.path.declNames));
1899 }1908 }
1900 renderSearchCursor();
19011909
1910 domListSearchResults.innerHTML = "";
1911 domListSearchResults.appendChild(domListSearchResultsFragment);
1902 domSectSearchResults.classList.remove("hidden");1912 domSectSearchResults.classList.remove("hidden");
1913
1914 renderSearchCursor();
1903 } else {1915 } else {
1904 domSectSearchNoResults.classList.remove("hidden");1916 domSectSearchNoResults.classList.remove("hidden");
1905 }1917 }