{"id":19685402,"url":"https://github.com/kislerdm/color_theory_app-wasm","last_synced_at":"2026-05-06T00:07:07.253Z","repository":{"id":99103128,"uuid":"523893153","full_name":"kislerdm/color_theory_app-wasm","owner":"kislerdm","description":"A ML demo webapp with logic running entirely on the client. It's a rework of https://github.com/kislerdm/color_theory_app","archived":false,"fork":false,"pushed_at":"2022-08-17T21:19:04.000Z","size":136,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-02-06T13:12:46.347Z","etag":null,"topics":["golang","machine-learning","vanila-javascript","wasm","xgboost"],"latest_commit_sha":null,"homepage":"https://color-theory-app-wasm.dkisler.com","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kislerdm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2022-08-11T23:08:27.000Z","updated_at":"2022-09-16T16:46:08.000Z","dependencies_parsed_at":"2023-06-03T20:15:31.887Z","dependency_job_id":null,"html_url":"https://github.com/kislerdm/color_theory_app-wasm","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/kislerdm/color_theory_app-wasm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kislerdm%2Fcolor_theory_app-wasm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kislerdm%2Fcolor_theory_app-wasm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kislerdm%2Fcolor_theory_app-wasm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kislerdm%2Fcolor_theory_app-wasm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kislerdm","download_url":"https://codeload.github.com/kislerdm/color_theory_app-wasm/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kislerdm%2Fcolor_theory_app-wasm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32672688,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-05T11:29:49.557Z","status":"ssl_error","status_checked_at":"2026-05-05T11:29:48.587Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["golang","machine-learning","vanila-javascript","wasm","xgboost"],"created_at":"2024-11-11T18:21:44.710Z","updated_at":"2026-05-06T00:07:07.236Z","avatar_url":"https://github.com/kislerdm.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Color Theory App - WASM\n\nCarnation of the [Color Theory App](https://github.com/kislerdm/color_theory_app) with two main differences:\n\n- Logic is executed entirely on the client;\n- Interface is implemented using vanilla JS instead of ReactJS.\n\n## Assets size minification\n\nTotal volume of assets data transferred to the client over the network is an important subject for optimisation.\n\nNote that the volume is assesses by using `wc -c`.\n\n### .wasm file\n\n|           Compiler            | Volume [bytes] | Comment                                                                                                        |\n|:-----------------------------:|---------------:|:---------------------------------------------------------------------------------------------------------------|\n|       Default Go build        |        2229903 | -                                                                                                              |\n| [tinygo](https://tinygo.org/) |         516864 | -                                                                                                              |\n| [tinygo](https://tinygo.org/) |         343122 | Removed dependency on `fmt`                                                                                    |\n| [tinygo](https://tinygo.org/) |         157227 | Removed dependency on `fmt`\u003cbr\u003eBuild flags: `-gc=leaking -opt=2 -no-debug -panic=trap`                         |\n\nOne can see that the logic refactoring, use of different compiler with configuration tweaks leads to the binary's size reduction by the factor of **~14** (!). \nMore adjustments and configuration tweaks may lead to further binary size cut. \nAlthough any further effort investment shall be considered carefully since its ROI may not be as high. \n\nIn case binary size is of critical importance, `rust` could be considered as the language which may potentially yield the wasm binary of under 50kB.      \n\nNote that the tinygo compiler does not [support](https://tinygo.org/docs/reference/lang-support/) reflection, hence the logic had to be adjusted to avoid using `encoding/json` and `encoding/csv`: \n- [Code generator for model definition](./internal/colortype/train/main.go) is used to convert the JSON model definition to the native Go struct;\n- [Code generator for colors names](./internal/colorname/data/main.go) is used to convert the CSV color names map to the native Go struct.\n\n### wasm_exec.js\n\n| Description | Volume [bytes] | Comment |\n|:-----------:|---------------:|:--------|\n|   Default   |          18669 | -       |\n|   TinyGo    |          16001 | -       |\n\n\n## Performance optimisation\n\n### [colorname](./internal/colorname)\n\n```bash\ngo test -bench=. -benchmem ./internal/colorname \ngoos: darwin\ngoarch: arm64\npkg: github.com/kislerdm/color_theory_app-wasm/internal/colorname\nBenchmarkFindColorNameByRGB-10              6038            196192 ns/op            8046 B/op          9 allocs/op\nBenchmarkFindColorNameByRGBv2-10          135073              8787 ns/op               0 B/op          0 allocs/op\nPASS\nok      github.com/kislerdm/color_theory_app-wasm/internal/colorname    3.554s\n```\n\nThe logic rework led to further reduction of the wasm binary size to 147791 bytes as an additional beneficial effect on top of computational and memory allocation performance improvements.\n\nFurther adjustment of the \"fast\" `sqrt` function by tweaking data types does not lead to performance improvement.\n\n**Definitions**:\n\n```go\npackage main\n\nimport \"math\"\n\nfunc sqrt(v float64) float64 {\n\t// from quake3 inverse sqrt algorithm\n\t// ref: https://medium.com/@adrien.za/fast-inverse-square-root-in-go-and-javascript-for-fun-6b891e74e5a8\n\tconst magic64 = 0x5FE6EB50C7B537A9\n\n\tn2, th := v*0.5, float64(1.5)\n\tb := math.Float64bits(v)\n\tb = magic64 - (b \u003e\u003e 1)\n\tf := math.Float64frombits(b)\n\tf *= th - (n2 * f * f)\n\treturn f\n}\n\nfunc sqrtV2(v uint32) float32 {\n\t// from quake3 inverse sqrt algorithm\n\t// ref: https://medium.com/@adrien.za/fast-inverse-square-root-in-go-and-javascript-for-fun-6b891e74e5a8\n\tconst magic = 0x5F375A86\n\n\tn2, th := float32(v)/2, float32(1.5)\n\tb := magic - (v \u003e\u003e 1)\n\tf := math.Float32frombits(b)\n\tf *= th - (n2 * f * f)\n\treturn f\n}\n```\n\n**Tests**:\n\n```go\npackage main\n\nimport (\n\t\"testing\"\n)\n\nfunc benchmarkSQRT(i float64, b *testing.B) {\n\tfor n := 0; n \u003c b.N; n++ {\n\t\tsqrt(i)\n\t}\n}\n\nfunc benchmarkSQRTv2(i uint32, b *testing.B) {\n\tfor n := 0; n \u003c b.N; n++ {\n\t\tsqrtV2(i)\n\t}\n}\n\nfunc BenchmarkSQRT1(b *testing.B)       { benchmarkSQRT(1, b) }\nfunc BenchmarkSQRT10(b *testing.B)      { benchmarkSQRT(10, b) }\nfunc BenchmarkSQRT100(b *testing.B)     { benchmarkSQRT(100, b) }\nfunc BenchmarkSQRT1000(b *testing.B)    { benchmarkSQRT(1000, b) }\nfunc BenchmarkSQRT10000(b *testing.B)   { benchmarkSQRT(10000, b) }\nfunc BenchmarkSQRT100000(b *testing.B)  { benchmarkSQRT(100000, b) }\nfunc BenchmarkSQRT1000000(b *testing.B) { benchmarkSQRT(1000000, b) }\n\nfunc BenchmarkSQRTv2_1(b *testing.B)       { benchmarkSQRTv2(1, b) }\nfunc BenchmarkSQRTv2_10(b *testing.B)      { benchmarkSQRTv2(10, b) }\nfunc BenchmarkSQRTv2_100(b *testing.B)     { benchmarkSQRTv2(100, b) }\nfunc BenchmarkSQRTv2_1000(b *testing.B)    { benchmarkSQRTv2(1000, b) }\nfunc BenchmarkSQRTv2_10000(b *testing.B)   { benchmarkSQRTv2(10000, b) }\nfunc BenchmarkSQRTv2_100000(b *testing.B)  { benchmarkSQRTv2(100000, b) }\nfunc BenchmarkSQRTv2_1000000(b *testing.B) { benchmarkSQRTv2(1000000, b) }\n```\n\nBenchmark results:\n\n```bash\ngo test -bench=. -benchmem .\ngoos: darwin\ngoarch: arm64\npkg: srt\nBenchmarkSQRT1-10               1000000000               0.3133 ns/op          0 B/op          0 allocs/op\nBenchmarkSQRT10-10              1000000000               0.3111 ns/op          0 B/op          0 allocs/op\nBenchmarkSQRT100-10             1000000000               0.3105 ns/op          0 B/op          0 allocs/op\nBenchmarkSQRT1000-10            1000000000               0.3109 ns/op          0 B/op          0 allocs/op\nBenchmarkSQRT10000-10           1000000000               0.3114 ns/op          0 B/op          0 allocs/op\nBenchmarkSQRT100000-10          1000000000               0.3104 ns/op          0 B/op          0 allocs/op\nBenchmarkSQRT1000000-10         1000000000               0.3126 ns/op          0 B/op          0 allocs/op\nBenchmarkSQRTv2_1-10            1000000000               0.3109 ns/op          0 B/op          0 allocs/op\nBenchmarkSQRTv2_10-10           1000000000               0.3105 ns/op          0 B/op          0 allocs/op\nBenchmarkSQRTv2_100-10          1000000000               0.3105 ns/op          0 B/op          0 allocs/op\nBenchmarkSQRTv2_1000-10         1000000000               0.3149 ns/op          0 B/op          0 allocs/op\nBenchmarkSQRTv2_10000-10        1000000000               0.3114 ns/op          0 B/op          0 allocs/op\nBenchmarkSQRTv2_100000-10       1000000000               0.3109 ns/op          0 B/op          0 allocs/op\nBenchmarkSQRTv2_1000000-10      1000000000               0.3111 ns/op          0 B/op          0 allocs/op\nPASS\nok      srt     5.129s\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkislerdm%2Fcolor_theory_app-wasm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkislerdm%2Fcolor_theory_app-wasm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkislerdm%2Fcolor_theory_app-wasm/lists"}