Skip to content

Commit

Permalink
Improve Quick Open performance (firefox-devtools#8209)
Browse files Browse the repository at this point in the history
  • Loading branch information
sorin-davidoi authored and jasonLaster committed Apr 29, 2019
1 parent e5dfa84 commit 0c2a1ba
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 50 deletions.
38 changes: 27 additions & 11 deletions src/components/QuickOpenModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import React, { Component } from "react";
import { connect } from "../utils/connect";
import fuzzyAldrin from "fuzzaldrin-plus";
import { basename } from "../utils/path";
import { throttle } from "lodash";

import actions from "../actions";
import {
Expand Down Expand Up @@ -43,8 +44,8 @@ import "./QuickOpenModal.css";

type Props = {
enabled: boolean,
sources: Array<Object>,
selectedSource?: Source,
displayedSources: Source[],
query: string,
searchType: QuickOpenType,
symbols: FormattedSymbolDeclarations,
Expand All @@ -69,12 +70,16 @@ type GotoLocationType = {
column?: number
};

const updateResultsThrottle = 100;
const maxResults = 100;

function filter(values, query) {
const preparedQuery = fuzzyAldrin.prepareQuery(query);

return fuzzyAldrin.filter(values, query, {
key: "value",
maxResults: maxResults
maxResults: maxResults,
preparedQuery
});
}

Expand Down Expand Up @@ -127,7 +132,9 @@ export class QuickOpenModal extends Component<Props, State> {
};

searchSources = (query: string) => {
const { sources } = this.props;
const { displayedSources, tabs } = this.props;
const tabUrls = new Set(tabs.map((tab: Tab) => tab.url));
const sources = formatSources(displayedSources, tabUrls);
const results =
query == "" ? sources : filter(sources, this.dropGoto(query));
return this.setResults(results);
Expand Down Expand Up @@ -158,16 +165,24 @@ export class QuickOpenModal extends Component<Props, State> {
};

showTopSources = () => {
const { tabs, sources } = this.props;
const { displayedSources, tabs } = this.props;
const tabUrls = new Set(tabs.map((tab: Tab) => tab.url));

if (tabs.length > 0) {
const tabUrls = tabs.map((tab: Tab) => tab.url);
this.setResults(sources.filter(source => tabUrls.includes(source.url)));
this.setResults(
formatSources(
displayedSources.filter(
source => !!source.url && tabUrls.has(source.url)
),
tabUrls
)
);
} else {
this.setResults(sources);
this.setResults(formatSources(displayedSources, tabUrls));
}
};

updateResults = (query: string) => {
updateResults = throttle((query: string) => {
if (this.isGotoQuery()) {
return;
}
Expand All @@ -185,7 +200,7 @@ export class QuickOpenModal extends Component<Props, State> {
}

return this.searchSources(query);
};
}, updateResultsThrottle);

setModifier = (item: QuickOpenResult) => {
if (["@", "#", ":"].includes(item.id)) {
Expand Down Expand Up @@ -422,16 +437,17 @@ export class QuickOpenModal extends Component<Props, State> {
/* istanbul ignore next: ignoring testing of redux connection stuff */
function mapStateToProps(state) {
const selectedSource = getSelectedSource(state);
const tabs = getTabs(state);

return {
enabled: getQuickOpenEnabled(state),
sources: formatSources(getDisplayedSourcesList(state), getTabs(state)),
selectedSource,
displayedSources: getDisplayedSourcesList(state),
symbols: formatSymbols(getSymbols(state, selectedSource)),
symbolsLoading: isSymbolsLoading(state, selectedSource),
query: getQuickOpenQuery(state),
searchType: getQuickOpenType(state),
tabs: getTabs(state)
tabs
};
}

Expand Down
24 changes: 21 additions & 3 deletions src/components/test/QuickOpenModal.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@

import React from "react";
import { shallow, mount } from "enzyme";
import lodash from "lodash";
import { QuickOpenModal } from "../QuickOpenModal";

jest.mock("fuzzaldrin-plus");
jest.unmock("lodash");

// $FlowIgnore
lodash.throttle = jest.fn(fn => fn);

import { filter } from "fuzzaldrin-plus";

Expand All @@ -18,7 +23,7 @@ function generateModal(propOverrides, renderType = "shallow") {
enabled: false,
query: "",
searchType: "sources",
sources: [],
displayedSources: [],
tabs: [],
selectSpecificLocation: jest.fn(),
setQuickOpenQuery: jest.fn(),
Expand Down Expand Up @@ -111,12 +116,24 @@ describe("QuickOpenModal", () => {
{
enabled: true,
query: "",
sources: [{ url: "mozilla.com" }],
displayedSources: [
// $FlowIgnore
{ url: "mozilla.com", relativeUrl: true }
],
tabs: [generateTab("mozilla.com")]
},
"shallow"
);
expect(wrapper.state("results")).toEqual([{ url: "mozilla.com" }]);
expect(wrapper.state("results")).toEqual([
{
id: undefined,
icon: "tab result-item-icon",
subtitle: "true",
title: "mozilla.com",
url: "mozilla.com",
value: "true"
}
]);
});

describe("shows loading", () => {
Expand Down Expand Up @@ -786,6 +803,7 @@ describe("QuickOpenModal", () => {
},
"mount"
);

expect(wrapper).toMatchSnapshot();
});

Expand Down
22 changes: 11 additions & 11 deletions src/components/test/__snapshots__/QuickOpenModal.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ exports[`QuickOpenModal Basic render with mount & searchType = functions 1`] = `
<QuickOpenModal
clearHighlightLineRange={[MockFunction]}
closeQuickOpen={[MockFunction]}
displayedSources={Array []}
enabled={true}
highlightLineRange={[MockFunction]}
isOriginal={false}
Expand All @@ -12,7 +13,6 @@ exports[`QuickOpenModal Basic render with mount & searchType = functions 1`] = `
selectSpecificLocation={[MockFunction]}
setQuickOpenQuery={[MockFunction]}
shortcutsModalEnabled={false}
sources={Array []}
symbols={
Object {
"functions": Array [],
Expand Down Expand Up @@ -130,6 +130,7 @@ exports[`QuickOpenModal Basic render with mount & searchType = variables 1`] = `
<QuickOpenModal
clearHighlightLineRange={[MockFunction]}
closeQuickOpen={[MockFunction]}
displayedSources={Array []}
enabled={true}
highlightLineRange={[MockFunction]}
isOriginal={false}
Expand All @@ -138,7 +139,6 @@ exports[`QuickOpenModal Basic render with mount & searchType = variables 1`] = `
selectSpecificLocation={[MockFunction]}
setQuickOpenQuery={[MockFunction]}
shortcutsModalEnabled={false}
sources={Array []}
symbols={
Object {
"functions": Array [],
Expand Down Expand Up @@ -240,6 +240,7 @@ exports[`QuickOpenModal Basic render with mount 1`] = `
<QuickOpenModal
clearHighlightLineRange={[MockFunction]}
closeQuickOpen={[MockFunction]}
displayedSources={Array []}
enabled={true}
highlightLineRange={[MockFunction]}
isOriginal={false}
Expand All @@ -248,7 +249,6 @@ exports[`QuickOpenModal Basic render with mount 1`] = `
selectSpecificLocation={[MockFunction]}
setQuickOpenQuery={[MockFunction]}
shortcutsModalEnabled={false}
sources={Array []}
symbols={
Object {
"functions": Array [],
Expand Down Expand Up @@ -400,6 +400,7 @@ exports[`QuickOpenModal Simple goto search query = :abc & searchType = goto 1`]
<QuickOpenModal
clearHighlightLineRange={[MockFunction]}
closeQuickOpen={[MockFunction]}
displayedSources={Array []}
enabled={true}
highlightLineRange={[MockFunction]}
isOriginal={false}
Expand All @@ -408,7 +409,6 @@ exports[`QuickOpenModal Simple goto search query = :abc & searchType = goto 1`]
selectSpecificLocation={[MockFunction]}
setQuickOpenQuery={[MockFunction]}
shortcutsModalEnabled={false}
sources={Array []}
symbols={
Object {
"functions": Array [],
Expand Down Expand Up @@ -515,6 +515,7 @@ exports[`QuickOpenModal showErrorEmoji false when count + query 1`] = `
<QuickOpenModal
clearHighlightLineRange={[MockFunction]}
closeQuickOpen={[MockFunction]}
displayedSources={Array []}
enabled={true}
highlightLineRange={[MockFunction]}
isOriginal={false}
Expand All @@ -523,7 +524,6 @@ exports[`QuickOpenModal showErrorEmoji false when count + query 1`] = `
selectSpecificLocation={[MockFunction]}
setQuickOpenQuery={[MockFunction]}
shortcutsModalEnabled={false}
sources={Array []}
symbols={
Object {
"functions": Array [],
Expand Down Expand Up @@ -672,6 +672,7 @@ exports[`QuickOpenModal showErrorEmoji false when goto numeric ':2222' 1`] = `
<QuickOpenModal
clearHighlightLineRange={[MockFunction]}
closeQuickOpen={[MockFunction]}
displayedSources={Array []}
enabled={true}
highlightLineRange={[MockFunction]}
isOriginal={false}
Expand All @@ -680,7 +681,6 @@ exports[`QuickOpenModal showErrorEmoji false when goto numeric ':2222' 1`] = `
selectSpecificLocation={[MockFunction]}
setQuickOpenQuery={[MockFunction]}
shortcutsModalEnabled={false}
sources={Array []}
symbols={
Object {
"functions": Array [],
Expand Down Expand Up @@ -786,6 +786,7 @@ exports[`QuickOpenModal showErrorEmoji false when no query 1`] = `
<QuickOpenModal
clearHighlightLineRange={[MockFunction]}
closeQuickOpen={[MockFunction]}
displayedSources={Array []}
enabled={true}
highlightLineRange={[MockFunction]}
isOriginal={false}
Expand All @@ -794,7 +795,6 @@ exports[`QuickOpenModal showErrorEmoji false when no query 1`] = `
selectSpecificLocation={[MockFunction]}
setQuickOpenQuery={[MockFunction]}
shortcutsModalEnabled={false}
sources={Array []}
symbols={
Object {
"functions": Array [],
Expand Down Expand Up @@ -911,6 +911,7 @@ exports[`QuickOpenModal showErrorEmoji true when goto not numeric ':22k22' 1`] =
<QuickOpenModal
clearHighlightLineRange={[MockFunction]}
closeQuickOpen={[MockFunction]}
displayedSources={Array []}
enabled={true}
highlightLineRange={[MockFunction]}
isOriginal={false}
Expand All @@ -919,7 +920,6 @@ exports[`QuickOpenModal showErrorEmoji true when goto not numeric ':22k22' 1`] =
selectSpecificLocation={[MockFunction]}
setQuickOpenQuery={[MockFunction]}
shortcutsModalEnabled={false}
sources={Array []}
symbols={
Object {
"functions": Array [],
Expand Down Expand Up @@ -1025,6 +1025,7 @@ exports[`QuickOpenModal showErrorEmoji true when no count + query 1`] = `
<QuickOpenModal
clearHighlightLineRange={[MockFunction]}
closeQuickOpen={[MockFunction]}
displayedSources={Array []}
enabled={true}
highlightLineRange={[MockFunction]}
isOriginal={false}
Expand All @@ -1033,7 +1034,6 @@ exports[`QuickOpenModal showErrorEmoji true when no count + query 1`] = `
selectSpecificLocation={[MockFunction]}
setQuickOpenQuery={[MockFunction]}
shortcutsModalEnabled={false}
sources={Array []}
symbols={
Object {
"functions": Array [],
Expand Down Expand Up @@ -1167,6 +1167,7 @@ exports[`QuickOpenModal updateResults on enable 1`] = `
<QuickOpenModal
clearHighlightLineRange={[MockFunction]}
closeQuickOpen={[MockFunction]}
displayedSources={Array []}
enabled={false}
highlightLineRange={[MockFunction]}
isOriginal={false}
Expand All @@ -1175,7 +1176,6 @@ exports[`QuickOpenModal updateResults on enable 1`] = `
selectSpecificLocation={[MockFunction]}
setQuickOpenQuery={[MockFunction]}
shortcutsModalEnabled={false}
sources={Array []}
symbols={
Object {
"functions": Array [],
Expand All @@ -1192,6 +1192,7 @@ exports[`QuickOpenModal updateResults on enable 2`] = `
<QuickOpenModal
clearHighlightLineRange={[MockFunction]}
closeQuickOpen={[MockFunction]}
displayedSources={Array []}
enabled={true}
highlightLineRange={[MockFunction]}
isOriginal={false}
Expand All @@ -1200,7 +1201,6 @@ exports[`QuickOpenModal updateResults on enable 2`] = `
selectSpecificLocation={[MockFunction]}
setQuickOpenQuery={[MockFunction]}
shortcutsModalEnabled={false}
sources={Array []}
symbols={
Object {
"functions": Array [],
Expand Down
16 changes: 9 additions & 7 deletions src/utils/quick-open.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
import type { Location as BabelLocation } from "@babel/types";
import type { Symbols } from "../reducers/ast";
import type { QuickOpenType } from "../reducers/quick-open";
import type { TabList } from "../reducers/tabs";
import type { Tab } from "../reducers/tabs";
import type { Source } from "../types";
import type {
SymbolDeclaration,
Expand Down Expand Up @@ -58,7 +58,10 @@ export function parseLineColumn(query: string) {
}
}

export function formatSourcesForList(source: Source, tabs: TabList) {
export function formatSourcesForList(
source: Source,
tabUrls: Set<$PropertyType<Tab, "url">>
) {
const title = getFilename(source);
const relativeUrlWithQuery = `${source.relativeUrl}${getSourceQueryString(
source
Expand All @@ -68,7 +71,7 @@ export function formatSourcesForList(source: Source, tabs: TabList) {
value: relativeUrlWithQuery,
title,
subtitle: relativeUrlWithQuery,
icon: tabs.some(tab => tab.url == source.url)
icon: tabUrls.has(source.url)
? "tab result-item-icon"
: classnames(getSourceClassnames(source), "result-item-icon"),
id: source.id,
Expand Down Expand Up @@ -136,10 +139,9 @@ export function formatShortcutResults(): Array<QuickOpenResult> {

export function formatSources(
sources: Source[],
tabs: TabList
tabUrls: Set<$PropertyType<Tab, "url">>
): Array<QuickOpenResult> {
return sources
.filter(source => !isPretty(source))
.filter(({ relativeUrl }) => !!relativeUrl)
.map(source => formatSourcesForList(source, tabs));
.filter(source => !!source.relativeUrl && !isPretty(source))
.map(source => formatSourcesForList(source, tabUrls));
}
Loading

0 comments on commit 0c2a1ba

Please sign in to comment.