solidart icon indicating copy to clipboard operation
solidart copied to clipboard

feat/v2.0.0

Open nank1ro opened this issue 2 years ago • 4 comments

  • CHORE: Improved Solid widget performance by more than 3000% in finding ancestor providers. During my performance tests, before I was able to observe up to 71 signals (provided through Solid) per second, now this numbers increased to 2159 signals per second.

  • FEAT: The SignalBuilder widget now automatically tracks the Signals used in the builder function allowing you to react to any number of signals at the same time. Before:

    SignalBuilder(
      signal: counter,
      builder: (context, value, child) {
        return Text('$value');
      },
    ),
    

    Now:

    SignalBuilder(
      builder: (context, child) {
        return Text('${counter.value}');
      },
    ),
    
  • BREAKING CHANGE: Removed DualSignalBuilder and TripleSignalBuilder in favor of SignalBuilder.

  • BREAKING CHANGE the context.observe methods (due to the performance improvements of the Solid widget) now needs the type of signal Before:

    final counter = context.observe<int>();
    

    Now:

    final counter = context.observe<int, Signal<int>>();
    // or
    final counter = context.observeSignal<int>();
    

    So this change includes the new observeSignal, observeReadSignal, observeComputed, observeResource, observeListSignal, observeSetSignal and observeMapSignal

    The PR has still some problems:

    1. The auto dispose of signals happens when using SignalBuilder because the effect tracks the dependencies in the build method. This is necessary to make it performant but, for a little moment, the signals will not be watched by the Effect. I still need to find a way to fix this.
    2. I don't know if context.observe<T, S> still be exposed, due to the new specific observe methods.
    3. Still waiting for the v2 of SolidJS that may happen at the end of January 2024, this could improve the performance of the automatic tracking system significantly (https://github.com/bubblegroup/bubble-reactivity)

    TODOs

    • [ ] fix unit tests
    • [ ] update solidart_lint
    • [ ] update docs

nank1ro avatar Jan 02 '24 11:01 nank1ro

Note that SignalBuilder has a hidden footgun that will catch some users. Any signals accessed in its entire subtree will trigger a rebuild in the parent.

SignalBuilder
  |_ Container
      |_ Column
            |_ SizedBox
                 |_ SignalBuilder
                       |_ Text  <- signal watched here will rebuild both SignalBuilders

zupat avatar Jan 02 '24 12:01 zupat

Note that SignalBuilder has a hidden footgun that will catch some users. Any signals accessed in its entire subtree will trigger a rebuild in the parent.


SignalBuilder

  |_ Container

      |_ Column

            |_ SizedBox

                 |_ SignalBuilder

                       |_ Text  <- signal watched here will rebuild both SignalBuilders

Thanks for reporting 🙏, need to investigate further to fix this

nank1ro avatar Jan 02 '24 13:01 nank1ro

@jinyus can't reproduce the issue, this is the code I used to test

import 'package:flutter/material.dart';
import 'package:flutter_solidart/flutter_solidart.dart';

final a = Signal(0);
final b = Signal(100);

class TestPage extends StatelessWidget {
  const TestPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SignalBuilder(
        builder: (_, __) {
          print('build a');
          return Column(
            children: [
              Text(a().toString()),
              const Second(),
            ],
          );
        },
      ),
      floatingActionButton: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          TextButton(
            onPressed: () => a.value++,
            child: const Text('add to A'),
          ),
          TextButton(
            onPressed: () => b.value++,
            child: const Text('add to B'),
          ),
        ],
      ),
    );
  }
}

class Second extends StatelessWidget {
  const Second({super.key});

  @override
  Widget build(BuildContext context) {
    return SignalBuilder(
      builder: (_, __) {
        print('build b');
        return Text(b().toString());
      },
    );
  }
}

Can you share your code please?

nank1ro avatar Jan 02 '24 13:01 nank1ro

I'm no longer seeing this bug. I will have to investigate further. Consider this a non-issue for now.

zupat avatar Jan 02 '24 14:01 zupat

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Please upload report for BASE (dev@e3bd529). Learn more about missing BASE report.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             dev       #85   +/-   ##
=======================================
  Coverage       ?   100.00%           
=======================================
  Files          ?        21           
  Lines          ?      1166           
  Branches       ?         0           
=======================================
  Hits           ?      1166           
  Misses         ?         0           
  Partials       ?         0           
Files Coverage Δ
...utter_solidart/lib/src/utils/solid_extensions.dart 100.00% <100.00%> (ø)
...ackages/flutter_solidart/lib/src/widgets/show.dart 100.00% <100.00%> (ø)
...utter_solidart/lib/src/widgets/signal_builder.dart 100.00% <100.00%> (ø)
...ckages/flutter_solidart/lib/src/widgets/solid.dart 100.00% <100.00%> (ø)
packages/solidart/lib/src/core/atom.dart 100.00% <100.00%> (ø)
packages/solidart/lib/src/core/batch.dart 100.00% <100.00%> (ø)
packages/solidart/lib/src/core/effect.dart 100.00% <100.00%> (ø)
...ckages/solidart/lib/src/core/reactive_context.dart 100.00% <100.00%> (ø)
packages/solidart/lib/src/core/read_signal.dart 100.00% <100.00%> (ø)
packages/solidart/lib/src/core/resource.dart 100.00% <ø> (ø)
... and 1 more

codecov[bot] avatar May 30 '24 09:05 codecov[bot]