diff --git a/src/parallax-css-testpage/particles.js b/src/parallax-css-testpage/particles.js
index b49af6abca7115a9171be3f4bf2d513efd944217..a9202cb0dfd4cede0d8cf8326d62a0b32289a8b2 100644
--- a/src/parallax-css-testpage/particles.js
+++ b/src/parallax-css-testpage/particles.js
@@ -7,11 +7,167 @@
  *  TODO: Pulse Animation anpassen (easing)
  */
 
+// The Fast-Memoize Library:
+// https://github.com/caiogondim/fast-memoize.js
 
+var Memoize = (function () {
 //
-//  Helper
+// Main
+//
+
+function memoize (fn, options) {
+    var cache = options && options.cache
+        ? options.cache
+        : cacheDefault
+
+    var serializer = options && options.serializer
+        ? options.serializer
+        : serializerDefault
+
+    var strategy = options && options.strategy
+        ? options.strategy
+        : strategyDefault
+
+    return strategy(fn, {
+        cache: cache,
+        serializer: serializer
+    })
+}
+
+//
+// Strategy
+//
+
+function isPrimitive (value) {
+    return value == null || typeof value === 'number' || typeof value === 'boolean' // || typeof value === "string" 'unsafe' primitive for our needs
+}
+
+function monadic (fn, cache, serializer, arg) {
+    var cacheKey = isPrimitive(arg) ? arg : serializer(arg)
+
+    var computedValue = cache.get(cacheKey)
+    if (typeof computedValue === 'undefined') {
+        computedValue = fn.call(this, arg)
+        cache.set(cacheKey, computedValue)
+    }
+
+    return computedValue
+}
+
+function variadic (fn, cache, serializer) {
+    var args = Array.prototype.slice.call(arguments, 3)
+    var cacheKey = serializer(args)
+
+    var computedValue = cache.get(cacheKey)
+    if (typeof computedValue === 'undefined') {
+        computedValue = fn.apply(this, args)
+        cache.set(cacheKey, computedValue)
+    }
+
+    return computedValue
+}
+
+function assemble (fn, context, strategy, cache, serialize) {
+    return strategy.bind(
+        context,
+        fn,
+        cache,
+        serialize
+    )
+}
+
+function strategyDefault (fn, options) {
+    var strategy = fn.length === 1 ? monadic : variadic
+
+    return assemble(
+        fn,
+        this,
+        strategy,
+        options.cache.create(),
+        options.serializer
+    )
+}
+
+function strategyVariadic (fn, options) {
+    var strategy = variadic
+
+    return assemble(
+        fn,
+        this,
+        strategy,
+        options.cache.create(),
+        options.serializer
+    )
+}
+
+function strategyMonadic (fn, options) {
+    var strategy = monadic
+
+    return assemble(
+        fn,
+        this,
+        strategy,
+        options.cache.create(),
+        options.serializer
+    )
+}
+
+//
+// Serializer
+//
+
+function serializerDefault () {
+    return JSON.stringify(arguments)
+}
+
+//
+// Cache
 //
 
+function ObjectWithoutPrototypeCache () {
+    this.cache = Object.create(null)
+}
+
+ObjectWithoutPrototypeCache.prototype.has = function (key) {
+    return (key in this.cache)
+}
+
+ObjectWithoutPrototypeCache.prototype.get = function (key) {
+    return this.cache[key]
+}
+
+ObjectWithoutPrototypeCache.prototype.set = function (key, value) {
+    this.cache[key] = value
+}
+
+var cacheDefault = {
+    create: function create () {
+        return new ObjectWithoutPrototypeCache()
+    }
+}
+
+//
+// API
+//
+
+// Default export
+var exports = memoize
+exports.strategies = {
+    variadic: strategyVariadic,
+    monadic: strategyMonadic
+}
+
+return exports
+    
+})()
+
+
+
+// Create the Particles Module | Namespace.
+var Particles = (function () {
+//
+//  Helper
+//
 
 function randomValue(min, max) {
     var value = (Math.random() * (+max - +min) + +min)
@@ -42,6 +198,31 @@ function calcParticleCount(scene, particleDensity) {
     return particleCount || 0
 }
 
+function normalize(val) {
+    var min = 0
+    var max = 1
+    var delta = max - min
+    return (val - min) / delta
+}
+
+// Easing functions from: https://easings.net/
+
+function easeOutQuint(x) {
+    return 1 - Math.pow(1 - x, 5);
+}
+
+function easeInQuint(x) {
+    return x * x * x * x * x;
+}
+
+function easeOutExpo(x) {
+    return x === 1 ? 1 : 1 - Math.pow(2, -10 * x);
+}
+
+function easeInExpo(x) {
+    return x === 0 ? 0 : Math.pow(2, 10 * x - 10);
+}
+    
 
 //
 //  Data
@@ -67,7 +248,6 @@ function RandomPoint2D(minMaxX, minMaxY) {
 }
 
 
-
 //
 //  Transformations | Actions
 //
@@ -349,4 +529,10 @@ function Particles(configs) {
             }
         }
     }
-}
\ No newline at end of file
+}
+
+
+// Default Export
+return Particles
+
+})()