localvoid / vdom-benchmark

Virtual DOM diff/patch benchmark
BSD 2-Clause "Simplified" License
49 stars 10 forks source link

pub serve fails with 'Could not resolve dart:core' #15

Open ghost opened 9 years ago

ghost commented 9 years ago

After reinstalling my operating system (and my whole dev environment), I get the following error when running pub serve:

Loading source assets... 
Loading liquid transformers... 
[Error from Factory on vdom_benchmark|lib/benchmark.dart]:
Unable to resolve asset ID for "dart:core"
[Error from Factory on vdom_benchmark|lib/generator.dart]:
Unable to resolve asset ID for "dart:core"
Serving vdom_benchmark web on http://localhost:8080
[Error from Factory on vdom_benchmark|lib/vdom.dart]:
Unable to resolve asset ID for "dart:core"
Build error:
Transform Factory on vdom_benchmark|lib/vdom.dart threw error: <rethrow>
Caused by Could not resolve dart:core
#0      AnalysisTask._safelyPerform (package:analyzer/src/generated/engine.dart:6762)
#1      AnalysisTask.perform (package:analyzer/src/generated/engine.dart:6727)
#2      AnalysisContextImpl._cacheDartResolutionData (package:analyzer/src/generated/engine.dart:2414)
#3      AnalysisContextImpl._getDartResolutionData (package:analyzer/src/generated/engine.dart:3046)
#4      AnalysisContextImpl._getDartResolutionData2 (package:analyzer/src/generated/engine.dart:3077)
#5      AnalysisContextImpl.computeLibraryElement (package:analyzer/src/generated/engine.dart:1192)
#6      ResolverImpl._performResolve.<anonymous closure>.<anonymous closure> (package:code_transformers/src/resolver_impl.dart:158)
#7      MappedListIterable.elementAt (dart:_internal/iterable.dart:417)
#8      ListIterable.toList (dart:_internal/iterable.dart:219)
#9      ResolverImpl._performResolve.<anonymous closure> (package:code_transformers/src/resolver_impl.dart:159)
#10     _RootZone.runUnary (dart:async/zone.dart:1155)
#11     _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:484)
#12     _Future._propagateToListeners (dart:async/future_impl.dart:567)
#13     _Future._completeWithValue (dart:async/future_impl.dart:358)
#14     _Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:412)
#15     _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:41)
#16     _asyncRunCallback (dart:async/schedule_microtask.dart:48)
#17     _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:84)
#18     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:131)

Dart VM version: 1.8.5 (Tue Jan 13 13:05:45 2015) on "macos_x64"

Does anybody have the same problem? If not, which Dart version are you using? Since I have the feeling that this is a problem with Dart itself, I have reported the issue also for the Dart project: https://code.google.com/p/dart/issues/detail?id=22099

localvoid commented 9 years ago

I am almost finished rewriting this benchmark in javascript without dart dependencies, I think that tomorrow I'll start to upload it on github.

ghost commented 9 years ago

@localvoid that's great news! By the way, I have several ideas for improvements and further tests. Are you planing to invest more time into this benchmark? If so, then I will open some tickets with them.

localvoid commented 9 years ago

Yes, it would be great.

I've already made some big changes. All implementations are now running from its own pages in separate windows(all implementations will be in separate repositories/domains, so they can be maintained by different people), they will receive test cases from the (window.opener) and when they finish, send results back.

Test cases are the same, but I want to add additional rules when generating nodes, for example:

to trigger deoptimization in implementations that use polymorphic virtual nodes.

localvoid commented 9 years ago

Link to the new benchmark: http://localvoid.github.io/benchmark-aggregator/?cfg=http://localvoid.github.io/vdom-benchmark/config.js

Link to the benchmark implementation for your library: https://github.com/localvoid/vdom-benchmark-cito

You can fork it, and I'll update links in http://localvoid.github.io/vdom-benchmark/config.js to make them point to your repository and github page.

ghost commented 9 years ago

@localvoid I have forked it: http://joelrich.github.io/vdom-benchmark-cito/

ghost commented 9 years ago

@localvoid Congrats for kivi! I fear I have to work again on my update algorithm to keep up with yours, but I have already some ideas :-)

I think the new vdom benchmark goes into the right direction. I am not sure though whether it will work in IE with different repositories (which means different origins) because postMessage does not work in that case unless it is an iframe.

Have you thought about adding a run button to the overview? A run all button would be nice too.

What I am really missing right now is the total render/update time. This would make it much easier for developers who try to optimize their library to see the total time difference for changes.

Then, I would suggest to add some tests which cover the following cases:

While I don't expect any surprises from the test 3/4, I know that it is possible to optimize batch remove operations.

localvoid commented 9 years ago

@joelrich Yes, there is a problem with postMessage with different origins, maybe then just use github organization, so all repos will be with the same origin.

I thought about run buttons, but it seems like it stops running in Chrome when opened window isn't focused.

Total render/update time for all test cases, or render+update for each case? If it is for all cases, it will be hard to normalize scores for each case, because if we use "raw time" as a score, "reverse" case will have much higher impact on the final result then "insertLast".

Ok, I'll add batched remove/insert test cases.

ghost commented 9 years ago

@localvoid A solution might be to use an iframe inside an iframe where the first iframe has another origin than the benchmark runner and the second iframe is the iframe with the benchmark itself. This should ensure that there is no difference whether the benchmark and the benchmark runner have the same origin or not. Assumed that it does not have an unexpected disadvantage, this would solve a couple issues: It would work in IE and it would make it possible to control everything from one tab and run all benchmarks sequentially.

I meant total render/update time for all test cases. You are right that the sum is not that meaningful (although I would add it anyway). Maybe you could normalize the total by dividing all test case results with the minimal number of nodes which had to be either moved/removed/updated. However, this would ignore the fact that the diffing itself needs time too. What do you think?

Probably it would also make sense to add some tests which do not update anything at all. Mithril, for example, diffs everything for every handled event (even if there is no change at all) which is why I think such test cases are more important than it first looks.

localvoid commented 9 years ago

@joelrich Implemented running benchmarks from iframes (Run buttons), added test case [500] ["skip"].

I am not sure that calculating scores is worth it, especially because of the differences between dom ops and javascript speed in different browsers/environments.

ghost commented 9 years ago

@localvoid something with the gh-pages branch seems to be wrong: http://localvoid.github.io/benchmark-aggregator/?cfg=http://localvoid.github.io/vdom-benchmark/config.js

Bobris commented 9 years ago

Came to party just on wrong time, when I don't see result. @joelrich Looks like you have very similar target like me with Bobril :-) Eventhough Bobril needs to work with selfcontained pages, that's why It needs to be minimal. (For example I don't care about MathML).

localvoid commented 9 years ago

Sorry, forget to mention that link to the benchmark is changed, and I moved benchmark-aggregator into vdom-benchmark repository. http://vdom-benchmark.github.io/vdom-benchmark/

ghost commented 9 years ago

@Bobris Are you building Bobril for a specific purpose? @localvoid What about you with kiwi? Have you ever thought about defining a virtual DOM standard or joining forces to work together on one library?

@Bobris Soon I will start working on the component framework and then the target group of cito.js will change drastically. Before that, I have to improve the performance again. It used to perform better before I implemented promises and fragment node support.

localvoid commented 9 years ago

@joelrich I just ported my VDom library from Dart to javascript to check how much it will be faster. I am still in exploration phase, trying different ideas.

Bobris commented 9 years ago

@joelrich I build it mainly for our commercial SW which is basically desktop builder of "HTML applications" and you build them visually just by combining components and mapping data model. In old version we used Angular but it was just too slow for nontrivial designs. But because apps needs to be self-contained (they can be send as e-mail attachment and work offline). React would probably helped us with speed, but not with output size. But Mithril is nice size wise, but does not have component architecture. Another benefit what Mithril does not have is Event normalization. I also emulate a lot of features of HTML5 which are not available in IE8 - like opacity completely transparently.

Bobris commented 9 years ago

BTW this night I will extract className and style directly to "Node" like kivi has (it is not exatly same), we hating to write attrs: { style: { } } - it is just too often you need just to set inline style and no other attributes.

Regarding speed in Profiler I don't see much time spend in my code, most of it is inside actual DOM manipulation, So I think we already are on local minimum of implementations. I still not understand render speed of kivi compared to us in IE11: [500] ["reverse"] render() kivi 0.0.1 7517 cito.js 0.0.1 23264 bobril 0.0.1 23009 React 0.12.2 4825

React is fast in IE11 because of innerHTML is much faster than DOM in IE. Updates in React are 10 times slower because they use DOM for that like we do plus all react overhead. But kivi ... I will need to look more exactly what is done differently...

localvoid commented 9 years ago

@Bobris Maybe it is because I am inserting nodes like this:

ref = create(vnode); // creates root level node
parent.appendChild(ref);
render(vnode); // renders subtree

instead of:

ref = render(vnode); // creates root level node and subtree
parent.appendChild(ref);
ghost commented 9 years ago

@localvoid That is likely the explanation. In a future version, I will either append the node first and update the children later or even use innerHTML in IE (which I will have to support anyway because I want to support server-side rendering too).

@Bobris I agree that we are already close to the maximum, but I wouldn't be surprised if somebody will find a technique which will change the game. For example, I am planning to experiment with parallel diffing in multiple web workers.

trueadm commented 9 years ago

@joelrich It's interesting you mention web workers. I did some playing around with them and found their overheads to be huge. Did you have any luck applying them to cito?

Bobris commented 9 years ago

I tried compared Bobril with handwritten DOM creation, and result was nearly identical. So best gain from web worker would be in case there of slow application code and minimal changes in DOM, which is hard to create realistic usecase. (and it would need completely different benchmark). Another problem is event processing which cannot be made async in current browsers.

ghost commented 9 years ago

@trueadm I made some tests and noticed that the latency of postMessage is pretty bad. There might still be an advantage for pages with ten thousands of nodes and very few changes, but I don't consider it as worth implementing at the moment.

@Bobris I am not sure if the event processing would be a problem. I think there are also other cases where it would make sense to asynchronously update the DOM. As long as the application does not try to access the DOM at inappropriate places, I think this wouldn't be a problem.

Anyway, I have made some other, more successful, experiments:

trueadm commented 9 years ago

I did some further tests on using Web Workers in general on iOS 8 last night and it really isn't worth it. I had instances where Safari would simple crash when trying to process large amounts of data – so I can't see too much validity in using Web Workers till they mature more.

Furthermore, I've found reflows to be the real killer for performance when checking the timeline on lower end devices (tablets/mobiles), specifically the different methods of changing "style" property on DOM nodes.

Bobris commented 9 years ago

@joelrich Problem with async handling of events is that, when code running outside of "click" handler is not considered user interaction, so you for example cannot start playing video.

ghost commented 9 years ago

@Bobris events would definitely have to be handled synchronously, but the dom itself can be updated asynchronously. Don't you already do that in Bobril?

Bobris commented 9 years ago

@joelrich But than you have problem with sharing virtual dom state - you don't want to copy it into webworker and back.

ghost commented 9 years ago

@Bobris I gave up about the web worker idea. The latency is just too high and syncing between the two "threads" will be annoying.