Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve tree perf #2555

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions app/components/component-tree-arg.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ export default class ComponentTreeArg extends Component {

get displayValue() {
if (this.isObject) {
if (this.args.value.inspect) {
if (this.args.value.type === 'function') {
return this.args.value.inspect
.replace(/"/g, '\\"')
.replace('bound ', '')
.replace('{ ... }', '');
}
return this.args.value.inspect.replace(/"/g, '\\"');
}
return '...';
} else if (typeof this.args.value === 'string') {
// Escape any interior quotes – we will add the surrounding quotes in the template
Expand Down
19 changes: 17 additions & 2 deletions app/components/component-tree-item.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
{{on "mouseenter" @item.showPreview}}
{{on "mouseleave" @item.hidePreview}}
>
{{resource @item.id create=@item.load update=@item.update teardown=@item.unload}}
<div class="component-tree-item-background flex items-center pr-2 rounded">
{{#if @item.hasChildren}}
<Ui::DisclosureTriangle
Expand All @@ -24,7 +25,7 @@
<code
class="component-tree-item__tag flex whitespace-no-wrap
{{if
@item.isComponent
(or @item.isComponent @item.isModifier @item.isHtmlTag)
(if
@item.isCurlyInvocation
"component-tree-item-classic__bracket"
Expand All @@ -37,7 +38,7 @@
}}"
>
{{!-- template-lint-disable no-unbalanced-curlies --}}
{{#if @item.isComponent}}
{{#if (or @item.isComponent @item.isModifier)}}
{{#if @item.isCurlyInvocation}}
<span class="component-name">
{{@item.name}}
Expand Down Expand Up @@ -83,6 +84,20 @@
\{{mount "{{@item.name}}"}}
{{else if @item.isRouteTemplate}}
{{@item.name}} route
{{else if @item.isHtmlTag}}
<span class="component-name">
{{@item.name}}
</span>
{{#each-in @item.args.named as |name value|}}
<div class="arg-token flex ml-2">
<span class="key-token">
{{name}}
</span>
={{if (is-string value) "\""}}
<ComponentTreeArg @value={{value}} />
{{if (is-string value) "\""}}
</div>
{{/each-in}}
{{/if}}
</code>
</div>
Expand Down
4 changes: 2 additions & 2 deletions app/components/object-inspector/property.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ export default class ObjectInspectorProperty extends Component<ObjectInspectorPr
}

get cannotEdit() {
if (this.args.model.name === '...' || !this.isCalculated) return true;
return this.isFunction || this.isOverridden || this.readOnly;
if (this.args.model.name === '...' || !this.isCalculated || this.readOnly) return true;
return this.args.model?.value?.type !== 'type-string' && this.args.model?.value?.type !== 'type-number';
}

@action
Expand Down
62 changes: 61 additions & 1 deletion app/controllers/component-tree.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Controller, { inject as controller } from '@ember/controller';
import { action } from '@ember/object';
import { debounce } from '@ember/runloop';
import { debounce, next } from '@ember/runloop';
import { inject as service } from '@ember/service';
import { htmlSafe } from '@ember/template';
import { tracked } from '@glimmer/tracking';
Expand Down Expand Up @@ -42,6 +42,9 @@ export default class ComponentTreeController extends Controller {
item = new RenderItem(this, parent, renderNode);
} else {
item.renderNode = renderNode;
if (item.isRendered) {
item.load();
}
}

store[renderNode.id] = item;
Expand All @@ -59,6 +62,15 @@ export default class ComponentTreeController extends Controller {
this.renderItems = renderItems;
}

setRenderTreeItem(item) {
if (item && this._store[item.id]) {
this._store[item.id].renderNode = Object.assign(
this._store[item.id].renderNode,
item
);
}
}

findItem(id) {
return this._store[id];
}
Expand Down Expand Up @@ -275,6 +287,7 @@ function arrowKeyPressed(keyCode) {
class RenderItem {
@tracked isExpanded;
@tracked renderNode;
@tracked renderCounter = 0;

constructor(controller, parentItem, renderNode) {
this.controller = controller;
Expand All @@ -284,6 +297,42 @@ class RenderItem {
this.isExpanded = this.isExpandable;
}

get isRendered() {
return this.renderCounter > 0;
}

@action
load() {
next(() => {
this.renderCounter += 1;
if (this.renderNode.args) {
return;
}
console.log('load', this.id);
this.send('view:getTreeItem', { id: this.id });
});
}

@action
async update(prevId) {
next(() => {
this.controller._store[prevId].renderCounter -= 1;
this.renderCounter += 1;
if (this.renderNode.args) {
return;
}
console.log('load', this.id);
this.send('view:getTreeItem', { id: this.id });
});
}

@action
async unload() {
next(() => {
this.renderCounter -= 1;
});
}

get id() {
return this.renderNode.id;
}
Expand All @@ -304,6 +353,14 @@ class RenderItem {
return this.renderNode.type === 'component';
}

get isModifier() {
return this.renderNode.type === 'modifier';
}

get isHtmlTag() {
return this.renderNode.type === 'html-element';
}

get name() {
return this.renderNode.name;
}
Expand All @@ -313,6 +370,9 @@ class RenderItem {
}

get isCurlyInvocation() {
if (this.isModifier) {
return true;
}
return this.renderNode.args && this.renderNode.args.positional;
}

Expand Down
25 changes: 25 additions & 0 deletions app/helpers/resource.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import Helper from '@ember/component/helper';
import { registerDestructor, unregisterDestructor } from '@ember/destroyable';

export default class ResourceHelper extends Helper {
compute(positional, named) {
const firstTime = !this.updateCallback;
this.updateCallback = named.update;
if (named.teardown) {
if (this.teardownCallback) {
unregisterDestructor(this, this.teardownCallback);
}
this.teardownCallback = named.teardown;
registerDestructor(this, this.teardownCallback);
}
if (this.updateCallback && !firstTime) {
this.updateCallback(this.prevState, positional);
}
if (firstTime && named.create) {
named.create();
}
//access all positional params
positional.forEach(() => null);
this.prevState = [...positional];
}
}
6 changes: 6 additions & 0 deletions app/routes/component-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default class ComponentTreeRoute extends TabRoute {
super.activate(...arguments);

this.port.on('view:renderTree', this, this.setRenderTree);
this.port.on('view:renderTreeItem', this, this.setRenderTreeItem);
this.port.on('view:cancelSelection', this, this.cancelSelection);
this.port.on('view:startInspecting', this, this.startInspecting);
this.port.on('view:stopInspecting', this, this.stopInspecting);
Expand All @@ -38,6 +39,7 @@ export default class ComponentTreeRoute extends TabRoute {
super.deactivate(...arguments);

this.port.off('view:renderTree', this, this.setRenderTree);
this.port.off('view:renderTreeItem', this, this.setRenderTreeItem);
this.port.off('view:cancelSelection', this, this.cancelSelection);
this.port.off('view:startInspecting', this, this.startInspecting);
this.port.off('view:stopInspecting', this, this.stopInspecting);
Expand All @@ -48,6 +50,10 @@ export default class ComponentTreeRoute extends TabRoute {
this.controller.renderTree = tree;
}

setRenderTreeItem({ treeItem }) {
this.controller.setRenderTreeItem(treeItem);
}

cancelSelection({ id, pin }) {
this.controller.cancelSelection(id, pin);
}
Expand Down
7 changes: 3 additions & 4 deletions ember-cli-build.js
Original file line number Diff line number Diff line change
Expand Up @@ -381,19 +381,18 @@ module.exports = function (defaults) {
if (env === 'test') {
// `ember test` expects the index.html file to be in the
// output directory.
output = mergeTrees([dists.basic, dists.chrome]);
} else {
// Change base tag for running tests in development env.
dists.basic = replace(dists.basic, {
files: ['tests/index.html'],
patterns: [
{
match: /<base.*\/>/,
replacement: '<base href="../" />',
replacement: '',
},
],
});

output = mergeTrees([dists.basic, dists.chrome]);
} else {
dists.testing = mergeTrees([dists.basic, dists.chrome]);

output = mergeTrees([
Expand Down
Loading
Loading