Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.

Speed up Out Of Scope lines#3184

Merged
jasonLaster merged 2 commits into
firefox-devtools:masterfrom
jasonLaster:oos
Jun 19, 2017
Merged

Speed up Out Of Scope lines#3184
jasonLaster merged 2 commits into
firefox-devtools:masterfrom
jasonLaster:oos

Conversation

@jasonLaster

@jasonLaster jasonLaster commented Jun 18, 2017

Copy link
Copy Markdown
Contributor

Associated Issue: #3180

Summary of Changes

This refactors out of scope lines a bit to support getting a list of in scope lines that can be used by the editor to check if a token is in scope on hover.

Test Plan

Jest tests

@codecov

codecov Bot commented Jun 18, 2017

Copy link
Copy Markdown

Codecov Report

Merging #3184 into master will decrease coverage by 0.03%.
The diff coverage is 67.5%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3184      +/-   ##
==========================================
- Coverage   47.59%   47.55%   -0.04%     
==========================================
  Files          97       98       +1     
  Lines        4036     4052      +16     
  Branches      828      832       +4     
==========================================
+ Hits         1921     1927       +6     
- Misses       2115     2125      +10
Impacted Files Coverage Δ
src/utils/scopes.js 80.35% <0%> (-2.98%) ⬇️
src/reducers/ast.js 83.78% <0%> (-4.79%) ⬇️
src/components/Editor/index.js 18.35% <0%> (-1.81%) ⬇️
src/actions/sources.js 50.62% <100%> (ø) ⬆️
src/actions/ast.js 72.09% <91.66%> (-0.41%) ⬇️
src/selectors/linesInScope.js 93.75% <93.75%> (ø)
src/reducers/sources.js 76.35% <0%> (-2.03%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 38e1558...7a85c3c. Read the comment docs.

@codecov

codecov Bot commented Jun 18, 2017

Copy link
Copy Markdown

Codecov Report

Merging #3184 into master will increase coverage by 0.03%.
The diff coverage is 54.54%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3184      +/-   ##
==========================================
+ Coverage   47.59%   47.63%   +0.04%     
==========================================
  Files          97       98       +1     
  Lines        4036     4062      +26     
  Branches      828      837       +9     
==========================================
+ Hits         1921     1935      +14     
- Misses       2115     2127      +12
Impacted Files Coverage Δ
src/utils/scopes.js 83.33% <ø> (ø) ⬆️
src/reducers/ast.js 83.78% <0%> (-4.79%) ⬇️
src/components/Editor/index.js 19.31% <27.27%> (-0.85%) ⬇️
src/actions/ast.js 71.42% <75%> (-1.08%) ⬇️
src/selectors/linesInScope.js 93.75% <93.75%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 22b7436...47fac1d. Read the comment docs.


if (!linesInScope.includes(line)) {
return;
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was the main thing that I wanted to get out of this PR. previously we were checking the parent's class which required always doing an expensive render. We should be ideally using data which is more trustworthy.

if (this.props.outOfScopeLocations !== nextProps.outOfScopeLocations) {
clearLineClass(this.editor.codeMirror, "out-of-scope");
if (this.props.linesInScope !== nextProps.linesInScope) {
this.editor.codeMirror.operation(() => {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this.editor.codeMirror.operation is a huge perf win. With that said, i'll be moving the operation inside clearLineClass soon :)

renderInScopeLines() {
const { linesInScope } = this.props;
if (
!isEnabled("highlightScopeLines") ||

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm re-adding a feature flag because i'm not happy with the cases we're missing like blocks and comments. Seeing those issues makes me think we should wait and re-launch highlighting when it's further along.

With that said, we still get the onMouseOver logic so fewer accidental popups

@@ -0,0 +1,42 @@
// import { linesInScope } from "../utils/scopes";
import { getOutOfScopeLocations, getSelectedSource } from "../selectors";

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the first selector that spans stores (sources, ast) with that in mind I created a new selectors directory. I'm not sure if that makes sense. What do others think?

Comment thread src/actions/ast.js Outdated
const sourceText = getSourceText(getState(), source.id);
if (!sourceText) {
const source = sourceRecord.toJS();
if (!source.text || hasSymbols(getState(), source)) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some small sourceText => source migrations

@jasonLaster jasonLaster force-pushed the oos branch 2 times, most recently from 3423f5e to 539c2ae Compare June 19, 2017 11:53
"column": 21,
"line": 1,
"column": 3,
"line": 10,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I switched the test to read from a new fixture file :)

10,
11,
12,
]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the ability to do line reviews

Comment thread src/actions/tests/ast.js
await dispatch(actions.loadSourceText({ id: "base.js" }));
await dispatch(actions.selectSource("base.js", { line: 1 }));

await dispatch(actions.setOutOfScopeLocations());

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah - so this is coooool. Turns out many of the dispatches are unnecessary.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome

}

.paused .CodeMirror-line, .paused .CodeMirror-linenumber {
opacity: 0.7;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we're now tracking in-scope and not out-of-scope.

some reasons:

  1. it's easier to get the lines in scope than all the lines that are out of scope
  2. it should be faster because there are fewer innies than outies.

Comment thread src/reducers/ast.js
case "RESUMED": {
return state.set("outOfScopeLocations", null);
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this fixes #3123

@codehag codehag left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good. I have a few comments. let me know if you have any questions!

@@ -0,0 +1,41 @@
import { getOutOfScopeLocations, getSelectedSource } from "../selectors";

import range from "lodash/range";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it make sense to do this?

import { range, flatMap, uniq, without } from "lodash";

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sadly... no because then we pull lodash into the bundle... I suppose if we made it an external then we could exclude it from the bundle and expect it to be available in m-c... If we like this i can file a separate issue for it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

import without from "lodash/without";

function getLinesOutOfScope(outOfScopeLocations: AstLocation[]) {
if (!outOfScopeLocations) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this is an array of AstLocations, I think this will always be true... or maybe it isnt an array?

if it is an array we probably need to do

if (!outOfScopeLocations.length) {
  ...
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can do both. when it is not available it's nully.

Comment thread src/selectors/linesInScope.js Outdated
import uniq from "lodash/uniq";
import without from "lodash/without";

function getLinesOutOfScope(outOfScopeLocations: AstLocation[]) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getLinesOutOfScope sounds like we are taking lines out of a scope, but I think this is getting the out of scope lines. maybe getOutOfScopeLines will be clearer here,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed :)


return uniq(
flatMap(outOfScopeLocations, location =>
range(location.start.line, location.end.line)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

Comment thread src/selectors/linesInScope.js Outdated
);
}

export default function getLinesInScope(state: OuterState) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment here about naming: proposing getInScopeLines


function getLinesOutOfScope(outOfScopeLocations: AstLocation[]) {
if (!outOfScopeLocations) {
return null;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is returning a different type; maybe it should be an empty array?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... not sure. i kinda like having explicit empty states to distinguish between nothing and we happen to have no out of scope locs. ill think about it

const sourceNumLines = source.get("text").split("\n").length;
const sourceLines = range(1, sourceNumLines + 1);

if (!linesOutOfScope) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the logic here would be clearer if this was checking for an empty array

Comment thread src/actions/tests/ast.js
await dispatch(actions.loadSourceText({ id: "base.js" }));
await dispatch(actions.selectSource("base.js", { line: 1 }));

await dispatch(actions.setOutOfScopeLocations());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome

@codehag codehag left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@jasonLaster jasonLaster merged commit 80dd3c8 into firefox-devtools:master Jun 19, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants