{"id":16014885,"url":"https://github.com/thheller/js-framework-shadow-grove","last_synced_at":"2025-04-05T02:43:17.425Z","repository":{"id":140236994,"uuid":"340983959","full_name":"thheller/js-framework-shadow-grove","owner":"thheller","description":null,"archived":false,"fork":false,"pushed_at":"2024-05-20T16:20:45.000Z","size":2530,"stargazers_count":16,"open_issues_count":0,"forks_count":0,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-02-10T11:11:42.799Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thheller.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-21T19:20:39.000Z","updated_at":"2024-06-07T15:48:43.000Z","dependencies_parsed_at":"2024-02-25T16:43:33.876Z","dependency_job_id":"96af04b8-9ba2-498d-80fd-2a41b3558a61","html_url":"https://github.com/thheller/js-framework-shadow-grove","commit_stats":{"total_commits":37,"total_committers":1,"mean_commits":37.0,"dds":0.0,"last_synced_commit":"82c02b3447425fcc622c0e544a9cc767c891ea5d"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thheller%2Fjs-framework-shadow-grove","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thheller%2Fjs-framework-shadow-grove/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thheller%2Fjs-framework-shadow-grove/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thheller%2Fjs-framework-shadow-grove/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thheller","download_url":"https://codeload.github.com/thheller/js-framework-shadow-grove/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247280181,"owners_count":20912965,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-08T15:05:25.894Z","updated_at":"2025-04-05T02:43:17.396Z","avatar_url":"https://github.com/thheller.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# shadow-grove benchmark\n\nThis is an implementation of of the [js-framework benchmark](https://github.com/krausest/js-framework-benchmark) using [shadow-grove](https://github.com/thheller/shadow-experiments).\n\n## 2024-05-20\n\n### Full\n\nLatest run using everything. With latest `shadow.grove.kv` changes.\n\n![Screenshot](Screenshot-2024-05-20-175542.png)\n\n### Ultralight\n\nComponents and KV still carry quite a bit of overhead when compared to this. Although it really doesn't matter, even the Full variant spends more time in the Browser rendering than actual JS.\n\n![Screenshot](Screenshot-2024-05-20-180645.png)\n\n## 2024-02-07\n\n### Ultralight Interpreted\n\nNo Components or DB. Just atom rendered from the root in pure interpreted Hiccup. No fragments. This is now actually competitive and no longer laughably slow because of a bug.\n\n![Screenshot](Screenshot-2024-02-07-114445.png)\n\n## 2024-01-11\n\nJust some updated numbers to see how things have developed in the meantime. svelte is cheating it seems, gotta look into what they are doing.\n\n### Ultralight\n\nNo Grove, Components or DB. Just atom rendered from the root. Closest featureset in comparison to everything else.\n\n![Screenshot](Screenshot-2024-01-11-230150.png)\n\n\n## 2022-08-03\n\nJust a quick check what the numbers look like after API cleanup. Did another Light run as well, looks decent. Main overhead still in EQL/DB indexing it seems.\n\n### Full\n\n![Screenshot](2022-08-03--23-00.png)\n\n### Light\n\n![Screenshot](2022-08-03--23-08.png)\n\n\n\n## 2022-07-16\n\nShould stop playing these benchmark games. There are some interesting cases to consider and a lot of room for improvement, but also far more important things to take care of first.\n\n![Screenshot](2022-07-16--18-31.png)\n\n\n## 2022-07-15\n\nRan the benchmark against the current `js-framework-benchmark` for the `0.2.0` shadow-grove release. Also ran against most common used JS frameworks according to the [State of JS Survey](https://2021.stateofjs.com/en-US/libraries/front-end-frameworks). Numbers still look decent given that I haven't done any performance work since the last time I ran these. \n\n![Screenshot](2022-07-15--18-44.png)\n\n## 2021-03-01\n\nLast few simple query optimizations. At this point I should really start focusing on something more useful. This is fast enough now.\n\nFull Benchmark HTML reports:\n- https://code.thheller.com/demos/js-framework-benchmark/benchmark-full.html\n- https://code.thheller.com/demos/js-framework-benchmark/benchmark-light.html\n\nshadow-cljs Build Reports:\n- https://code.thheller.com/demos/js-framework-benchmark/full.html\n- https://code.thheller.com/demos/js-framework-benchmark/light.html\n\n### full\n\n![Screenshot](2021-03-01--15-41.png)\n\n## 2021-03-01\n\nOptimized `render-seq` a little more since we can exploit `identical?` checks to skip some work. Mostly affects `light` variant since that has to `render-seq` in `select row`.\n\n### full\n\n![Screenshot](2021-03-01--11-19.png)\n\n### light\n\n![Screenshot](2021-03-01--11-18.png)\n\n\n## 2021-02-27\n\nSaw another easy win in `clear rows` and couldn't resist taking it. Seems to be at the point where now more time is spent in event data processing than any DOM related update work.\n\n### full\n\n![Screenshot](2021-02-27--14-17.png)\n\n### light\n\n![Screenshot](2021-02-27--14-10.png)\n\n\n## 2021-02-27\n\nOne more. Realized that all query indexing work can be delayed and moved it to async queue. Minor gain overall but I'll take it.\n\n### full\n\n![Screenshot](2021-02-27--11-51.png)\n\n### light\n\nunchanged since it doesn't use EQL queries\n\n## 2021-02-26\n\nHappy with performance for now. Added a couple more impls for comparison. Any CLJS impls I missed?\n\n- `full` variant pays for faster update cycles by having slower mount/unmount since it has to hook up the EQL queries. There is lots of room left to make that faster overall.\n- `light` variant doesn't do EQL but `select row` is rather slow. Mostly of time is spent in `render-seq`. Likely that can be tweaked more but good enough for now. Easily escaped by skipping `render-seq` entirely and updating row directly as EQL variant does.\n\n### full\n\n![Screenshot](2021-02-26--17-25.png)\n\n### light\n\n![Screenshot](2021-02-26--17-19.png)\n\n## 2021-02-25\n\nThings look better with optimized `render-seq`. Now just need to get query indexing to a decent state and I'm happy with the performance.\n\nLight variant still about same overall score. Trades faster create/clear for `select row` being much slower. Didn't optimize the actual diffing that occurs there yet. Full doesn't need to diff because it knows which rows were modified, that's were the power of the normalized DB really shines.\n\nTo be honest those numbers already look much much better than anticipated. Almost suspiciously so. Need some kind of better real-world related benchmark but things seem to be at the point where it matters much more what the app does than the underlying core algos.\n\n### full\n\n![Screenshot](2021-02-25--14-07.png)\n\n\n## 2021-02-24\n\nAdded a `light` variant that doesn't use any normalized DB or EQL queries. Faster in some aspects actually slower in others. Suffers greatly from `render-seq` behavior being bad. `full` variant actually surprisingly good.\n\n### light\n![Screenshot](2021-02-24--14-11.png)\n\n### full\n![Screenshot](2021-02-23--10-48.png)\n\n\n- create (many) rows: expected to be slow because of setting up and running the EQL to get the data\n- replace all rows: I guess the warmup makes all the difference here. no clue how it could be faster than create otherwise\n- partial update: decent, slow because of EQL queries \n- select row: fast since computation is done in event handler instead of dynamic EQL attribute\n- swap rows: only has to update a vector via assoc (fast) and then swap two DOM nodes (also fast)\n- remove row: `render-seq` behavior terrible for removals\n- append: expected this to be slower but I guess it had enough warmup time when created the first 10,000.\n- clear: most time spent in clearing up the normalized DB and EQL query machinery. actual DOM time is a tiny fraction.\n\n## Older versions\n\n\nThis version had terrible `select row` performance because of a EQL computed attribute. Instead now calculating it once in the `::select!` event.\n\n![Screenshot](2021-02-22--12-15.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthheller%2Fjs-framework-shadow-grove","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthheller%2Fjs-framework-shadow-grove","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthheller%2Fjs-framework-shadow-grove/lists"}