{"id":15542097,"url":"https://github.com/lifeart/demo-async-dom","last_synced_at":"2025-04-23T17:11:20.964Z","repository":{"id":144803803,"uuid":"102507517","full_name":"lifeart/demo-async-dom","owner":"lifeart","description":"Demo page with async dom and webworkers","archived":false,"fork":false,"pushed_at":"2020-03-12T22:06:40.000Z","size":1427,"stargazers_count":35,"open_issues_count":1,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-10-02T12:21:11.506Z","etag":null,"topics":["60fps","animations","async-dom","demo-page","dom","javascript","web-worker"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/lifeart.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":"2017-09-05T16:55:31.000Z","updated_at":"2020-09-09T02:26:59.000Z","dependencies_parsed_at":null,"dependency_job_id":"b7ab5e4e-4d6e-4695-abd0-f70c3792891e","html_url":"https://github.com/lifeart/demo-async-dom","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lifeart%2Fdemo-async-dom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lifeart%2Fdemo-async-dom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lifeart%2Fdemo-async-dom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lifeart%2Fdemo-async-dom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lifeart","download_url":"https://codeload.github.com/lifeart/demo-async-dom/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250477812,"owners_count":21437049,"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":["60fps","animations","async-dom","demo-page","dom","javascript","web-worker"],"created_at":"2024-10-02T12:20:40.497Z","updated_at":"2025-04-23T17:11:20.944Z","avatar_url":"https://github.com/lifeart.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Demo-async-dom, #AsyncDOM\n* [Demo page](https://lifeart.github.io/demo-async-dom/) with async dom and webworkers\n* [Demo Page (no async-dom)](https://lifeart.github.io/demo-async-dom/index2.html) no async dom and webworkers\n* [Ember.js App](https://lifeart.github.io/demo-async-dom/ember/index.html) with async dom and webworkers\n* [Glimmer.js App](https://lifeart.github.io/demo-async-dom/glimmer-port/index.html) with async dom and webworkers\n* [Glimmer.js App (no AsyncDom)](https://lifeart.github.io/sierpinski-glimmer/)\n* [React App](https://lifeart.github.io/demo-async-dom/react-port/index.html) with async dom and webworkers\n------------------------------------------\n# Latest codebase in https://github.com/lifeart/async-dom\n------------------------------------------\n\n# Why?\n\n```javascript\n\nconsole.time('commonAppend');\nfor (let i = 0; i \u003c 10000; i++) {\n\tdocument.body.appendChild(document.createElement('div'));\n}\nconsole.timeEnd('commonAppend');\n//commonAppend: 62.622802734375ms - 300+ms (depend at layout calculation time, t != const)\n\nconsole.time('asyncAppend');\nfor (let i = 0; i \u003c 10000; i++) {\n\tlet id = i;\n\tasyncSendMessage({\n\t\taction: 'createNode',\n\t\tid: id,\n\t\ttag: 'div'\n\t});\n\tasyncSendMessage({\n\t\taction: 'bodyAppendChild',\n\t\tid: id\n\t});\n}\nconsole.timeEnd('asyncAppend');\n//asyncAppend: 277.938232421875ms (not depend at layout calculation time, t = const)\n\nconsole.time('asyncAppendGroup');\nfor (let i = 0; i \u003c 10000; i++) {\n\tlet id = i;\n\tasyncSendMessage([{\n\t\taction: 'createNode',\n\t\tid: id,\n\t\ttag: 'div'\n\t},{\n\t\taction: 'bodyAppendChild',\n\t\tid: id\n\t}]);\n}\nconsole.timeEnd('asyncAppendGroup');\n//asyncAppend: 117.579833984375ms (not depend at layout calculation time, t = const)\n\nconsole.time('asyncAppendBatch');\nvar msgs = [];\nfor (let i = 0; i \u003c 10000; i++) {\n\tlet id = i;\n\tmsgs.push({\n\t\taction: 'createNode',\n\t\tid: id,\n\t\ttag: 'div'\n\t});\n\tmsgs.push({\n\t\taction: 'bodyAppendChild',\n\t\tid: id\n\t});\n}\nasyncSendMessage(msgs);\nconsole.timeEnd('asyncAppendBatch');\n//asyncAppend: 23.794189453125ms (not depend at layout calculation time, t = const)\n\n```\n# Logic\n\n1. All DOM modifications collected in single pool\n2. For each `requestAnimationFrame` we create fittable modifications list (pool slice)\n3. If our modifications took more than 16ms, we put remaining modifications back to pool\n4. Repeat all operations for next frame\n\n* DOM modifications are sorted for optimal \"rolling changes\" (first create an element, add styles, and then add to DOM (not create an element, add to DOM, add styles))\n* Optional DOM modifications (if the performance does not allow this modification, it is thrown out of the queue)\n* Modifications orioritization and batching (you can create an array of modifications that will always be executed within a single frame)\n\n# Description\nThis is a proof of concept of asynchronous DOM modification example with:\n* event binding\n* DOM modifications batching\n* 60 fps performance\n* optional DOM updates\n\n# Main thread (DOM EventLoop)\n* Only DOM update logic\n\n# WebWorker \n* Business logic\n* All DOM modifications came from WebWorker and applyed to Main thread DOM\n\n\n* [async PreventDefault/StopPropagation](https://github.com/lifeart/async-event) - as part of concept\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flifeart%2Fdemo-async-dom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flifeart%2Fdemo-async-dom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flifeart%2Fdemo-async-dom/lists"}