{"id":21585085,"url":"https://github.com/angular-ru/change-detection-tree","last_synced_at":"2025-07-11T15:36:52.071Z","repository":{"id":90970972,"uuid":"125082838","full_name":"Angular-RU/change-detection-tree","owner":"Angular-RU","description":"Visual detecting changes in the component tree (View Engine)","archived":false,"fork":false,"pushed_at":"2018-03-29T18:00:25.000Z","size":159,"stargazers_count":76,"open_issues_count":1,"forks_count":7,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-10T20:22:52.785Z","etag":null,"topics":["angular","change-detection","changedetection","detect-changes","ng-zone","ngzone","tree"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/Angular-RU.png","metadata":{"files":{"readme":"README.md","changelog":"change-detection-strategy-default-async-pipe/app/app.component.css","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,"zenodo":null}},"created_at":"2018-03-13T16:36:12.000Z","updated_at":"2024-10-16T10:39:38.000Z","dependencies_parsed_at":null,"dependency_job_id":"bdacb14c-6971-45d2-93fb-74bc40589be4","html_url":"https://github.com/Angular-RU/change-detection-tree","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Angular-RU/change-detection-tree","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Angular-RU%2Fchange-detection-tree","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Angular-RU%2Fchange-detection-tree/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Angular-RU%2Fchange-detection-tree/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Angular-RU%2Fchange-detection-tree/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Angular-RU","download_url":"https://codeload.github.com/Angular-RU/change-detection-tree/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Angular-RU%2Fchange-detection-tree/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264841967,"owners_count":23671907,"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":["angular","change-detection","changedetection","detect-changes","ng-zone","ngzone","tree"],"created_at":"2024-11-24T15:08:56.487Z","updated_at":"2025-07-11T15:36:52.065Z","avatar_url":"https://github.com/Angular-RU.png","language":"TypeScript","readme":"## Visual detecting changes in the component tree\n\n\u003e This project shows you how the component tree in Angular is updated. \n\u003e The time shown on the component nodes in the tree is the interval \n\u003e between ngDoCheck and ngAfterViewChecked.\n\n```bash\n$ git clone https://github.com/Angular-RU/change-detection-tree cd-tree \u0026\u0026 cd cd-tree\n$ npm install # install all dependencies\n$ ng serve # worked with jit or aot\n```\n\n### StackBlitz examples \n\n✅ **ChangeDetection.Default + NgZone (static tree + projection)**: \u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;Example: https://stackblitz.com/github/Angular-RU/change-detection-tree \u003cbr\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eLearn more\u003c/summary\u003e\n\u003cdiv\u003e\u003cbr\u003e\n\u003cimg src=\"https://habrastorage.org/webt/dl/w4/u-/dlw4u-sfjgf1i2e7b-dpwlefx_k.gif\"\u003e\n\u003cpre\u003e\n$ ng serve --app 0 --port 4200\n\u003c/pre\u003e\n\u003c/details\u003e\u003cbr\u003e\n\n✅ **ChangeDetection.OnPush + NgZone (random generate tree)**: \u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;Example: https://stackblitz.com/github/Angular-RU/change-detection-tree/tree/onpush\n\n\u003cdetails\u003e\n\u003csummary\u003eLearn more\u003c/summary\u003e\n\u003cdiv\u003e\u003cbr\u003e\n\u003cimg src=\"https://habrastorage.org/webt/jq/0t/_l/jq0t_ltli9iyvjtuvumct6awfmk.gif\"\u003e\n\u003cpre\u003e\n$ ng serve --app 1 --port 4201\n\u003c/pre\u003e  \n\u003c/details\u003e\u003cbr\u003e\n\n✅ **ChangeDetection.OnPush + Async pipe - without ngZone (random generate tree)**: \u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;Example: https://stackblitz.com/github/Angular-RU/change-detection-tree/tree/onpush-async-without-zone\n\n\u003cdetails\u003e\n\u003csummary\u003eLearn more\u003c/summary\u003e\n\u003cdiv\u003e\u003cbr\u003e\n\u003cimg src=\"https://habrastorage.org/webt/jq/0t/_l/jq0t_ltli9iyvjtuvumct6awfmk.gif\"\u003e\n\u003cpre\u003e\n$ ng serve --app 2 --port 4202\n\u003c/pre\u003e\n\u003c/details\u003e\u003cbr\u003e\n\n✅ **ChangeDetection.Default + Async pipe + ngZone (random generate tree)**: \u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;Example: https://stackblitz.com/github/Angular-RU/change-detection-tree/tree/async-pipe\n\n\u003cdetails\u003e\n\u003csummary\u003eLearn more\u003c/summary\u003e\n\u003cdiv\u003e\u003cbr\u003e\n\u003cimg src=\"https://habrastorage.org/webt/p5/ac/hg/p5achg7jybtcquownvjxohcs5ck.gif\" /\u003e\n\u003cpre\u003e\n$ ng serve --app 3 --port 4203\n\u003c/pre\u003e\n\u003c/details\u003e\u003cbr\u003e\n\n### TODO\n\n❌ **ChangeDetection.Default + Async pipe + Reactive Forms - without ngZone**: \u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;Example: In progress\n\n❌ **Custom state-management (services)**: \u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;Example: In progress\n\n❌ **NgRx**: \u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;Example: In progress\n\n❌ **MobX**: \u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;Example: In progress\n\n❌ **Web-worker platform**: \u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;Example: In progress\n\n### Checklist for detect problem\n\n- Detect problem with Zone\n\n\u003e Copy the code and paste it into the console. \n\u003e If your component tree too often calls Application.tick() your application will disappear.\n\n```typescript\nlet [root] = getAllAngularRootElements();\nlet appRoot = ng.probe(root);\nlet [rootComponent] = appRoot.injector.get(ng.coreTokens.ApplicationRef).components;\nlet ChangeDetectorRef = rootComponent.changeDetectorRef.constructor.prototype;\nChangeDetectorRef.constructor.prototype.detectChanges = (function () {\n    let oldDC = ChangeDetectorRef.constructor.prototype.detectChanges;\n    let map = new WeakMap();\n    \n    return function () {\n        Zone.root.run(() =\u003e showChangeDetection(this));\n        return oldDC.apply(this, arguments);\n    }\n\n    function showChangeDetection (changeDetector) {\n        let view = changeDetector._view;\n        modifyNodeOpacity(view, fade);\n        modifyNodeOpacity(view, (node) =\u003e {\n            let timeout = map.get(node.renderElement);\n            if (timeout) {\n                clearTimeout(timeout);\n            }\n            timeout = setTimeout(() =\u003e show(node), 1000);\n            map.set(node.renderElement, timeout);\n        });\n    }\n\n    function modifyNodeOpacity (view, modifier) {\n        view.nodes.forEach(node =\u003e {\n            if (node \u0026\u0026 node.renderElement \u0026\u0026 node.renderElement.style) {\n                modifier(node);\n            }\n        });\n    }\n\n    function fade (node) {\n        let { style } = node.renderElement;\n        let opacity = parseFloat(style.opacity) || 1;\n        let newOpacity = opacity - 0.01;\n        style.display = 'block';\n        style.opacity = newOpacity \u003e 0 ? newOpacity : 0;\n    }\n\n    function show (node) {\n        let { style } = node.renderElement;\n        style.display = 'block';\n        style.opacity = 1;\n    }\n})();\n```\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fangular-ru%2Fchange-detection-tree","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fangular-ru%2Fchange-detection-tree","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fangular-ru%2Fchange-detection-tree/lists"}