public string Execute(string containerId, string url, string encodedProps, out string inBrowserScript, out ReactPerformaceMeasurements measurements) { try { measurements = new ReactPerformaceMeasurements(); var stopwatch = new Stopwatch(); var engineFlags = V8ScriptEngineFlags.None; if (DisableGlobalMembers) { engineFlags = V8ScriptEngineFlags.DisableGlobalMembers; } stopwatch.Start(); using (var engine = Runtime.CreateScriptEngine(engineFlags)) { stopwatch.Stop(); measurements.EngineInitializationTime = stopwatch.ElapsedMilliseconds; //Firstly we'll add the libraries to the engine! if (EnableCompilation) { stopwatch.Restart(); engine.Execute(CompiledShimms); stopwatch.Stop(); measurements.ShimmInitializationTime = stopwatch.ElapsedMilliseconds; stopwatch.Restart(); engine.Execute(Compiled); stopwatch.Stop(); measurements.ScriptsInitializationTime = stopwatch.ElapsedMilliseconds; } else { stopwatch.Restart(); engine.Execute(JavascriptShimms.ConsoleShim); stopwatch.Stop(); measurements.ShimmInitializationTime = stopwatch.ElapsedMilliseconds; stopwatch.Restart(); engine.Execute(ScriptRaw); stopwatch.Stop(); measurements.ScriptsInitializationTime = stopwatch.ElapsedMilliseconds; } //we generate the code to execute in the engine here var routerInitCode = String.Format( @"Router.run( SuperChargedReact.routes, '{0}', function( Handler ) {{ {1} = React.renderToString(React.createElement(Handler, {2} )); }});", url, ROUTER_OUTPUT_KEY, encodedProps ); stopwatch.Restart(); engine.Execute(routerInitCode); // TODO: Might swap this timeout stuff for an actual Timespan check instead var timeOutCounter = 0; var maxCyclesBeforeTimeout = 10; // TODO: Config this // Poll the engine to see if the router callback has fired while (!engine.HasVariable(ROUTER_OUTPUT_KEY) && timeOutCounter <= maxCyclesBeforeTimeout) { timeOutCounter++; Thread.Sleep(10); // DIRTY! } stopwatch.Stop(); measurements.ComponentGenerationTime = stopwatch.ElapsedMilliseconds; // Default to a timeout message var html = "<p>Router init timed out waiting for response, try increasing the timeout in React.Config</p>"; if (timeOutCounter <= maxCyclesBeforeTimeout) { html = engine.GetVariableValue <string>(ROUTER_OUTPUT_KEY); } //get the console statements out of the engine var consoleStatements = engine.Evaluate <string>("console.getCalls()"); //generate the scripts to render in the browser inBrowserScript = String.Format( @" var {0} = {1}; Router.run( SuperChargedReact.routes, Router.HistoryLocation, function( Handler ) {{ React.render( React.createElement(Handler, {0} ), document.getElementById( '{2}' ) ); }});", IN_BROWSER_DATA_KEY, encodedProps, containerId ); inBrowserScript = consoleStatements + inBrowserScript; //Cleanup the engine stopwatch.Restart(); Cleanup(engine); stopwatch.Stop(); measurements.CleanupTime = stopwatch.ElapsedMilliseconds; return(string.Format( "<{2} id=\"{0}\">{1}</{2}>", containerId, html, "div" )); } } catch (Microsoft.ClearScript.ScriptEngineException e) { throw new Exception(e.ErrorDetails); } }
/// <summary> /// Execute the bundle with the given settings /// </summary> public string Execute(string containerId, string url, object props, out string inBrowserScript, out ReactPerformaceMeasurements measurements) { return(Execute(containerId, url, JsonConvert.SerializeObject(props, SerializationSettings), out inBrowserScript, out measurements)); }
public string Execute(string containerId, string url, string encodedProps, out string inBrowserScript, out ReactPerformaceMeasurements measurements) { try { measurements = new ReactPerformaceMeasurements(); var stopwatch = new Stopwatch(); var engineFlags = V8ScriptEngineFlags.None; if (DisableGlobalMembers) { engineFlags = V8ScriptEngineFlags.DisableGlobalMembers; } stopwatch.Start(); using (var engine = Runtime.CreateScriptEngine(engineFlags)) { stopwatch.Stop(); measurements.EngineInitializationTime = stopwatch.ElapsedMilliseconds; //Firstly we'll add the libraries to the engine! if (EnableCompilation) { stopwatch.Restart(); engine.Execute(CompiledShimms); stopwatch.Stop(); measurements.ShimmInitializationTime = stopwatch.ElapsedMilliseconds; stopwatch.Restart(); engine.Execute(Compiled); stopwatch.Stop(); measurements.ScriptsInitializationTime = stopwatch.ElapsedMilliseconds; } else { stopwatch.Restart(); engine.Execute(JavascriptShimms.ConsoleShim); stopwatch.Stop(); measurements.ShimmInitializationTime = stopwatch.ElapsedMilliseconds; stopwatch.Restart(); engine.Execute(ScriptRaw); stopwatch.Stop(); measurements.ScriptsInitializationTime = stopwatch.ElapsedMilliseconds; } //we generate the code to execute in the engine here var routerInitCode = String.Format( @"Router.run( reactRoutesConfig, '{0}', function( Handler ) {{ {1} = React.renderToString(React.createElement(Handler, {2} )); }});", url, ROUTER_OUTPUT_KEY, encodedProps ); stopwatch.Restart(); engine.Execute(routerInitCode); // TODO: Might swap this timeout stuff for an actual Timespan check instead var timeOutCounter = 0; var maxCyclesBeforeTimeout = 10; // TODO: Config this // Poll the engine to see if the router callback has fired while (!engine.HasVariable(ROUTER_OUTPUT_KEY) && timeOutCounter <= maxCyclesBeforeTimeout) { timeOutCounter++; Thread.Sleep(10); // DIRTY! } stopwatch.Stop(); measurements.ComponentGenerationTime = stopwatch.ElapsedMilliseconds; // Default to a timeout message var html = "<p>Router init timed out waiting for response, try increasing the timeout in React.Config</p>"; if (timeOutCounter <= maxCyclesBeforeTimeout) { html = engine.GetVariableValue<string>(ROUTER_OUTPUT_KEY); } //get the console statements out of the engine var consoleStatements = engine.Evaluate<string>("console.getCalls()"); //generate the scripts to render in the browser inBrowserScript = String.Format( @" var {0} = {1}; Router.run( reactRoutesConfig, Router.HistoryLocation, function( Handler ) {{ React.render( React.createElement(Handler, {0} ), document.getElementById( '{2}' ) ); }});", IN_BROWSER_DATA_KEY, encodedProps, containerId ); inBrowserScript = consoleStatements + inBrowserScript; //Cleanup the engine stopwatch.Restart(); Cleanup(engine); stopwatch.Stop(); measurements.CleanupTime = stopwatch.ElapsedMilliseconds; return string.Format( "<{2} id=\"{0}\">{1}</{2}>", containerId, html, "div" ); } } catch (Microsoft.ClearScript.ScriptEngineException e) { throw new Exception(e.ErrorDetails); } }
/// <summary> /// Excutes the passed in script /// </summary> /// <param name="containerId"></param> /// <param name="url"></param> /// <param name="props"></param> /// <param name="inBrowserScript"></param> /// <param name="measurements"></param> /// <returns></returns> public string Execute(IRenderSettings settings, out string inBrowserScript, out ReactPerformaceMeasurements measurements, bool disableServerSide = false) { measurements = new ReactPerformaceMeasurements(); var bootstrapper = BootstrapCommand + "(" + JsonConvert.SerializeObject(settings, SerializationSettings) + ");"; if (disableServerSide) { inBrowserScript = bootstrapper; return(""); } try { var stopwatch = new Stopwatch(); var engineFlags = V8ScriptEngineFlags.None; if (DisableGlobalMembers) { engineFlags = V8ScriptEngineFlags.DisableGlobalMembers; } stopwatch.Start(); using (var engine = Runtime.CreateScriptEngine(engineFlags)) { stopwatch.Stop(); measurements.EngineInitializationTime = stopwatch.ElapsedMilliseconds; //Firstly we'll add the libraries to the engine! if (EnableCompilation) { // Use the pre-compiled ones for speed stopwatch.Restart(); engine.Execute(CompiledShimms); stopwatch.Stop(); measurements.ShimmInitializationTime = stopwatch.ElapsedMilliseconds; stopwatch.Restart(); engine.Execute(Compiled); stopwatch.Stop(); measurements.ScriptsInitializationTime = stopwatch.ElapsedMilliseconds; } else { // Use the raw uncompiled ones, these will be parsed a fresh each time by the JS engine stopwatch.Restart(); engine.Execute(JavascriptShimms.ConsoleShim); stopwatch.Stop(); measurements.ShimmInitializationTime = stopwatch.ElapsedMilliseconds; stopwatch.Restart(); engine.Execute(ScriptRaw); stopwatch.Stop(); measurements.ScriptsInitializationTime = stopwatch.ElapsedMilliseconds; } // Kick off the render stopwatch.Restart(); engine.Execute(bootstrapper); // TODO: Might swap this timeout stuff for an actual Timespan check instead var timeOutCounter = 0; var maxCyclesBeforeTimeout = 10; // TODO: Config this // Poll the engine to see if the router callback has fired while ( ( !engine.HasVariable(ROUTER_OUTPUT_KEY) || string.IsNullOrEmpty(engine.GetVariableValue <string>(ROUTER_OUTPUT_KEY)) ) && timeOutCounter <= maxCyclesBeforeTimeout ) { timeOutCounter++; Thread.Sleep(10); // DIRTY! See here of reasoning https://github.com/Offroadcode/SuperchargedReact.Net/issues/1#issuecomment-118848133 // But it works, need to bench mark if this is quicker than linking the JS engine to the .net context as then we could // ping the value straight out form within JS. Alternatively we could get away with just reducing this sleep time but // it depends on how much code we have running, machine speed etc. Its "fast enough" for now though. } stopwatch.Stop(); measurements.ComponentGenerationTime = stopwatch.ElapsedMilliseconds; // Default to a timeout message var html = "<p>Router init timed out waiting for response, try increasing the timeout in React.Config</p>"; if (timeOutCounter <= maxCyclesBeforeTimeout) { html = engine.ExecuteCommand(ROUTER_OUTPUT_KEY);// engine.GetVariableValue<string>(); } //get the console statements out of the engine var consoleStatements = engine.Evaluate <string>("console.getCalls()"); inBrowserScript = consoleStatements + ";" + bootstrapper; //Cleanup the engine stopwatch.Restart(); Cleanup(engine); stopwatch.Stop(); measurements.CleanupTime = stopwatch.ElapsedMilliseconds; return(string.Format( "<{2} id=\"{0}\">{1}</{2}>", settings.ContainerId, html, "div" )); } } catch (Microsoft.ClearScript.ScriptEngineException e) { throw new Exception(e.ErrorDetails); } }
/// <summary> /// Execute the bundle with the given settings /// </summary> public string Execute(string containerId, string url, object props, out string inBrowserScript, out ReactPerformaceMeasurements measurements) { return Execute(containerId, url, JsonConvert.SerializeObject(props, SerializationSettings), out inBrowserScript, out measurements); }