You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This isn't exactly a feature idea or proposal, more just some general thoughts that I've been meaning to get written down.
At the moment, the compiler can only operate on a single file at a time. This has the virtue of simplicity, but we're leaving some low-hanging fruit on the tree. (Well, maybe not that low-hanging. But certainly ripe and tasty.)
Take an example like this:
<!-- App.html --><Widgetfoo='bar'/><Widgetfoo='baz'/><script>importWidgetfrom'./Widget.html';exportdefault{components: { Widget }};</script><!-- Widget.html --><p>foo is {{foo}}</p>
Without us needing to specify that {{foo}} is static (see #364 for a relevant proposal), we can see that it won't ever change. So the generated code could be a bit simpler:
function create_main_fragment ( state, component ) {
var p, text, text_1_value, text_1;
return {
create: function () {
p = createElement( 'p' );
text = createText( "foo is " );
text_1 = createText( text_1_value = state.foo );
},
mount: function ( target, anchor ) {
insertNode( p, target, anchor );
appendNode( text, p );
appendNode( text_1, p );
},
- update: function ( changed, state ) {- if ( text_1_value !== ( text_1_value = state.foo ) ) {- text_1.data = text_1_value;- }- },+ update: noop,
unmount: function () {
detachNode( p );
},
destroy: noop
};
}
If the app template only had one instance of <Widget>...
<Widgetfoo='bar'/>
...it could even become this:
function create_main_fragment ( state, component ) {
- var p, text, text_1_value, text_1;+ var p, text;
return {
create: function () {
p = createElement( 'p' );
- text = createText( "foo is " );- text_1 = createText( text_1_value = state.foo );+ text = createText( "foo is bar" );
},
mount: function ( target, anchor ) {
insertNode( p, target, anchor );
appendNode( text, p );
- appendNode( text_1, p );
},
- update: function ( changed, state ) {- if ( text_1_value !== ( text_1_value = state.foo ) ) {- text_1.data = text_1_value;- }- },+ update: noop,
unmount: function () {
detachNode( p );
},
destroy: noop
};
}
Those savings (in bytes, and update performance) could add up quite nicely over an entire app. But we could go much further. In this situation we know that that the Widget doesn't need observers, event handlers and so on. In fact, we could probably do away with the component constructor altogether, and just treat <Widget> as a fragment. (We would bail out of that optimisation if we saw <Widget ref:whatever>, or event handlers that we weren't sure about, or anything else that meant someone could get a reference to the component.)
Bindings could become much simpler in this world. Code like this...
In other words, changing the input value causes input_input_handler to run, which causes the <Widget> component's set method to be called, which dispatches observers, which includes the observer function in App.js, which causes the <App> component's set method to be called, which updates the root-level state object and causes a top-down update (by-passing <Widget> because it's already updating).
That's okay, but it would be much nicer if input_input_handler could bypass the observer mechanism altogether and directly set data on the <App> component. That's possible, but only really if we consider the entire application in one go.
I'm not entirely sure what that would look like in practice. Presumably, the compiler would still operate on individual files, but would be passed information about the current component's environment and needed features. Gathering that information would be a little tricky — we can see how App.html is using Widget.html before it gets compiled (e.g. rollup-plugin-svelte can figure this out, as long as the appropriate component metadata is exposed by the compiler when App.html is compiled), but if we later discovered that a different part of the app was using Widget.html in a different way, it would be too late — compilation would have already happened. So we'd effectively need to trace component definitions ourselves, which could be tricky and probably leads to all sorts of wacky edge cases.
But worth it, if we can figure out how.
The text was updated successfully, but these errors were encountered:
This isn't exactly a feature idea or proposal, more just some general thoughts that I've been meaning to get written down.
At the moment, the compiler can only operate on a single file at a time. This has the virtue of simplicity, but we're leaving some low-hanging fruit on the tree. (Well, maybe not that low-hanging. But certainly ripe and tasty.)
Take an example like this:
Without us needing to specify that
{{foo}}
is static (see #364 for a relevant proposal), we can see that it won't ever change. So the generated code could be a bit simpler:If the app template only had one instance of
<Widget>
......it could even become this:
Those savings (in bytes, and update performance) could add up quite nicely over an entire app. But we could go much further. In this situation we know that that the
Widget
doesn't need observers, event handlers and so on. In fact, we could probably do away with the component constructor altogether, and just treat<Widget>
as a fragment. (We would bail out of that optimisation if we saw<Widget ref:whatever>
, or event handlers that we weren't sure about, or anything else that meant someone could get a reference to the component.)Bindings could become much simpler in this world. Code like this...
...results is code like this:
In other words, changing the input value causes
input_input_handler
to run, which causes the<Widget>
component'sset
method to be called, which dispatches observers, which includes theobserver
function in App.js, which causes the<App>
component'sset
method to be called, which updates the root-levelstate
object and causes a top-down update (by-passing<Widget>
because it's already updating).That's okay, but it would be much nicer if
input_input_handler
could bypass the observer mechanism altogether and directly set data on the<App>
component. That's possible, but only really if we consider the entire application in one go.I'm not entirely sure what that would look like in practice. Presumably, the compiler would still operate on individual files, but would be passed information about the current component's environment and needed features. Gathering that information would be a little tricky — we can see how
App.html
is usingWidget.html
before it gets compiled (e.g. rollup-plugin-svelte can figure this out, as long as the appropriate component metadata is exposed by the compiler whenApp.html
is compiled), but if we later discovered that a different part of the app was usingWidget.html
in a different way, it would be too late — compilation would have already happened. So we'd effectively need to trace component definitions ourselves, which could be tricky and probably leads to all sorts of wacky edge cases.But worth it, if we can figure out how.
The text was updated successfully, but these errors were encountered: