运行 主线程中的一个模块,否则 Angular webworker 项目
Run one module in main thread in otherwise Angular webworker project
让我们在 angular 中创建一个项目。出于性能原因,我们希望该应用程序在 webworkers 中 运行,这没关系,因为 Angular 团队有可能做到这一点。
我们的应用程序需要实现一个 DOM 操作库(google 地图)。因此,我们需要在主线程上创建此模块 运行,其中可以进行 DOM 操作。然而,我们仍然希望在 webworker 中完成所有繁重的工作。
为了减少这个问题,我将对外部库的所有调用都包含在一个文件中。为方便起见,此文件是模块的服务。
map
- component.ts
- service.ts
- module.ts
- template.html
- styles.css
export class MapComponent implements OnInit, OnDestroy {
constructor(private mapService: MapService, element: ElementRef, renderer: Renderer2)
this.mapService.element.then(map => {
renderer.appendChild(element.nativeElement, map)
})
}
}
@Injectable()
export class MapService {
private static worker = new Worker('./worker.js')
public map: google.maps.Map
public element: Promise<Element>
constructor(private http: Http) {
const div = document.createElement('div')
this.map = new google.maps.Map(div, { ... })
this.element = new Promise(resolve => {
// Fetch google map div element as soon as it is availe
google.maps.event.addDomListenerOnce(this.map, 'idle', () => {
resolve(this.map.getDiv())
})
})
MapService.worker.postMessage({ name: 'init', data: ... }])
MapService.worker.addEventListener('message', event => { ... })
}
}
template.html
只包含<content></content>
。该组件从外部库请求地图元素服务,它是一个 div
,然后通过 renderer.appendChild(element.nativeElement, div)
添加这个 div。函数 renderer.appendChild
是安全的,但我不确定 DOM 元素是否能够传递给 worker。
要回答的问题:
- 如何在 webworker Angular 应用程序的主线程中 运行 一个 module/service?
- 将外部库的元素附加到组件模板。
- 在 webworker
上制作内部组件 运行
备注:
- 整个应用 运行 在影子 DOM 中,使用
encapsulation: ViewEncapsulation.Native
- 应用程序是通过 Angular CLI 创建的
我认为 angular 没有默认支持 运行 网络工作者中的一些模块和主线程中的一些模块。 angular 中可用的默认支持是 运行 使用 "platform-webworker" 和 "platform-werbworker-dynamic" 模块的 Web 工作线程中的所有业务逻辑(组件和服务)。
要使用此解决方案,您需要确保您的应用程序在您的组件和服务中没有对 window、dom、文档等的任何直接引用。
如果很难修改现有应用程序以使其与 web worker 兼容,您仍然可以使用 web worker 运行在 web 中 cpu 密集 code/logic工作线程和应用程序的其余部分可以在主线程中保持 运行ning。
这里有一个演示文稿,讨论如何做到这一点:
Web Workers In Your Angular Application
演示文稿中示例的源代码
Angular 5 和
Angular 6
希望这对您有所帮助。
让我们在 angular 中创建一个项目。出于性能原因,我们希望该应用程序在 webworkers 中 运行,这没关系,因为 Angular 团队有可能做到这一点。
我们的应用程序需要实现一个 DOM 操作库(google 地图)。因此,我们需要在主线程上创建此模块 运行,其中可以进行 DOM 操作。然而,我们仍然希望在 webworker 中完成所有繁重的工作。
为了减少这个问题,我将对外部库的所有调用都包含在一个文件中。为方便起见,此文件是模块的服务。
map
- component.ts
- service.ts
- module.ts
- template.html
- styles.css
export class MapComponent implements OnInit, OnDestroy {
constructor(private mapService: MapService, element: ElementRef, renderer: Renderer2)
this.mapService.element.then(map => {
renderer.appendChild(element.nativeElement, map)
})
}
}
@Injectable()
export class MapService {
private static worker = new Worker('./worker.js')
public map: google.maps.Map
public element: Promise<Element>
constructor(private http: Http) {
const div = document.createElement('div')
this.map = new google.maps.Map(div, { ... })
this.element = new Promise(resolve => {
// Fetch google map div element as soon as it is availe
google.maps.event.addDomListenerOnce(this.map, 'idle', () => {
resolve(this.map.getDiv())
})
})
MapService.worker.postMessage({ name: 'init', data: ... }])
MapService.worker.addEventListener('message', event => { ... })
}
}
template.html
只包含<content></content>
。该组件从外部库请求地图元素服务,它是一个 div
,然后通过 renderer.appendChild(element.nativeElement, div)
添加这个 div。函数 renderer.appendChild
是安全的,但我不确定 DOM 元素是否能够传递给 worker。
要回答的问题:
- 如何在 webworker Angular 应用程序的主线程中 运行 一个 module/service?
- 将外部库的元素附加到组件模板。
- 在 webworker 上制作内部组件 运行
备注:
- 整个应用 运行 在影子 DOM 中,使用
encapsulation: ViewEncapsulation.Native
- 应用程序是通过 Angular CLI 创建的
我认为 angular 没有默认支持 运行 网络工作者中的一些模块和主线程中的一些模块。 angular 中可用的默认支持是 运行 使用 "platform-webworker" 和 "platform-werbworker-dynamic" 模块的 Web 工作线程中的所有业务逻辑(组件和服务)。 要使用此解决方案,您需要确保您的应用程序在您的组件和服务中没有对 window、dom、文档等的任何直接引用。
如果很难修改现有应用程序以使其与 web worker 兼容,您仍然可以使用 web worker 运行在 web 中 cpu 密集 code/logic工作线程和应用程序的其余部分可以在主线程中保持 运行ning。
这里有一个演示文稿,讨论如何做到这一点: Web Workers In Your Angular Application
演示文稿中示例的源代码 Angular 5 和 Angular 6
希望这对您有所帮助。