diff --git a/src/atlasViewer/atlasViewer.workerService.service.ts b/src/atlasViewer/atlasViewer.workerService.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7e66dc31b5e5ab6b6935f3fcd7e9582bc906a4c8
--- /dev/null
+++ b/src/atlasViewer/atlasViewer.workerService.service.ts
@@ -0,0 +1,10 @@
+import { Injectable } from "@angular/core";
+
+@Injectable({
+  providedIn:'root'
+})
+
+export class AtlasWorkerService{
+  public worker = new Worker('worker.js')
+  public safeMeshSet : Map<string, Set<number>> = new Map()
+}
\ No newline at end of file
diff --git a/src/main.module.ts b/src/main.module.ts
index 8b88b968c1355e3423d6058d725c5c045bdef609..8887dbc3e6f1257c08073a14605d639faa2c210a 100644
--- a/src/main.module.ts
+++ b/src/main.module.ts
@@ -25,6 +25,7 @@ import { AtlasViewerAPIServices } from "./atlasViewer/atlasViewer.apiService.ser
 import { PluginUnit } from "./atlasViewer/pluginUnit/pluginUnit.component";
 import { NewViewerDisctinctViewToLayer } from "./util/pipes/newViewerDistinctViewToLayer.pipe";
 import { ToastService } from "./services/toastService.service";
+import { AtlasWorkerService } from "./atlasViewer/atlasViewer.workerService.service";
 
 @NgModule({
   imports : [
@@ -80,6 +81,7 @@ import { ToastService } from "./services/toastService.service";
     AtlasViewerURLService,
     AtlasViewerAPIServices,
     ToastService,
+    AtlasWorkerService,
   ],
   bootstrap : [
     AtlasViewer
diff --git a/src/ui/nehubaContainer/nehubaContainer.component.ts b/src/ui/nehubaContainer/nehubaContainer.component.ts
index 71b944c9fba29764ab9e7a1b77eb8886a97cec11..50920f80cdf6d967cd5e8d851a3ca087bc58d014 100644
--- a/src/ui/nehubaContainer/nehubaContainer.component.ts
+++ b/src/ui/nehubaContainer/nehubaContainer.component.ts
@@ -239,7 +239,7 @@ export class NehubaContainer implements OnInit, OnDestroy{
           const e = (event as any)
           const lastLoadedIdString = e.detail.lastLoadedMeshId.split(',')[0]
           const lastLoadedIdNum = Number(lastLoadedIdString)
-          return e.detail.meshesLoaded >= this.regionsLabelIndexMap.size
+          return e.detail.meshesLoaded >= this.nehubaViewer.numMeshesToBeLoaded
             ? null
             : isNaN(lastLoadedIdNum)
               ? 'Loading unknown chunk'
diff --git a/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.component.ts b/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.component.ts
index fdc89f2940b3b53d5ae5245863568c3cf6a9ffdf..0876ffee9d8e72f1dd23c6076bf717b380a74afa 100644
--- a/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.component.ts
+++ b/src/ui/nehubaContainer/nehubaViewer/nehubaViewer.component.ts
@@ -1,8 +1,10 @@
-import { Component, AfterViewInit, OnDestroy, Output, EventEmitter, ElementRef } from "@angular/core";
+import { Component, AfterViewInit, OnDestroy, Output, EventEmitter, ElementRef, NgZone } from "@angular/core";
 import * as export_nehuba from 'third_party/export_nehuba/main.bundle.js'
 
 import 'third_party/export_nehuba/chunk_worker.bundle.js'
-import { getActiveColorMapFragmentMain } from "../nehubaContainer.component";
+import { fromEvent, interval } from 'rxjs'
+import { AtlasWorkerService } from "../../../atlasViewer/atlasViewer.workerService.service";
+import { buffer, map, filter } from "rxjs/operators";
 
 @Component({
   templateUrl : './nehubaViewer.template.html',
@@ -22,9 +24,6 @@ export class NehubaViewerUnit implements AfterViewInit,OnDestroy{
   initRegions : any[]
   initNiftiLayers : any[] = []
 
-  /* deprecated */
-  initDedicatedView : string[]
-
   config : any
   
   nehubaViewer : any
@@ -49,16 +48,87 @@ export class NehubaViewerUnit implements AfterViewInit,OnDestroy{
     this._s8$
   ]
 
-  constructor(public elementRef:ElementRef){
+  ondestroySubscriptions: any[] = []
+
+  constructor(
+    public elementRef:ElementRef,
+    private workerService : AtlasWorkerService,
+    private zone : NgZone
+  ){
     this.patchNG()
+
+    this.ondestroySubscriptions.push(
+
+      fromEvent(this.workerService.worker,'message').pipe(
+        filter((message:any) => {
+  
+          if(!message){
+            // console.error('worker response message is undefined', message)
+            return false
+          }
+          if(!message.data){
+            // console.error('worker response message.data is undefined', message.data)
+            return false
+          }
+          if(message.data.type !== 'CHECKED_MESH'){
+            /* worker responded with not checked mesh, no need to act */
+            return false
+          }
+          return true
+        }),
+        map(e => e.data),
+        buffer(interval(1000)),
+        map(arr => arr.reduce((acc:Map<string,Set<number>>,curr)=> {
+          
+          const newMap = new Map(acc)
+          const set = newMap.get(curr.baseUrl)
+          if(set){
+            set.add(curr.checkedIndex)
+          }else{
+            newMap.set(curr.baseUrl,new Set([curr.checkedIndex]))
+          }
+          return newMap
+        }, new Map()))
+      ).subscribe(map => {
+        
+        Array.from(map).forEach(item => {
+          const baseUrl : string = item[0]
+          const set : Set<number> = item[1]
+  
+          /* validation passed, add to safeMeshSet */
+          const oldset = this.workerService.safeMeshSet.get(baseUrl)
+          if(oldset){
+            this.workerService.safeMeshSet.set(baseUrl, new Set([...oldset, ...set]))
+          }else{
+            this.workerService.safeMeshSet.set(baseUrl, new Set([...set]))
+          }
+  
+          /* if the active parcellation is the current parcellation, load the said mesh */
+          if(baseUrl === this._baseUrl){
+            this.nehubaViewer.setMeshesToLoad([...this.workerService.safeMeshSet.get(this._baseUrl)], {
+              name : this.parcellationId
+            })
+          }
+        })
+      })
+    )
   }
 
-  private _parcellationId : string
+  private _baseUrl : string 
+  get numMeshesToBeLoaded():number{
+    if(!this._baseUrl)
+      return 0
 
+    const set = this.workerService.safeMeshSet.get(this._baseUrl)
+    return set
+      ? set.size
+      : 0
+  }
+
+  private _parcellationId : string
   get parcellationId(){
     return this._parcellationId
   }
-
   set parcellationId(id:string){
 
     if(this._parcellationId && this.nehubaViewer){
@@ -89,7 +159,6 @@ export class NehubaViewerUnit implements AfterViewInit,OnDestroy{
   ngAfterViewInit(){
     this.nehubaViewer = export_nehuba.createNehubaViewer(this.config, (err)=>{
       /* print in debug mode */
-      console.log('xgui3783', err)
     });
     
     if(this.regionsLabelIndexMap){
@@ -107,6 +176,7 @@ export class NehubaViewerUnit implements AfterViewInit,OnDestroy{
     this._s$.forEach(_s$=>{
       if(_s$) _s$.unsubscribe()
     })
+    this.ondestroySubscriptions.forEach(s => s.unsubscribe())
     this.nehubaViewer.dispose()
   }
 
@@ -313,7 +383,8 @@ export class NehubaViewerUnit implements AfterViewInit,OnDestroy{
 
   private newViewerInit(){
 
-    /* isn't this segment specific? */
+    /* isn't this layer specific? */
+    /* TODO this is layer specific. need a way to distinguish between different segmentation layers */
     this._s2$ = this.nehubaViewer.mouseOver.segment
       .subscribe(obj=>this.mouseOverSegment = obj.segment)
 
@@ -331,22 +402,6 @@ export class NehubaViewerUnit implements AfterViewInit,OnDestroy{
       this.hideAllSeg()
     }
 
-    /* dedicated view is deprecated */
-    if(this.initDedicatedView){
-      this.hideAllSeg()
-      const _ = {}
-      
-      this.initDedicatedView.forEach((layer,index) => {
-        _[`dedicatedview-${index}`] = {
-          type : 'image',
-          source : layer,
-          shader : getActiveColorMapFragmentMain()
-        }
-      })
-      
-      this.loadLayer(_)
-    }
-
     this._s8$ = this.nehubaViewer.mouseOver.segment.subscribe(({segment})=>{
       if( segment && segment < 65500 ) {
         const region = this.regionsLabelIndexMap.get(segment)
@@ -399,16 +454,42 @@ export class NehubaViewerUnit implements AfterViewInit,OnDestroy{
     if(newlayer)newlayer.setVisible(true)
     else console.warn('could not find new layer',this.parcellationId)
 
+    const regex = /^(\S.*?)\:\/\/(.*?)$/.exec(newlayer.sourceUrl)
+    
+    if(!regex || !regex[2]){
+      console.error('could not parse baseUrl')
+      return
+    }
+    if(regex[1] !== 'precomputed'){
+      console.error('sourceUrl is not precomputed')
+      return
+    }
+    
+    const baseUrl = regex[2]
+    this._baseUrl = baseUrl
+
     /* load meshes */
-    this.nehubaViewer.setMeshesToLoad(
-      [
-        ...Array.from(this.regionsLabelIndexMap.keys()),
-        ...getAuxilliaryLabelIndices()
-      ],
-      {
+    /* TODO could be a bug where user loads new parcellation, but before the worker could completely populate the list */
+    const set = this.workerService.safeMeshSet.get(baseUrl)
+    if(set){
+      this.nehubaViewer.setMeshesToLoad([...set],{
         name : this.parcellationId
+      })
+    }else{
+      if(newlayer){
+        this.zone.runOutsideAngular(() => 
+          this.workerService.worker.postMessage({
+            type : 'CHECK_MESHES',
+            parcellationId : this.parcellationId,
+            baseUrl,
+            indices : [
+              ...Array.from(this.regionsLabelIndexMap.keys()),
+              ...getAuxilliaryLabelIndices()
+            ]
+          })
+        )
       }
-    )
+    }
 
     this.defaultColormap = new Map(
       Array.from(
diff --git a/src/util/worker.ts b/src/util/worker.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f5d34bdfa740da166c07f4199967e58fd522daca
--- /dev/null
+++ b/src/util/worker.ts
@@ -0,0 +1,43 @@
+const validTypes = ['CHECK_MESHES']
+const validOutType = ['CHECKED_MESH']
+
+const checkMeshes = (action) => {
+  
+  /* filtering now done on the angular level */
+  const baseUrl = action.baseUrl
+  fetch(`${baseUrl}/info`)
+    .then(res => res.json())
+    .then(json => json.mesh
+      ? json.mesh
+      : new Error(`mesh does not exist on fetched info file: ${JSON.stringify(json)}`))
+    .then(meshPath => action.indices.forEach(index => {
+      fetch(`${baseUrl}/${meshPath}/${index}:0`)
+        .then(() => {
+          postMessage({
+            type: 'CHECKED_MESH',
+            parcellationId: action.parcellationId,
+            checkedIndex: index,
+            baseUrl
+          })
+        })
+        .catch(error => {
+          /* no cors error is also caught here, but also printed to the console */
+        })
+    }))
+    .catch(error => {
+      console.error('parsing info json error', error)
+    })
+}
+
+onmessage = (message) => {
+  
+  if(validTypes.findIndex(type => type === message.data.type)>=0){
+    switch(message.data.type){
+      case 'CHECK_MESHES':
+        checkMeshes(message.data)
+        return;
+      default:
+        console.warn('unhandled worker action')
+    }
+  }
+}
diff --git a/tsconfig.json b/tsconfig.json
index 1e1c481748c91961ea899dbb2d1bfb1261c8cf64..13633294135515b7caea1c6550552b07cea72232 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -3,7 +3,7 @@
     "experimentalDecorators": true,
     "emitDecoratorMetadata": true,
     "moduleResolution": "node",
-    "skipLibCheck": true,
+    "lib":["webworker","es2015", "dom"],
     "target": "es2015",
     "sourceMap": true,
     "baseUrl": ".",
diff --git a/webpack.aot.js b/webpack.aot.js
index 45c6c9278d350a6b429c5ebfa62ca8fddddd4151..aaeea3e40899e9c0c146363e89eb591b4af3470f 100644
--- a/webpack.aot.js
+++ b/webpack.aot.js
@@ -6,12 +6,16 @@ const AngularCompilerPlugin = ngtools.AngularCompilerPlugin
 const ClosureCompilerPlugin = require('webpack-closure-compiler')
 const merge = require('webpack-merge')
 const staticAssets = require('./webpack.staticassets')
+const worker = require('./webpack.worker')
 
-module.exports = merge(staticAssets, {
+module.exports = merge(worker, staticAssets, {
 
-  entry : './src/main-aot.ts',
+  entry : {
+    main : './src/main-aot.ts',
+    worker : './src/util/worker.ts'
+  },
   output : {
-    filename : 'main.js',
+    filename : '[name].js',
     path : path.resolve(__dirname,'dist/aot')
   },
   module: {
@@ -27,9 +31,8 @@ module.exports = merge(staticAssets, {
       },
       {
         test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
-        // test : /\.ts$/,
         loader: '@ngtools/webpack',
-        exclude : /export_nehuba|plugin_example/
+        exclude : /worker|export_nehuba|plugin_example/
       },
       {
         test : /\.(html|css)$/,
diff --git a/webpack.common.js b/webpack.common.js
index 64d93df42a3ecf189938a3c3022a3e5c009ed2cc..f84ff7357eef32339f70f2d1221e3dfac9935852 100644
--- a/webpack.common.js
+++ b/webpack.common.js
@@ -7,7 +7,7 @@ module.exports = {
       {
         test : /\.ts$/,
         loaders : ['ts-loader','angular2-template-loader?keepUrl=true'],
-        exclude : /node_modules|[Ss]pec\.ts$/
+        exclude : /worker|node_modules|[Ss]pec\.ts$/
       },
       {
         test : /.*?worker.*?\.js$/,
diff --git a/webpack.dev.js b/webpack.dev.js
index 5e812129eee3095b6ec70738a27c24f8fabae71a..05babdb5cee93ccc91c2e54d859bc44813b831f4 100644
--- a/webpack.dev.js
+++ b/webpack.dev.js
@@ -4,13 +4,16 @@ const path = require('path')
 const ngAssets = require('./webpack.ngassets')
 const staticAssets = require('./webpack.staticassets')
 const HtmlWebpackPlugin = require('html-webpack-plugin')
+const worker = require('./webpack.worker')
 
-
-module.exports = merge(common,ngAssets,staticAssets,{
-  entry : './src/main.ts',
+module.exports = merge(common,worker,ngAssets,staticAssets,{
+  entry : {
+    main : './src/main.ts',
+    worker: './src/util/worker.ts'
+  },
   mode : 'development',
   output : {
-    filename : 'main.js',
+    filename : '[name].js',
     path : path.resolve(__dirname,'dist/dev')
   },
   devtool:'source-map',
diff --git a/webpack.worker.js b/webpack.worker.js
new file mode 100644
index 0000000000000000000000000000000000000000..02f442e04c93d2b2b38b6f52af0c1e68307be122
--- /dev/null
+++ b/webpack.worker.js
@@ -0,0 +1,9 @@
+module.exports = {
+  module : {
+    rules : [{
+      test : /worker.*?\.ts/,
+      loaders : ['ts-loader'],
+      exclude : /node_modules/
+    }],
+  }
+}
\ No newline at end of file