I was facing the same problem some time ago (when doing service for photographers, using angular).
Problem is not about RxJS or angular, it is rather about browser itself - it is not optimised for displaying lots of big images this way.
At first if you need to display lots of images(does not matter is it local or remote files):
- Resize them before displaying (faster loading, no need for resize, lower memory consumption).
- If you can - display only visible images (otherwise page would be really slow until all images would be loaded). Check this answer: How do I get the x and y positions of an element in an AngularJS directive originally trackVisibilitywas written to display images only when they become visible.
About displaying images from local files, things are even more complicated:
In your case you are loading files as data urls, and there is a problem: 70 images you mentioned for 3 mb each will consume at least 2.1 Gb of RAM(actually more, and obliviously will affect performance)
First recommendation is - if you can: do not use data urls, better use URL.createObjectURL and use URL.revokeObjectURL when you do not need it anymore.
Second: if you need just thumbnails - resize images locally(using canvas) before displaying them. There would be an issue with antialiasing, if it is important for you case - take a look at step-down technic described here: Html5 canvas drawImage: how to apply antialiasing And if you are supporting iOS - there can be a problem with canvas size limitation, so you will need to detect it somehow. (both issues were addressed in example below)
And the last one: if you need to create thumbnails for lots of images - do not do this at once, instead - schedule work pieces over event loop (otherwise browser would be not responsive while resizing images). And for better preformance: do this sequentially(not in parallel for all images), it may sound strange - but, it would be faster(due too lower memory consumption, and less disk reads at the same time). 
In summary:
- Use trackVisibilitydirective mentioned above to display only visible images
- Do not use, data urls especially for big images.
- Create resized thumbnails, before displaying them
Libraries you may find useful for implementing this:
Rough code example about doing image thumbnails (most of code was copied from working project - so, it is expected to work. canvasToJpegBlob and makeThumbnail was written just now and was not tested, so there can be small mistakes):
 function loadImage(imagePath) {
   return Rx.Observable.create(function(observer) {
     var img = new Image();
     img.src = imagePath;
     image.onload = function() {
       observer.onNext(image);
       observer.onCompleted();
     }
     image.onError = function(err) {
       observer.onError(err);
     }
   });
 }
 // canvas edge cases detection
 var maxDimm = 32000;
 var ios5 = false, ios3 = false;
 (function() {
   if (navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0) {
     maxDimm = 8000;
   } else {
     var canvas = document.createElement('canvas');
     canvas.width = 1024 * 3;
     canvas.height = 1025;
     if (canvas.toDataURL('image/jpeg') === 'data:,') {
       ios3 = true;
     } else {
       canvas = document.createElement('canvas');
       canvas.width = 1024 * 5;
       canvas.height = 1025;
       if (canvas.toDataURL('image/jpeg') === 'data:,') {
         ios5 = true;
       }
     }
   }
 }());
 function stepDown(src, width, height) {
   var
     steps,
     resultCanvas = document.createElement('canvas'),
     srcWidth = src.width,
     srcHeight = src.height,
     context;
   resultCanvas.width = width;
   resultCanvas.height = height;
   if ((srcWidth / width) > (srcHeight / height)) {
     steps = Math.ceil(Math.log(srcWidth / width) / Math.log(2));
   } else {
     steps = Math.ceil(Math.log(srcHeight / height) / Math.log(2));
   }
   if (steps <= 1) {
     context = resultCanvas.getContext('2d');
     context.drawImage(src, 0, 0, width, height);
   } else {
     var tmpCanvas = document.createElement('canvas');
     var
       currentWidth = width * Math.pow(2, steps - 1),
       currentHeight = height * Math.pow(2, steps - 1),
       newWidth = currentWidth,
       newHeight = currentHeight;
     if (ios3 && currentWidth * currentHeight > 3 * 1024 * 1024) {
       newHeight = 1024 * Math.sqrt(3 * srcHeight / srcWidth);
       newWidth = newHeight * srcWidth / srcHeight;
     } else {
       if (ios5 && currentWidth * currentHeight > 5 * 1024 * 1024) {
         newHeight = 1024 * Math.sqrt(5 * srcHeight / srcWidth);
         newWidth = newHeight * srcWidth / srcHeight;
       } else {
         if (currentWidth > maxDimm || currentHeight > maxDimm) {
           if (currentHeight > currentWidth) {
             newHeight = maxDimm;
             newWidth = maxDimm * currentWidth / currentHeight;
           } else {
             newWidth = maxDimm;
             newHeight = maxDimm * currentWidth / currentHeight;
           }
         }
       }
     }
     currentWidth = newWidth;
     currentHeight = newHeight;
     if ((currentWidth / width) > (currentHeight / height)) {
       steps = Math.ceil(Math.log(currentWidth / width) / Math.log(2));
     } else {
       steps = Math.ceil(Math.log(currentHeight / height) / Math.log(2));
     }
     context = tmpCanvas.getContext('2d');
     tmpCanvas.width = Math.ceil(currentWidth);
     tmpCanvas.height = Math.ceil(currentHeight);
     context.drawImage(src, 0, 0, srcWidth, srcHeight, 0, 0, currentWidth, currentHeight);
     while (steps > 1) {
       newWidth = currentWidth * 0.5;
       newHeight = currentHeight * 0.5;
       context.drawImage(tmpCanvas, 0, 0, currentWidth, currentHeight, 0, 0, newWidth, newHeight);
       steps -= 1;
       currentWidth = newWidth;
       currentHeight = newHeight;
     }
     context = resultCanvas.getContext('2d');
     context.drawImage(tmpCanvas, 0, 0, currentWidth, currentHeight, 0, 0, width, height);
   }
   return resultCanvas;
 }
 function canvasToJpegBlob(canvas) {
   return Rx.Observable.create(function(observer) {
     try {
       canvas.toBlob(function(blob) {
         observer.onNext(blob);
         observer.onCompleted();
       }, 'image/jpeg');
     } catch (err) {
       observer.onError(err);
     }
   });
 }
 function makeThumbnail(file) {
   return Observable.defer(()=> {
     const fileUrl = URL.createObjectURL(file);
     return loadImage(fileUrl)
       .map(image => {
         const width = 200;
         const height = image.height * width / image.width;
         const thumbnailCanvas = stepDown(image, width, height);
         URL.revokeObjectURL(fileUrl);
         return thubnailCanvas;
       })
       .flatMap(canvasToJpegBlob)
       .map(canvasBlob=>URL.createObjectURL(canvasBlob))
       .map(thumbnailUrl => {
         return {
           file,
           thumbnailUrl
         }
       })
   });
  }