diff --git a/libraries/script-engine/src/ScriptValueUtils.cpp b/libraries/script-engine/src/ScriptValueUtils.cpp
index 4929093821..c081a67925 100644
--- a/libraries/script-engine/src/ScriptValueUtils.cpp
+++ b/libraries/script-engine/src/ScriptValueUtils.cpp
@@ -33,12 +33,7 @@
 #include "ScriptEngineCast.h"
 #include "ScriptValueIterator.h"
 #include "ScriptEngineLogging.h"
-
-#define CONVERSIONS_OPTIMIZED_FOR_V8
-
-#ifdef CONVERSIONS_OPTIMIZED_FOR_V8
 #include "v8/FastScriptValueUtils.h"
-#endif
 
 bool isListOfStrings(const ScriptValue& arg) {
     if (!arg.isArray()) {
@@ -65,11 +60,7 @@ void registerMetaTypes(ScriptEngine* engine) {
     scriptRegisterMetaType<QVector3D, qVector3DToScriptValue, qVector3DFromScriptValue>(engine);
 
     scriptRegisterMetaType<glm::vec2, vec2ToScriptValue, vec2FromScriptValue>(engine);
-#ifdef CONVERSIONS_OPTIMIZED_FOR_V8
-    scriptRegisterMetaType<glm::vec3, vec3ToScriptValueFast, vec3FromScriptValueFast>(engine);
-#else
     scriptRegisterMetaType<glm::vec3, vec3ToScriptValue, vec3FromScriptValue>(engine);
-#endif
     scriptRegisterMetaType<glm::u8vec3, u8vec3ToScriptValue, u8vec3FromScriptValue>(engine);
     scriptRegisterMetaType<glm::vec4, vec4toScriptValue, vec4FromScriptValue>(engine);
     scriptRegisterMetaType<glm::quat, quatToScriptValue, quatFromScriptValue>(engine);
@@ -127,11 +118,7 @@ bool qVector2DFromScriptValue(const ScriptValue& object, QVector2D& qVector2D) {
 
 ScriptValue qVector3DToScriptValue(ScriptEngine* engine, const QVector3D& qVector3D) {
     glm::vec3 vec3(qVector3D.x(), qVector3D.y(), qVector3D.z());
-#ifdef CONVERSIONS_OPTIMIZED_FOR_V8
-    return vec3ToScriptValueFast(engine, vec3);
-#else
     return vec3ToScriptValue(engine, vec3);
-#endif
 }
 
 bool qVector3DFromScriptValue(const ScriptValue& object, QVector3D& qVector3D) {
@@ -191,6 +178,7 @@ bool vec2FromScriptValue(const ScriptValue& object, glm::vec2& vec2) {
     return true;
 }
 
+#ifndef CONVERSIONS_OPTIMIZED_FOR_V8
 ScriptValue vec3ToScriptValue(ScriptEngine* engine, const glm::vec3& vec3) {
     auto prototype = engine->globalObject().property("__hifi_vec3__");
     if (!prototype.hasProperty("defined") || !prototype.property("defined").toBool()) {
@@ -215,6 +203,7 @@ ScriptValue vec3ToScriptValue(ScriptEngine* engine, const glm::vec3& vec3) {
     value.setPrototype(prototype);
     return value;
 }
+#endif
 
 ScriptValue vec3ColorToScriptValue(ScriptEngine* engine, const glm::vec3& vec3) {
     auto prototype = engine->globalObject().property("__hifi_vec3_color__");
@@ -242,6 +231,7 @@ ScriptValue vec3ColorToScriptValue(ScriptEngine* engine, const glm::vec3& vec3)
 }
 
 // V8TODO: add similar checks to rest of the conversions
+#ifndef CONVERSIONS_OPTIMIZED_FOR_V8
 bool vec3FromScriptValue(const ScriptValue& object, glm::vec3& vec3) {
     if (object.isNumber()) {
         vec3 = glm::vec3(object.toVariant().toFloat());
@@ -301,6 +291,7 @@ bool vec3FromScriptValue(const ScriptValue& object, glm::vec3& vec3) {
     }
     return true;
 }
+#endif
 
 ScriptValue u8vec3ToScriptValue(ScriptEngine* engine, const glm::u8vec3& vec3) {
     auto prototype = engine->globalObject().property("__hifi_u8vec3__");
@@ -470,11 +461,7 @@ ScriptValue qVectorVec3ColorToScriptValue(ScriptEngine* engine, const QVector<gl
 ScriptValue qVectorVec3ToScriptValue(ScriptEngine* engine, const QVector<glm::vec3>& vector) {
     ScriptValue array = engine->newArray();
     for (int i = 0; i < vector.size(); i++) {
-#ifdef CONVERSIONS_OPTIMIZED_FOR_V8
-        array.setProperty(i, vec3ToScriptValueFast(engine, vector.at(i)));
-#else
         array.setProperty(i, vec3ToScriptValue(engine, vector.at(i)));
-#endif
     }
     return array;
 }
@@ -794,17 +781,9 @@ bool qURLFromScriptValue(const ScriptValue& object, QUrl& url) {
 
 ScriptValue pickRayToScriptValue(ScriptEngine* engine, const PickRay& pickRay) {
     ScriptValue obj = engine->newObject();
-#ifdef CONVERSIONS_OPTIMIZED_FOR_V8
-    ScriptValue origin = vec3ToScriptValueFast(engine, pickRay.origin);
-#else
     ScriptValue origin = vec3ToScriptValue(engine, pickRay.origin);
-#endif
     obj.setProperty("origin", origin);
-#ifdef CONVERSIONS_OPTIMIZED_FOR_V8
-    ScriptValue direction = vec3ToScriptValueFast(engine, pickRay.direction);
-#else
     ScriptValue direction = vec3ToScriptValue(engine, pickRay.direction);
-#endif
     obj.setProperty("direction", direction);
     return obj;
 }
@@ -850,15 +829,9 @@ ScriptValue collisionToScriptValue(ScriptEngine* engine, const Collision& collis
     obj.setProperty("type", collision.type);
     obj.setProperty("idA", quuidToScriptValue(engine, collision.idA));
     obj.setProperty("idB", quuidToScriptValue(engine, collision.idB));
-#ifdef CONVERSIONS_OPTIMIZED_FOR_V8
-    obj.setProperty("penetration", vec3ToScriptValueFast(engine, collision.penetration));
-    obj.setProperty("contactPoint", vec3ToScriptValueFast(engine, collision.contactPoint));
-    obj.setProperty("velocityChange", vec3ToScriptValueFast(engine, collision.velocityChange));
-#else
     obj.setProperty("penetration", vec3ToScriptValue(engine, collision.penetration));
     obj.setProperty("contactPoint", vec3ToScriptValue(engine, collision.contactPoint));
     obj.setProperty("velocityChange", vec3ToScriptValue(engine, collision.velocityChange));
-#endif
     return obj;
 }
 
diff --git a/libraries/script-engine/src/v8/FastScriptValueUtils.cpp b/libraries/script-engine/src/v8/FastScriptValueUtils.cpp
index f5b5f44c37..130ac1f7b8 100644
--- a/libraries/script-engine/src/v8/FastScriptValueUtils.cpp
+++ b/libraries/script-engine/src/v8/FastScriptValueUtils.cpp
@@ -17,9 +17,11 @@
 #include "V8Types.h"
 #include "ScriptValueV8Wrapper.h"
 
-ScriptValue vec3ToScriptValueFast(ScriptEngine* engine, const glm::vec3& vec3) {
-    auto prototype = engine->globalObject().property("__hifi_vec3__");
-    if (!prototype.hasProperty("defined") || !prototype.property("defined").toBool()) {
+#ifdef CONVERSIONS_OPTIMIZED_FOR_V8
+
+ScriptValue vec3ToScriptValue(ScriptEngine* engine, const glm::vec3& vec3) {
+    //auto prototype = engine->globalObject().property("__hifi_vec3__");
+    /*if (!prototype.hasProperty("defined") || !prototype.property("defined").toBool()) {
         prototype = engine->evaluate(
             "__hifi_vec3__ = Object.defineProperties({}, { "
             "defined: { value: true },"
@@ -33,7 +35,7 @@ ScriptValue vec3ToScriptValueFast(ScriptEngine* engine, const glm::vec3& vec3) {
             "green: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } },"
             "blue: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }"
             "})");
-    }
+    }*/
     ScriptValue value = engine->newObject();
 
     ScriptValueV8Wrapper *proxy = ScriptValueV8Wrapper::unwrap(value);
@@ -49,6 +51,51 @@ ScriptValue vec3ToScriptValueFast(ScriptEngine* engine, const glm::vec3& vec3) {
     V8ScriptValue v8ScriptValue = proxy->toV8Value();
     v8::Local<v8::Object> v8Object = v8::Local<v8::Object>::Cast(v8ScriptValue.get());
 
+    v8::Local<v8::Value> prototype;
+    bool hasPrototype = false;
+
+    if (context->Global()->Get(context, v8::String::NewFromUtf8(isolate, "__hifi_vec3__").ToLocalChecked()).ToLocal(&prototype)) {
+        if (!prototype->IsNullOrUndefined() && prototype->IsObject()) {
+            v8::Local<v8::Object> prototypeObject = v8::Local<v8::Object>::Cast(prototype);
+            v8::Local<v8::Value> isDefined;
+            if (prototypeObject->Get(context, v8::String::NewFromUtf8(isolate, "defined").ToLocalChecked()).ToLocal(&isDefined)) {
+                if ((!isDefined->IsNullOrUndefined()) && isDefined->BooleanValue(isolate)) {
+                    hasPrototype = true;
+                }
+            }
+        }
+    }
+
+    if (!hasPrototype) {
+        QString sourceCode("globalThis.__hifi_vec3__ = Object.defineProperties({}, { "
+        "defined: { value: true },"
+        "0: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } },"
+        "1: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } },"
+        "2: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } },"
+        "r: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } },"
+        "g: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } },"
+        "b: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } },"
+        "red: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } },"
+        "green: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } },"
+        "blue: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }"
+        "})");
+        v8::TryCatch tryCatch(isolate);
+        v8::ScriptOrigin scriptOrigin(isolate, v8::String::NewFromUtf8(isolate, "Vec3prototype").ToLocalChecked());
+        v8::Local<v8::Script> script;
+        if (!v8::Script::Compile(context, v8::String::NewFromUtf8(isolate, sourceCode.toStdString().c_str()).ToLocalChecked(), &scriptOrigin).ToLocal(&script)) {
+            Q_ASSERT(false);
+        }
+        v8::Local<v8::Value> result;
+        if (!script->Run(context).ToLocal(&result)) {
+            Q_ASSERT(false);
+        }
+        if (!context->Global()->Get(context, v8::String::NewFromUtf8(isolate, "__hifi_vec3__").ToLocalChecked()).ToLocal(&prototype)) {
+            Q_ASSERT(false);
+        }
+        Q_ASSERT(!tryCatch.HasCaught());
+        qDebug() <<"vec3ToScriptValue: creating prototype";
+    }
+
     if (!v8Object->Set(context, v8::String::NewFromUtf8(isolate, "x").ToLocalChecked(), v8::Number::New(isolate, vec3.x)).FromMaybe(false)) {
         Q_ASSERT(false);
     }
@@ -59,15 +106,15 @@ ScriptValue vec3ToScriptValueFast(ScriptEngine* engine, const glm::vec3& vec3) {
         Q_ASSERT(false);
     }
 
-    auto v8Prototype = ScriptValueV8Wrapper::fullUnwrap(engineV8, prototype);
-    if (!v8Object->SetPrototype(context, v8Prototype.get()).FromMaybe(false)) {
+    //auto v8Prototype = ScriptValueV8Wrapper::fullUnwrap(engineV8, prototype);
+    if (!v8Object->SetPrototype(context, prototype).FromMaybe(false)) {
         Q_ASSERT(false);
     }
-    value.setPrototype(prototype);
+    //value.setPrototype(prototype);
     return value;
 }
 
-bool vec3FromScriptValueFast(const ScriptValue& object, glm::vec3& vec3) {
+bool vec3FromScriptValue(const ScriptValue& object, glm::vec3& vec3) {
     ScriptValueV8Wrapper *proxy = ScriptValueV8Wrapper::unwrap(object);
 
     auto engineV8 = proxy->getV8Engine();
@@ -185,3 +232,5 @@ bool vec3FromScriptValueFast(const ScriptValue& object, glm::vec3& vec3) {
     }
     return true;
 }
+
+#endif
\ No newline at end of file
diff --git a/libraries/script-engine/src/v8/FastScriptValueUtils.h b/libraries/script-engine/src/v8/FastScriptValueUtils.h
index 8401f9ab36..80d97023a5 100644
--- a/libraries/script-engine/src/v8/FastScriptValueUtils.h
+++ b/libraries/script-engine/src/v8/FastScriptValueUtils.h
@@ -9,7 +9,9 @@
 //  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
 //
 
-// Contains V8-specific implementations of th
+// Contains V8-specific implementations of the function converting Overte datatypes to and from script values.
+// These are used instead of generic implementations if CONVERSIONS_OPTIMIZED_FOR_V8 is defined.
+// V8-specific implementations can make script engine several times faster.
 
 #ifndef overte_FastScriptValueUtils_h
 #define overte_FastScriptValueUtils_h
@@ -19,8 +21,12 @@
 
 #include "../ScriptValue.h"
 
-ScriptValue vec3ToScriptValueFast(ScriptEngine* engine, const glm::vec3& vec3);
+#define CONVERSIONS_OPTIMIZED_FOR_V8
 
-bool vec3FromScriptValueFast(const ScriptValue& object, glm::vec3& vec3);
+#ifdef CONVERSIONS_OPTIMIZED_FOR_V8
+ScriptValue vec3ToScriptValue(ScriptEngine* engine, const glm::vec3& vec3);
+
+bool vec3FromScriptValue(const ScriptValue& object, glm::vec3& vec3);
+#endif
 
 #endif  // overte_FastScriptValueUtils_h
diff --git a/libraries/script-engine/src/v8/ScriptEngineV8.cpp b/libraries/script-engine/src/v8/ScriptEngineV8.cpp
index bf3750ef4f..746483cc8a 100644
--- a/libraries/script-engine/src/v8/ScriptEngineV8.cpp
+++ b/libraries/script-engine/src/v8/ScriptEngineV8.cpp
@@ -937,13 +937,15 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f
     v8::Isolate::Scope isolateScope(_v8Isolate);
     v8::HandleScope handleScope(_v8Isolate);
     v8::Context::Scope contextScope(getContext());
-    v8::TryCatch tryCatch(getIsolate());
     v8::ScriptOrigin scriptOrigin(getIsolate(), v8::String::NewFromUtf8(getIsolate(), fileName.toStdString().c_str()).ToLocalChecked());
     v8::Local<v8::Script> script;
-    if (!v8::Script::Compile(getContext(), v8::String::NewFromUtf8(getIsolate(), sourceCode.toStdString().c_str()).ToLocalChecked(), &scriptOrigin).ToLocal(&script)) {
-        setUncaughtException(tryCatch, "Error while compiling script");
-        _evaluatingCounter--;
-        return nullValue();
+    {
+        v8::TryCatch tryCatch(getIsolate());
+        if (!v8::Script::Compile(getContext(), v8::String::NewFromUtf8(getIsolate(), sourceCode.toStdString().c_str()).ToLocalChecked(), &scriptOrigin).ToLocal(&script)) {
+            setUncaughtException(tryCatch, "Error while compiling script");
+            _evaluatingCounter--;
+            return nullValue();
+        }
     }
     //qCDebug(scriptengine_v8) << "Script compilation succesful: " << fileName;