gioser

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 5544Rust 88Markdown 11TOML 91926 Definitions

WIP: 0.3.0 release (#357)

* Update README description for 0.3.0

* Bump version number to 0.3.0

* Merge alpha1 and alpha2 release notes

* Convert style helpers to a table

* Add newlines to style helper table

* Add more track sizing functions

* Fully verbose style helper works with section

* Orient style helpers table by type rather than helper

* Add highlights

* Fix link

* Allow inline HTML in markdown

* Fix link

* Remove style changes from highlights

* Remove multiple blank lines to make linter happy

* Format old benchmarks

* Add new benchmark run

* Add percentage change to benchmark results

* Correct benchmarks in 0.2 release notes from later run

* Update benchmarks in README

* Fix markdownlint

* Add learning resources to README

* Reword README intro

* Add newline to intro

* Move learning resources below usage

* Remove complex/generated benchmark results

868b3a47e525b3480d0bd3a4207a7ebc1c9db470 · by Nico Burns · (3 years ago) · parent 8eee4f420 · browse the tree at this commit

Semantic delta

No definition changed: this change is text, documentation or data.

6 files · +223 −116

diff --git a/.github/linters/.markdown-lint.yml b/.github/linters/.markdown-lint.yml
index 760686631..e7264e68d 100644
--- a/.github/linters/.markdown-lint.yml
+++ b/.github/linters/.markdown-lint.yml
@@ -27,3 +27,4 @@
 # blank_lines: false  # Error on blank lines
 line_length: false # Ignore excessively long lines
 no-duplicate-heading: false # This is useful in RELEASES.md
+no-inline-html: false # Needed to create complex tables
diff --git a/Cargo.toml b/Cargo.toml
index a194f481e..64c6c6ebf 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "taffy"
-version = "0.3.0-alpha1"
+version = "0.3.0"
 authors = [
     "Alice Cecile <alice.i.cecile@gmail.com>",
     "Johnathan Kelley <jkelleyrtp@gmail.com>",
diff --git a/README.md b/README.md
index 4323f7ae3..f9965346e 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,12 @@
-# taffy
+# Taffy
 
 [![GitHub CI](https://github.com/DioxusLabs/taffy/actions/workflows/ci.yml/badge.svg)](https://github.com/DioxusLabs/taffy/actions/workflows/ci.yml)
 [![crates.io](https://img.shields.io/crates/v/taffy.svg)](https://crates.io/crates/taffy)
 [![docs.rs](https://img.shields.io/docsrs/taffy)](https://docs.rs/taffy)
 
-`taffy` is a flexible, high-performance, cross-platform UI layout library written in [Rust](https://www.rust-lang.org).
+Taffy is a flexible, high-performance, cross-platform UI layout library written in [Rust](https://www.rust-lang.org).
 
-Currently Taffy implements only CSS based layout algorithms:
-
-- The stable `0.2.x` releases of Taffy implements the [flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) layout algorithm.
-- Support for [CSS Grid](https://css-tricks.com/snippets/css/complete-guide-grid/) is in preview. If you wish to try this out then you should use the `0.3.x` alpha releases ~and enable the `experimental_grid` cargo feature~ (from `0.3.0-alpha2` the CSS Grid feature is enabled by default). For information, see the [release notes](https://github.com/DioxusLabs/taffy/blob/main/RELEASES.md) and the [tracking issue](https://github.com/DioxusLabs/taffy/issues/204). Experimentation with the CSS Grid implementation is encouraged, and feedback and bug reports are welcomed.
-
-Support for other paradigms [is planned](https://github.com/DioxusLabs/taffy/issues/28).
+It currently implements the **Flexbox** and **CSS Grid** layout algorithms. Support for other paradigms is planned. For more information on this and other future development plans see the [roadmap issue](https://github.com/DioxusLabs/taffy/issues/345).
 
 This crate is a collaborative, cross-team project, and is designed to be used as a dependency for other UI and GUI libraries.
 Right now, it powers:
@@ -71,6 +66,22 @@ assert_eq!(taffy.layout(body_node).unwrap().size.height, 500.0); // This value w
 
 ```
 
+## Learning Resources
+
+Taffy implements the Flexbox and CSS Grid specifications faithfully, so documentation designed for the web should translate cleanly to Taffy's implementation. For reference documentation on individual style properties we recommend the MDN documentation (for example [this page](https://developer.mozilla.org/en-US/docs/Web/CSS/width) on the `width` property). Such pages can usually be found by searching for "MDN property-name" using a search engine.
+
+If you are interested in guide-level documentation on CSS layout, then we recommend the following resources:
+
+### Flexbox
+
+- [Flexbox Froggy](https://flexboxfroggy.com/). This is an interactive tutorial/game that allows you to learn the essential parts of Flebox in a fun engaging way.
+- [A Complete Guide To Flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) by CSS Tricks. This is detailed guide with illustrations and comphrehensive written explanation of the different Flexbox properties and how they work.
+
+### CSS Grid
+
+- [CSS Grid Garden](https://cssgridgarden.com/). This is an interactive tutorial/game that allows you to learn the essential parts of CSS Grid in a fun engaging way.
+- [A Complete Guide To CSS Grid](https://css-tricks.com/snippets/css/complete-guide-grid/) by CSS Tricks. This is detailed guide with illustrations and comphrehensive written explanation of the different CSS Grid properties and how they work.
+
 ## Benchmarks (vs. [Yoga](https://github.com/facebook/yoga))
 
 - Run on a 2021 MacBook Pro with M1 Pro processor using [criterion](https://github.com/bheisler/criterion.rs)
@@ -78,23 +89,23 @@ assert_eq!(taffy.layout(body_node).unwrap().size.height, 500.0); // This value w
 - Yoga benchmarks were run via the [yoga](https://github.com/bschwind/yoga-rs) crate (Rust bindings)
 - Most popular websites seem to have between 3,000 and 10,000 nodes (although they also require text layout, which neither yoga nor taffy implement).
 
-Note that the table below contains multiple different units (milliseconds vs. microseconds
+Note that the table below contains multiple different units (milliseconds vs. microseconds)
 
-| Benchmark          | Node Count | Depth | Yoga ([ba27f9d]) | Taffy ([9059647]) |
+| Benchmark          | Node Count | Depth | Yoga ([ba27f9d]) | Taffy ([71027a8]) |
 | ---                | ---        | ---   | ---              | ---               |
-| yoga 'huge nested' | 1,000      | 3     | 411.42 µs        | 275.47 µs         |
-| yoga 'huge nested' | 10,000     | 4     | 3.9882 ms        | 3.9409 ms         |
-| yoga 'huge nested' | 100,000    | 5     | 46.117 ms        | 32.458 ms         |
-| big trees (wide)   | 1,000      | 1     | 750.75 µs        | 571.35 µs         |
-| big trees (wide)   | 10,000     | 1     | 7.1639 ms        | 7.4838 ms         |
-| big trees (wide)   | 100,000    | 1     | 132.17 ms        | 245.16 ms         |
-| big trees (deep)   | 4,000      | 12    | 2.3140 ms        | 2.0300 ms         |
-| big trees (deep)   | 10,000     | 14    | 6.0009 ms        | 5.1872 ms         |
-| big trees (deep)   | 100,000    | 17    | 76.954 ms        | 74.946 ms         |
-| super deep         | 1,000      | 1,000 | 563.15 µs        | 548.97 µs         |
+| yoga 'huge nested' | 1,000      | 3     | 364.60 µs        | 329.04 µs         |
+| yoga 'huge nested' | 10,000     | 4     | 4.1988 ms        | 4.3486 ms         |
+| yoga 'huge nested' | 100,000    | 5     | 45.804 ms        | 38.559 ms         |
+| big trees (wide)   | 1,000      | 1     | 737.77 µs        | 505.99 µs         |
+| big trees (wide)   | 10,000     | 1     | 7.1007 ms        | 8.3395 ms         |
+| big trees (wide)   | 100,000    | 1     | 135.78 ms        | 247.42 ms         |
+| big trees (deep)   | 4,000      | 12    | 2.2333 ms        | 1.7400 ms         |
+| big trees (deep)   | 10,000     | 14    | 5.9477 ms        | 4.4445 ms         |
+| big trees (deep)   | 100,000    | 17    | 76.755 ms        | 63.778 ms         |
+| super deep         | 1,000      | 1,000 | 555.32 µs        | 472.85 µs         |
 
 [ba27f9d]: https://github.com/facebook/yoga/commit/ba27f9d1ecfa7518019845b84b035d3d4a2a6658
-[9059647]: https://github.com/DioxusLabs/taffy/commit/ba27f9d1ecfa7518019845b84b035d3d4a2a6658
+[71027a8]: https://github.com/DioxusLabs/taffy/commit/71027a8de03b343e120852b84bb7dca9fb4651c5
 
 ## Contributions
 
diff --git a/RELEASES.md b/RELEASES.md
index e6e27298b..95b9d964f 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,43 +1,17 @@
 # Release Notes
 
-## 0.3.0-alpha2 (unreleased)
+## 0.3.0
 
-### Added
+### Highlights
 
-- A new style helper `evenly_sized_tracks(count: u16)` has been added which creates a grid template containing `count` evenly sized tracks (rows or columns)
+- [CSS Grid algorithm support](#new-feature-css-grid)
+- [Style helper functions](#new-feature-style-helpers)
 
-### Changed
+See below for details of breaking changes.
 
-- `experimental_grid` feature named to just `grid`
-- `grid` feature enabled by default
-- `GridPlacement::Line` now stores a `GridLine` newtype wrapper around an `i16` rather than a raw `i16`. If you are using the style helpers then this change will not affect you.
-- *BREAKING:* `Position` is now renamed to `Inset` and is now in line with [CSS inset specs](https://developer.mozilla.org/en-US/docs/Web/CSS/inset)
-- *BREAKING:* `PositionType` is now renamed to `Position` and is now in line with [CSS position specs](https://developer.mozilla.org/en-US/docs/Web/CSS/position)
-- `MaxTrackSizingFunction::Flex` is now called `MaxTrackSizingFunction::Fraction`. The `flex()` helper is now called `fr()`. A new `flex()` helper has been added which create a `minmax(0, Nfr)` track.
+### New Feature: CSS Grid
 
-### Fixes
-
-- Flexbox nodes sized under a min-content constraint now size correctly (#291)
-- Aspect ratio is now applied correctly in many circumstances
-- Absolutely positioned items now apply margins correctly
-- Min/max size are now applied correctly
-- Inset applied incorrectly to relatively positioned flexbox children when both `top` and `bottom` or `left` and `right` were specified (#348)
-
-### Removed
-
-- Removed `top_from_points`, `bot_from_points`, `top_from_percent`, and `bot_from_percent` methods removed from `Rect<Dimension>`. These functions were incredibly specific for an unusual use case, so we would be surprised if anyone was using them. Please use the new style helpers instead.
-- Removed `min_main_size`, `max_main_size`, `min_cross_size`, `max_cross_size`, and `cross_size` methods from `Style`. Use the more general `cross` and `main` methods directly on the `size`, `min_size`, and `max_size` properties instead.
-- Removed `main_margin_start`, `main_margin_end`, `cross_margin_start`, `cross_margin_end` from `Style`. Use the more general `main_start`, `main_end`, `cross_start`, and `cross_end` on the `margin` property instead.
-
-## 0.3.0-alpha1
-
-This is the first in a series of planned alpha releases to allow users of Taffy to try out the new CSS Grid layout mode in advance of a stable release. We hope that by marking this is alpha release we are clearly communicating that this a pre-release and that the implementation is not yet of production quality. But we never-the-less encourage you to try it out. Feedback is welcome, and bug reports for the Grid implementation are being accepted as of this release.
-
-~**Note: CSS Grid support must be enabled using the `experimental_grid` feature. For the time being this feature is not enabled by default.**~ From `0.3.0-alpha2`, the CSS Grid feature is now enabled by default.
-
-### New Feature: CSS Grid (Experimental)
-
-We very excited to report that we have an initial version of the CSS Grid layout available. This is in addition to the existing Flexbox layout support, and the two modes interoperate (although this interaction has not been extensively tested). You can set a node to use Grid layout by setting the `display` property to `Display::Grid`.
+We very excited to report that we now have support for CSS Grid layout. This is in addition to the existing Flexbox layout support, and the two modes interoperate. You can set a node to use Grid layout by setting the `display` property to `Display::Grid`.
 
 #### Learning Resources
 
@@ -87,15 +61,10 @@ And the following Grid style properties are supported on Grid Items (children):
 [`align-self`]: https://developer.mozilla.org/en-US/docs/Web/CSS/align-self
 [`justify-self`]: https://developer.mozilla.org/en-US/docs/Web/CSS/justify-self
 
-The following properties and features are not yet supported, but are planned for the near future:
-
-- Baseline alignment
-- `fit-content()` with a percentage argument.
-- `repeat()` with integer repetition (but users of Taffy can just expand these definition manually)
-
-The following properties and features are not supported, and there are no immediate plans to implement them:
+The following properties and features are not currently supported:
 
 - Subgrids
+- Masonry grid layout
 - Named grid lines
 - Named areas: `grid-template-areas` and `grid-area`
 - `grid-template` or `grid` shorthand
@@ -130,27 +99,104 @@ And that same helper function will work other types like `LengthPercentage` and
 let size : Size<Dimension> = points(100.0);
 ```
 
-The following functions work for `Dimension`, `LengthPercentageAuto`, `LengthPercentage`, `AvailableSpace` and for Grid track sizing functions
-
-- `points(f32)` - Generates a `Points` variant with the specified value
-- `zero()` - Generates a `Points` variant with the value `0.0`.
-
-The following functions work for `Dimension`, `LengthPercentageAuto`, `LengthPercentage` and for Grid track sizing functions
-
-- `percent(f32)` - Generates a `Percent` value
-- `auto()` - Generates an `Auto` variant
-
-The following functions work for `AvailableSpace` and grid track sizing functions:
-
-- `min_content()` - Generates an `MinContent` variant
-- `max_content()` - Generates an `MaxContent` variant
-
-The following functions currently work only for grid track sizing functions:
-
-- `flex(f32)` - Genrates a `Flex` variant with the specified flex fraction
-- `fit_content(LengthPercentage)` - Generates a `FitContent` variant with the specified limit. Nest `points` or `percent` inside this function to specified the limit.
-- `minmax(MinTrackSizingFunction, MaxTrackSizingFunction)` - Generates a track sizing function with different min and max sizing functions. Nest `points`, `percent`, `auto`, `min_content`, `max_content`, or `flex` to specify the min and max functions.
-- `repeat(GridTrackRepetition, Vec<TrackSizingFunction>)` - Genereate an auto-repeating track definition.
+Available style helpers:
+
+<table>
+  <thead><tr><th>Type(s)</th><th colspan="2">Helpers that work with that type</th></tr></thead>
+  <tbody>
+    <tr>
+      <td rowspan="3"><code>LengthPercentage</code></td>
+      <td><code>zero()</code></td>
+      <td>Generates a <code>Points</code> variant with the value <code>0.0</code></td>
+    </tr>
+    <tr>
+      <td><code>points(val:&nbsp;f32)</code></td>
+      <td>Generates a <code>Points</code> variant with the specified value</td>
+    </tr>
+    <tr>
+      <td><code>percent(val:&nbsp;f32)</code></td>
+      <td>Generates a <code>Percent</code> variant with the specified value.<br />Note that the scale of 0-1 not 0-100.</td>
+    </tr>
+    <tr>
+      <td rowspan="2"><code>LengthPercentageAuto</code><br /><code>Dimension</code></td>
+      <td colspan="2"><i>All helpers from <code>LengthPercentage</code> and...</i></td>
+    </tr>
+    <tr>
+      <td><code>auto()</code></td>
+      <td>Generates an <code>Auto</code> variant</td>
+    </tr>
+    <tr>
+      <td rowspan="3"><code>MinTrackSizingFunction</code></td>
+      <td colspan="2"><i>All helpers from <code>LengthPercentageAuto</code>/<code>Dimension</code> and...</i></td>
+    </tr>
+    <tr>
+      <td><code>min_content()</code></td>
+      <td>Generates an <code>MinContent</code> variant</td>
+    </tr>
+      <tr>
+      <td><code>max_content()</code></td>
+      <td>Generates an <code>MinContent</code> variant</td>
+    </tr>
+    <tr>
+      <td rowspan="3"><code>MaxTrackSizingFunction</code></td>
+      <td colspan="2"><i>All helpers from <code>MinTrackSizingFunction</code> and...</i></td>
+    </tr>
+    <tr>
+      <td><code>fit_content(limit:&nbsp;LengthPercentage)</code></td>
+      <td>Generates a <code>FitContent</code> variant with the specified limit.<br />Nest the <code>points</code> or <code>percent</code> helper inside this function to specified the limit.</td>
+    </tr>
+      <tr>
+      <td><code>fr(fraction:&nbsp;f32)</code></td>
+      <td>Generates a <code>Fraction</code> (<code>fr</code>) variant with the specified flex fraction </td>
+    </tr>
+    <tr>
+      <td rowspan="3"><code>NonRepeatingTrackSizingFunction</code></td>
+      <td colspan="2"><i>All helpers from <code>MaxTrackSizingFunction</code> and...</i></td>
+    </tr>
+    <tr>
+      <td><code>minmax(min: MinTrackSizingFunction, max: MaxTrackSizingFunction)</code></td>
+      <td>Equivalent to CSS <code>minmax()</code> function.</td>
+    </tr>
+    <tr>
+      <td><code>flex(fraction:&nbsp;f32)</code></td>
+      <td>Equivalent to CSS <code>minmax(0px, 1fr)</code>. This is likely what you want if you want evenly sized rows/columns.</td>
+    </tr>
+    <tr>
+      <td rowspan="2"><code>TrackSizingFunction</code></td>
+      <td colspan="2"><i>All helpers from <code>NonRepeatingTrackSizingFunction</code> and...</i></td>
+    </tr>
+    <tr>
+      <td><code>repeat(rep: GridTrackRepetition, tracks: Vec&lt;TrackSizingFunction&gt;)</code></td>
+      <td>Equivalent to css <code>repeat()</code> function.</td>
+    </tr>
+    <tr>
+      <td><code>Vec&lt;TrackSizingFunction&gt;</code></td>
+      <td><code>evenly_sized_tracks(count:&nbsp;u16)</code></td>
+      <td>Equivalent to CSS <code>repeat(count, minmax(0px, 1fr)</code></td>
+    </tr>
+    <tr>
+      <td rowspan="3"><code>AvailableSpace</code></td>
+      <td><code>auto()</code></td>
+      <td>Generates an <code>Auto</code> variant</td>
+    </tr>
+    <tr>
+      <td><code>min_content()</code></td>
+      <td>Generates an <code>MinContent</code> variant</td>
+    </tr>
+      <tr>
+      <td><code>max_content()</code></td>
+      <td>Generates an <code>MinContent</code> variant</td>
+    </tr>
+    <tr>
+      <td><code>Size&lt;T&gt;</code></td>
+      <td colspan="2">Any helper that works for <code>T</code> will also work for <code>Size&lt;T&gt;</code> and will set both <code>width</code> and <code>height</code> to that value</td>
+    </tr>
+    <tr>
+      <td><code>Rect&lt;T&gt;</code></td>
+      <td colspan="2">Any helper that works for <code>T</code> will also work for <code>Rect&lt;T&gt;</code> and will set <code>top</code>, <code>left</code>, <code>bottom</code>, and <code>right</code> to that value</td>
+    </tr>
+  </tbody>
+</table>
 
 ### Breaking API changes
 
@@ -172,6 +218,11 @@ The following functions currently work only for grid track sizing functions:
   - `LengthPercentageAuto` is currently identical to `Dimension` but will allow us to expand dimension in future to support values like `MinContent`, `MaxContent` and `FitContent`.
 - Some style properties have been updated to use either `LengthPercentage` or `LengthPercentageAuto` instead of `Dimension`. You will need to update your code, but it is recommended that you use the new style helpers (see above) rather than using the new types directly (although you certainly can use them directly if you want to).
 
+#### Position properties renamed
+
+- The `position` property is now renamed to `inset` and is now in line with [CSS inset specs](https://developer.mozilla.org/en-US/docs/Web/CSS/inset)
+- The `position_type` property is now renamed to `position` and is now in line with [CSS position specs](https://developer.mozilla.org/en-US/docs/Web/CSS/position). The `PositionType` enum has been similarly renamed to `Position`.
+
 #### Changes to `LayoutTree`
 
 - Added generic associated type to `LayoutTree` for a `ChildIter`, an iterator on the children of a given node.
@@ -185,8 +236,19 @@ The `AvailableSpace` enum has been moved from the `layout` module to the `style`
 
 ### Fixes
 
+- Flexbox nodes sized under a min-content constraint now size correctly (#291)
+- Aspect ratio is now applied correctly in many circumstances
+- Absolutely positioned items now apply margins correctly
+- Min/max size are now applied correctly
+- Inset applied incorrectly to relatively positioned flexbox children when both `top` and `bottom` or `left` and `right` were specified (#348)
 - Fix case where column-gap style could be used in place of row-gap style (when using a percentage gap with an indefinite container size)
 
+### Removed
+
+- Removed `top_from_points`, `bot_from_points`, `top_from_percent`, and `bot_from_percent` methods removed from `Rect<Dimension>`. These functions were incredibly specific for an unusual use case, so we would be surprised if anyone was using them. Please use the new style helpers instead.
+- Removed `min_main_size`, `max_main_size`, `min_cross_size`, `max_cross_size`, and `cross_size` methods from `Style`. Use the more general `cross` and `main` methods directly on the `size`, `min_size`, and `max_size` properties instead.
+- Removed `main_margin_start`, `main_margin_end`, `cross_margin_start`, `cross_margin_end` from `Style`. Use the more general `main_start`, `main_end`, `cross_start`, and `cross_end` on the `margin` property instead.
+
 ## 0.2.2
 
 ### Fixes
@@ -226,15 +288,15 @@ A number of performance improvements have landed since taffy 0.1:
 
 #### Benchmarks vs. Taffy 0.1
 
-| Benchmark | Taffy 0.1 | Taffy 0.2 | % change (0.1 -> 0.2) |
-| --- | --- | --- | --- |
-| wide/1_000 nodes (2-level hierarchy) | 3.5458 µs | 4.3571 µs | +23.333% |
-| wide/10_000 nodes (2-level hierarchy) | 36.418 µs | 42.967 µs | +17.357% |
-| wide/100_000 nodes (2-level hierarchy) | 1.8275 ms | 3.9096 ms | +112.26% |
-| deep/4000 nodes (12-level hierarchy)) | 5.1845 s | 15.318 µs | -100.000% |
-| deep/10_000 nodes (14-level hierarchy) | 75.978 s | 40.315 µs | -100.000% |
-| deep/100_000 nodes (17-level hierarchy) | - | 2.7644 ms| - |
-| deep/1_000_000 nodes (20-level hierarchy) | - | 1.2130 s| - |
+| Benchmark                                 | Taffy 0.1 | Taffy 0.2 | % change (0.1 -> 0.2) |
+| ---                                       | ---       | ---       | ---                   |
+| wide/1_000 nodes (2-level hierarchy)      | 699.18 µs | 445.01 µs | -36.279%              |
+| wide/10_000 nodes (2-level hierarchy)     | 8.8244 ms | 7.1313 ms | -16.352%              |
+| wide/100_000 nodes (2-level hierarchy)    | 204.48 ms | 242.93 ms | +18.803%              |
+| deep/4000 nodes (12-level hierarchy))     | 5.2320 s  | 2.7363 ms | -99.947%              |
+| deep/10_000 nodes (14-level hierarchy)    | 75.207 s  | 6.9415 ms | -99.991%              |
+| deep/100_000 nodes (17-level hierarchy)   | -         | 102.72 ms | -                     |
+| deep/1_000_000 nodes (20-level hierarchy) | -         | 799.35 ms | -                     |
 
 (note that the table above contains multiple different units (milliseconds vs. microseconds vs. nanoseconds))
 
diff --git a/benches/results-2022-12-07.md b/benches/results-2022-12-07.md
index cec319998..1b0a49ddf 100644
--- a/benches/results-2022-12-07.md
+++ b/benches/results-2022-12-07.md
@@ -6,27 +6,23 @@
 - Taffy benchmarks are using criterion (10 iterations).
 - Yoga benchmarks run via the `yoga-layout-prebuilt` npm package, they were run a few times manually and it was verified that variance in the numbers of each run was minimal. It should be noted that this is using an old version of Yoga.
 
-| Benchmark | Yoga | Taffy 0.1 | Taffy 0.2 | % change (0.1 -> 0.2) |
-| --- | --- | --- | --- | --- |
-| yoga/10 nodes (1-level hierarchy) | 45.1670 µs | 2.2851 µs | 2.0787 µs | -9.3338% |
-| yoga/100 nodes (2-level hierarchy) | 134.1250 µs | 75.518 µs | 41.022 µs | -46.577% |
-| yoga/1_000 nodes (3-level hierarchy) | 1.2221 ms | 1.7794 ms | 355.50 µs | -79.608% |
-| yoga/10_000 nodes (4-level hierarchy) | 13.8672 ms | 52.117 ms | 3.6848 ms | -92.968% |
-| yoga/100_000 nodes (5-level hierarchy) | 141.5307 ms | 1.5626 s | 39.830 ms | -97.459% |
-| yoga /1_000_000 nodes (6-level hierarchy) | -  | - | 384.19 ms | - |
-| wide/10 nodes (2-level hierarchy) | - | 6.1508 µs | 4.1094 µs | -33.923% |
-| wide/100 nodes (2-level hierarchy) | - | 66.602 µs | 41.056 µs | -35.742% |
-| wide/1_000 nodes (2-level hierarchy) | - | 699.18 µs | 445.01 µs | -36.279% |
-| wide/10_000 nodes (2-level hierarchy) | - | 8.8244 ms | 7.1313 ms | -16.352% |
-| wide/100_000 nodes (2-level hierarchy) | - | 204.48 ms | 242.93 ms | +18.803% |
-| semi-wide/100_000 nodes (7-level hierarchy) | - | 2.6539 s | 69.141 ms | -97.402% |
-| deep/4000 nodes (12-level hierarchy)) | - | 5.2320 s | 2.7363 ms | -99.947% |
-| deep/10_000 nodes (14-level hierarchy) | - | 75.207 s | 6.9415 ms | -99.991% |
-| deep/100_000 nodes (17-level hierarchy) | - | - | 102.72 ms| - |
-| deep/1_000_000 nodes (20-level hierarchy) | - | - | 799.35 ms | - |
-| super-deep/100 nodes (100-level hierarchy) | - | - | 111.26 µs | - |
-| super-deep/1000 nodes (1000-level hierarchy) | - | - | 1.1746 ms | - |
-| deep hierarchy/build  | - | 1.5060 µs | 616.12 ns | -1.5167% |
-| deep hierarchy/single | - | 7.1453 µs | 4.5461 µs | -0.5156% |
-| deep hierarchy/relayout | - | 3.7863 µs | 2.1275 µs | -1.0900% |
-| generated benchmarks  | - | 255.83 µs | 221.73 µs | -13.125% |
+| Benchmark                                    | Yoga        | Taffy 0.1 | Taffy 0.2 | % change (0.1 -> 0.2) |
+| ---                                          | ---         | ---       | ---       | ---                   |
+| yoga/10 nodes (1-level hierarchy)            | 45.1670 µs  | 2.2851 µs | 2.0787 µs | -9.3338%              |
+| yoga/100 nodes (2-level hierarchy)           | 134.1250 µs | 75.518 µs | 41.022 µs | -46.577%              |
+| yoga/1_000 nodes (3-level hierarchy)         | 1.2221 ms   | 1.7794 ms | 355.50 µs | -79.608%              |
+| yoga/10_000 nodes (4-level hierarchy)        | 13.8672 ms  | 52.117 ms | 3.6848 ms | -92.968%              |
+| yoga/100_000 nodes (5-level hierarchy)       | 141.5307 ms | 1.5626 s  | 39.830 ms | -97.459%              |
+| yoga /1_000_000 nodes (6-level hierarchy)    | -           | -         | 384.19 ms | -                     |
+| wide/10 nodes (2-level hierarchy)            | -           | 6.1508 µs | 4.1094 µs | -33.923%              |
+| wide/100 nodes (2-level hierarchy)           | -           | 66.602 µs | 41.056 µs | -35.742%              |
+| wide/1_000 nodes (2-level hierarchy)         | -           | 699.18 µs | 445.01 µs | -36.279%              |
+| wide/10_000 nodes (2-level hierarchy)        | -           | 8.8244 ms | 7.1313 ms | -16.352%              |
+| wide/100_000 nodes (2-level hierarchy)       | -           | 204.48 ms | 242.93 ms | +18.803%              |
+| semi-wide/100_000 nodes (7-level hierarchy)  | -           | 2.6539 s  | 69.141 ms | -97.402%              |
+| deep/4000 nodes (12-level hierarchy))        | -           | 5.2320 s  | 2.7363 ms | -99.947%              |
+| deep/10_000 nodes (14-level hierarchy)       | -           | 75.207 s  | 6.9415 ms | -99.991%              |
+| deep/100_000 nodes (17-level hierarchy)      | -           | -         | 102.72 ms | -                     |
+| deep/1_000_000 nodes (20-level hierarchy)    | -           | -         | 799.35 ms | -                     |
+| super-deep/100 nodes (100-level hierarchy)   | -           | -         | 111.26 µs | -                     |
+| super-deep/1000 nodes (1000-level hierarchy) | -           | -         | 1.1746 ms | -                     |
diff --git a/benches/results-2023-02-08.md b/benches/results-2023-02-08.md
new file mode 100644
index 000000000..5c0d7bfc8
--- /dev/null
+++ b/benches/results-2023-02-08.md
@@ -0,0 +1,37 @@
+# Benchmarks (Taffy 0.3 and Yoga)
+
+- Taffy `0.2` results come from commit `456653c2c618ea2b3390c4d717c38edbdf684ae4`
+- Taffy `0.3` and Yoga results come from commit `71027a8de03b343e120852b84bb7dca9fb4651c5`
+- Yoga benchmarks are run using version `0.4.0` of the `yoga` crate
+- Run on a 2021 MacBook Pro with M1 Pro processor.
+- Taffy benchmarks are using criterion (10 iterations).
+
+## Flexbox Benchmarks
+
+| Benchmark                                    | Yoga      | Taffy 0.2 | Taffy 0.3 | % change (0.2 -> 0.3) |
+| ---                                          | ---       | ---       | ---       | ---                   |
+| yoga/1_000 nodes (3-level hierarchy)         | 402.58 µs | 364.60 µs | 329.04 µs | -                     |
+| yoga/10_000 nodes (4-level hierarchy)        | 4.1988 ms | 3.6236 ms | 4.3486 ms | +20.01%               |
+| yoga/100_000 nodes (5-level hierarchy)       | 45.804 ms | 39.467 ms | 38.559 ms | -                     |
+| wide/1_000 nodes (2-level hierarchy)         | 737.77 µs | 470.52 µs | 505.99 µs | -                     |
+| wide/10_000 nodes (2-level hierarchy)        | 7.1007 ms | 7.1008 ms | 8.3395 ms | +17.44%               |
+| wide/100_000 nodes (2-level hierarchy)       | 135.78 ms | 241.34 ms | 247.42 ms | -                     |
+| deep/4000 nodes (12-level hierarchy))        | 2.2333 ms | 4.7362 ms | 1.7400 ms | -63.26%               |
+| deep/10_000 nodes (14-level hierarchy)       | 5.9477 ms | 10.729 ms | 4.4445 ms | -58.57%               |
+| deep/100_000 nodes (17-level hierarchy)      | 76.755 ms | 151.53 ms | 63.778 ms | -57.91%               |
+| super-deep/1000 nodes (1000-level hierarchy) | 555.32 µs | 1.6444 ms | 472.85 µs | -71.24%               |
+
+## CSS Grid Benchmarks
+
+`NxN/12345` signifies that each node is an N by N grid, and that there are 12345 total nodes in the tree.
+
+| Benchmark                                    | Taffy 0.3 |
+| ---                                          | ---       |
+| grid/wide/31x31/961                          | 491.65 µs |
+| grid/wide/100x100/10000                      | 7.0741 ms |
+| grid/wide/316x316/99856                      | 104.54 ms |
+| grid/deep/2x2/1024                           | 1.6624 ms |
+| grid/deep/3x3/6561                           | 8.1927 ms |
+| grid/deep/2x2/16384                          | 32.700 ms |
+| grid/superdeep/1x1/100                       | 172.83 µs |
+| grid/superdeep/1x1/1000                      | 2.0197 ms |