Commit Graph

84 Commits

Author SHA1 Message Date
Pieter De Baets b40631b3cc Remove unused RKAnalyticsCPULogger
Reviewed By: bryceredd

Differential Revision: D2766801

fb-gh-sync-id: c5088c01bbae6a10b17317cc5ec2adcf157f415e
2015-12-16 16:16:28 -08:00
Tadeu Zagallo 809627379b Rename RCTContextExecutor to RCTJSCExecutor
Summary:
public

Rename the executor to so it actually says something about the implementation.

Reviewed By: jspahrsummers, nicklockwood

Differential Revision: D2759688

fb-gh-sync-id: 5b1ac447e75109fbbc2ee71c804710d9926785aa
2015-12-16 02:51:28 -08:00
Tadeu Zagallo f8c125c64b Remove redundant profile events
Summary:
public

Remove some of the manual markers from the bridge since they will already be added dinamically.

Reviewed By: jspahrsummers

Differential Revision: D2761748

fb-gh-sync-id: 0c726373f9105258feb8230d30453559ed1e6a65
2015-12-16 02:31:29 -08:00
Nick Lockwood f7edcda5d7 Deprecated RCTDidCreateNativeModules notification
Summary:
public

Thanks to the new lazy initialization system for modules, `RCTDidCreateNativeModules` no longer does what the name implies.

Previously, `RCTDidCreateNativeModules` was fired after all native modules had been initialized. Now, it simply fires each time the bridge is reloaded. Modules are created on demand when they are needed, so most of the assumptions about when `RCTDidCreateNativeModules` will fire are now incorrect.

This diff deprecates `RCTDidCreateNativeModules`, and adds a new notification, `RCTDidInitializeModuleNotification`, which fires each time a module a new module is instantiated.

If you need to access a module at any time you can just call `-[bridge moduleForClass:]` and the module will be instantiated on demand. If you want to access a module *only* after it has already been instantiated, you can use the `RCTDidInitializeModuleNotification` notification.

Reviewed By: tadeuzagallo

Differential Revision: D2755036

fb-gh-sync-id: 25bab6d5eb6fcd35d43125ac45908035eea01487
2015-12-15 05:43:33 -08:00
Tadeu Zagallo 2d61dfd9c1 Replace private bridge categories with private header
Summary:
public

A lot of the core modules have to use private methods in the bridge, specially
since the `RCTBatchedBridge` interface is never exposed. That was leading to a
lot of different private bridge categories spread across different modules,
which makes harder to identify which modules are affected by private API changes.

Replace all the categories with a single private header.

Reviewed By: nicklockwood

Differential Revision: D2757564

fb-gh-sync-id: 793158b9082d542b74a6094ed0db4d5dc3a88f78
2015-12-15 05:40:27 -08:00
Martin Kralik a86171a482 exposed a way to trigger layout on the uimanager
Summary:
A component can be backed by native "node" that can change its internal state, which would result in a new UI after the next layout. Since js has no way of knowing that this has happened it wouldn't trigger a layout if nothing in js world has changed. Therefore we need a way how to trigger layout from native code.

This diff does it by adding methods `layoutIfNeeded` on the uimanager and `isBatchActive` on the bridge.
When `layoutIfNeeded` is called it checks whether a batch is in progress. If it is we do nothing, since at it's end layout happens. If a batch is not in progress we immidiately do layout.

I went with the easiest way how to implement this - `isBatchActive` is a public method on the bridge. It's not ideal, but consistent with other methods for modules.
public

Reviewed By: jspahrsummers, nicklockwood

Differential Revision: D2748896

fb-gh-sync-id: f3664c4af980d40a463b538e069b26c9ebad6300
2015-12-11 06:59:30 -08:00
Nick Lockwood d138403c2e Added deferred module loading feature
Reviewed By: javache

Differential Revision: D2717687

fb-gh-sync-id: 4c03c721c794a2e7ac67a0b20474129fde7f0a0d
2015-12-10 04:31:30 -08:00
Tadeu Zagallo cd4574498d Use actual CADisplayLink timestamp for VSYNC
Summary:
public

Use the actual timestamp provided through `CADisplayLink` instead of the time
the handler is called.

Reviewed By: jspahrsummers

Differential Revision: D2739121

fb-gh-sync-id: 1da28190bb25351dc3dd94efaff21d49279a570f
2015-12-09 09:56:27 -08:00
Sebastian Markbage 8d397b4cbc Decouple Module System from Native Calls
Summary:
The JavaScript ecosystem doesn't have the notion of a built-in native module loader. Even Node is decoupled from its module loader. The module loader system is just JS that runs on top of the global `process` object which has all the built-in goodies.

Additionally there is no such thing as a global require. That is something unique to our providesModule system. In other module systems such as node, every require is contextual. Even registered npm names are localized by version.

The only global namespace that is accessible to the host environment is the global object. Normally module systems attaches itself onto the hooks provided by the host environment on the global object.

Currently, we have two forms of dispatch that reaches directly into the module system. executeJSCall which reaches directly into require. Everything now calls through the BatchedBridge module (except one RCTLog edge case that I will fix). I propose that the executors calls directly onto `BatchedBridge` through an instance on the global so that everything is guaranteed to go through it. It becomes the main communication hub.

I also propose that we drop the dynamic requires inside of MessageQueue/BatchBridge and instead have the modules register themselves with the bridge.

executeJSCall was originally modeled after the XHP equivalent. The XHP equivalent was designed that way because the act of doing the call was the thing that defined a dependency on the module from the page. However, that is not how React Native works.

The JS side is driving the dependencies by virtue of requiring new modules and frameworks and the existence of dependencies is driven by the JS side, so this design doesn't make as much sense.

The main driver for this is to be able to introduce a new module system like Prepack's module system. However, it also unlocks the possibility to do dead module elimination even in our current module system. It is currently not possible because we don't know which module might be called from native.

Since the module system now becomes decoupled we could publish all our providesModule modules as npm/CommonJS modules using a rewrite script. That's what React Core does.

That way people could use any CommonJS bundler such as Webpack, Closure Compiler, Rollup or some new innovation to create a JS bundle.

This diff expands the executeJSCalls to the BatchedBridge's three individual pieces to make them first class instead of being dynamic. This removes one layer of abstraction. Hopefully we can also remove more of the things that register themselves with the BatchedBridge (various EventEmitters) and instead have everything go through the public protocol. ReactMethod/RCT_EXPORT_METHOD.

public

Reviewed By: vjeux

Differential Revision: D2717535

fb-gh-sync-id: 70114f05483124f5ac5c4570422bb91a60a727f6
2015-12-08 16:03:37 -08:00
Justin Spahr-Summers 8e55858397 Precompute whether modules respond to batch notification methods
Summary:
public

Looping through every `RCTModuleData` to check whether the module responds to `-batchDidComplete` or `-partialBatchDidFlush` is unnecessarily expensive. We can cache the answer at the time that the module instance is actually initialized.

Reviewed By: tadeuzagallo

Differential Revision: D2717594

fb-gh-sync-id: 274a59ec2d6014ce18c93404ce6b9940c1dc9c32
2015-12-03 04:20:27 -08:00
Justin Spahr-Summers c25c98c00c Flush UI blocks as soon as they're accumulated
Summary:
public

Currently, we wait to invoke `-flushUIBlocks` until the JavaScript batch to native has completed. This means we may be waiting an unnecessarily long time to perform view hierarchy changes and prop changes.

By instead invoking this after each chunk of enqueued UI blocks, we can perform some updates more eagerly, increasing our utilization of the main thread while splitting up the amount of time we spend running upon it.

This shouldn't affect layout, which is still tied to `-batchDidComplete`, so any visual inconsistencies should be limited to prop changes, which seems acceptable for the dramatic improvement in performance.

Reviewed By: javache

Differential Revision: D2658552

fb-gh-sync-id: 6d4560e21d7da1b02d2f30d1860d60735f11c4b5
2015-12-02 06:03:27 -08:00
Frédéric Sagnes 599a130c9a Add perf tests to avoid decoding the bundle completely
Reviewed By: jspahrsummers

Differential Revision: D2574965

fb-gh-sync-id: 7bea6b3af04ba7e15471cc94a324a6c4a1d3614d
2015-11-27 09:21:29 -08:00
Tadeu Zagallo ea96a7edb8 Avoid dispatch_async on RCTProfile when not profiling
Summary: public

Fixes #3953

Bail out soon when the profiler is not running + move string formating into the macro so that it happens in a background queue.

Reviewed By: jspahrsummers

Differential Revision: D2696167

fb-gh-sync-id: a1b91ee4459078ab9a4c0be62bd23362ec05e208
2015-11-26 04:11:28 -08:00
Nick Lockwood 060664fd3d Refactored module access to allow for lazy loading
Summary: public

The `bridge.modules` dictionary provides access to all native modules, but this API requires that every module is initialized in advance so that any module can be accessed.

This diff introduces a better API that will allow modules to be initialized lazily as they are needed, and deprecates `bridge.modules` (modules that use it will still work, but should be rewritten to use `bridge.moduleClasses` or `-[bridge moduleForName/Class:` instead.

The rules are now as follows:

* Any module that overrides `init` or `setBridge:` will be initialized on the main thread when the bridge is created
* Any module that implements `constantsToExport:` will be initialized later when the config is exported (the module itself will be initialized on a background queue, but  `constantsToExport:` will still be called on the main thread.
* All other modules will be initialized lazily when a method is first called on them.

These rules may seem slightly arcane, but they have the advantage of not violating any assumptions that may have been made by existing code - any module written under the original assumption that it would be initialized synchronously on the main thread when the bridge is created should still function exactly the same, but modules that avoid overriding `init` or `setBridge:` will now be loaded lazily.

I've rewritten most of the standard modules to take advantage of this new lazy loading, with the following results:

Out of the 65 modules included in UIExplorer:

* 16 are initialized on the main thread when the bridge is created
* A further 8 are initialized when the config is exported to JS
* The remaining 41 will be initialized lazily on-demand

Reviewed By: jspahrsummers

Differential Revision: D2677695

fb-gh-sync-id: 507ae7e9fd6b563e89292c7371767c978e928f33
2015-11-25 04:49:45 -08:00
Martin Kralik 510f001390 put exception message in front of error log
Summary: Exception message was the last part of the whole shown error. This is not optimal in case where there are deeply nested objects as parameters, which used to be displayed before the message.
This diff moves the exception message to the front.

public

Reviewed By: javache

Differential Revision: D2691426

fb-gh-sync-id: c6c9ad3ac4681a8102ea2c580f24382640b7246c
2015-11-24 12:12:26 -08:00
Pieter De Baets b40631d0db Add exception description to exception name
Reviewed By: fkgozali

Differential Revision: D2687906

fb-gh-sync-id: f1bbc7c3deb9068877add37619faee730cdec743
2015-11-23 16:19:29 -08:00
Tadeu Zagallo 0b46a0c13b Add a naive WPO implementation
Summary: public

RFC: The minifier haven't been stripping dead-code, and it also can't kill unused
modules, so as a temporary solution this inlines `__DEV__`, kill dead branches
and kill dead modules. For now I'm just white-listing the dev variable, but we
could definitely do better than that, but as a temporary fix this should be
helpful.

I also intend to kill some dead variables, so we can kill unused requires,
although inline-requires can also fix it.

Reviewed By: vjeux

Differential Revision: D2605454

fb-gh-sync-id: 50acb9dcbded07a43080b93ac826a5ceda695936
2015-11-17 03:39:28 -08:00
Nick Lockwood fa0b45c58b Replaced RCTSparseArray with NSDictionary
Reviewed By: jspahrsummers

Differential Revision: D2651920

fb-gh-sync-id: 953e2ea33abfc7a3a553da95b13e9ab2bccc5a1c
2015-11-14 10:28:28 -08:00
Pieter De Baets a377f81b4e Fix check for rethrowing RCTFatal exceptions
Summary: I changed the format slightly of the exception being generated in RCTFatal, so we we're catching and rethrowing it, which left some useful information of the error stack.

public

Reviewed By: majak

Differential Revision: D2631341

fb-gh-sync-id: feb4939f58014171a55cd74f20f57bcd6dfddc1e
2015-11-10 04:30:37 -08:00
Tadeu Zagallo e5b843834d Rename RCTProfile(Begin|End)Event
Summary: public

Rename it to `RCT_PROFILE_(BEGIN|END)_EVENT` to make it clearer that it's a macro,
since it has special behaviours.

Reviewed By: jspahrsummers

Differential Revision: D2631542

fb-gh-sync-id: 629c139462c4aa3582f719b14482017d13676e33
2015-11-09 08:43:29 -08:00
Tadeu Zagallo e1fa325569 Change async events' cookie to NSUInteger
Summary: public

As jspahrsumemrs pointed out, `int` could overflow pretty easy, since it was static,
change it to an NSUInteger and downcast it when need to interop.

Reviewed By: jspahrsummers

Differential Revision: D2625902

fb-gh-sync-id: 2052be47a7b0ed81484da004fa18d6ef5baf26f7
2015-11-08 10:20:29 -08:00
Tadeu Zagallo 8dac41b7f0 Rename variable to unbreak the build
Reviewed By: javache

Differential Revision: D2625963

fb-gh-sync-id: 136013d7fa3b8eea322eea4ec45901376c30881d
2015-11-06 07:23:25 -08:00
Tadeu Zagallo de1c0169fc Clean up unnecessary profile events
Summary: public

There were some old markers that are now automatically inject and now are no longer necessary (+ one that was missing an end call :( ))

Reviewed By: javache

Differential Revision: D2625901

fb-gh-sync-id: 4c4c9d6b4e8e2b4bdb9c64fde01000b0ca2e9f47
2015-11-06 06:55:30 -08:00
Pieter De Baets 31b5b0ac01 Create RCTFatal for reporting fatal React events
Summary: public

Add RCTFatal for reporting fatal runtime conditions. This centralizes failure handling to one function and allows you to customize how they should be handled. RCTFatal will be logged to the console and as a redbox and will also be triggered by fatal exceptions coming from RCTExceptionsManager.

Note that there is no RCTLogFatal, since just logging the fatal condition does not allow us to handle it consistently.

Reviewed By: nicklockwood

Differential Revision: D2615490

fb-gh-sync-id: 7d8e134419e10a8fb549297054ad955db3f6bee0
2015-11-05 12:51:27 -08:00
Tadeu Zagallo 0c74804427 Use dispatch_async instead of lock
Summary: public

The initial implementation used a lock to manage the stored profile information,
blocking the caller thread for longer than it should. Replace it with a private
queue, since the only thing we need to from the caller is to record the immediate
call time and the caller thread/queue, all the rest has absolutely no priority.

Use macros to also defer work done when generate the name of the events.

Reviewed By: nicklockwood

Differential Revision: D2603120

fb-gh-sync-id: e3e36160c893e7ae9ed3558f07c854ea76396661
2015-11-04 09:03:01 -08:00
Nick Lockwood c5b990f65f Added lightweight generic annotations
Summary: public

Added lightweight genarics annotations to make the code more readable and help the compiler catch bugs.

Fixed some type bugs and improved bridge validation in a few places.

Reviewed By: javache

Differential Revision: D2600189

fb-gh-sync-id: f81e22f2cdc107bf8d0b15deec6d5b83aacc5b56
2015-11-03 14:49:30 -08:00
Pawel Sienkowski d0371165c3 Fix the way the Storyline native module is updated
Reviewed By: javache

Differential Revision: D2609706

fb-gh-sync-id: dcacd9085243d04f4e0dfa8d4a4c5df594ef31ec
2015-11-03 08:58:28 -08:00
Tadeu Zagallo 27be386c2e Fix trace name for native module calls received from JS
Summary: public

At some point the profile call was changed to only pass `@"invoke callback"`
rather than the module name, which makes most entries pretty much useless.
Change it back to be the module name.

Reviewed By: javache

Differential Revision: D2602222

fb-gh-sync-id: c4e8e3f559f66725620293cc575baf5ede48df31
2015-11-03 03:51:27 -08:00
David Aurelio 40f513aa71 Bring back D2570057 (previously backed out) + fixes
Reviewed By: nicklockwood

Differential Revision: D2590604

fb-gh-sync-id: 63a0e0c6afda740f22aacb3f469d411f236fa16b
2015-10-28 18:44:26 -07:00
David Aurelio 4ac898fceb Backout D2570057
Reviewed By: kmagiera

Differential Revision: D2590341

fb-gh-sync-id: 8a6073de3ef2a6e87b785a2bb252468a37c081cf
2015-10-28 08:28:25 -07:00
Nick Lockwood 500ffa9b76 Fixed dev mode override to work with unminified JS
Summary: public

The dev mode override feature was built with the assumption that bunlded JS would be minified, and broke with unminified JS. This fixes that by using a more robust regex-based search.

Reviewed By: tadeuzagallo

Differential Revision: D2581240

fb-gh-sync-id: 4d4b45eb8573ceb956b7259550d80a9807f83d59
2015-10-27 04:14:29 -07:00
Tadeu Zagallo 9069bdf1c2 Introduce Perf Monitor
Summary: public

Kill `RCTPerfStats` and introduce the new `RCTPerfMonitor`, including memory
usage, JSC heap size, number of RN views in screen, FPS (both on UI and JS threads)
and more to come.

It removes all the previous traces that were previous spread across the bridge
and the dev menu and moves everything to be more contained, so the whole thing
can be safely striped in production.

Reviewed By: nicklockwood

Differential Revision: D2575158

fb-gh-sync-id: 6a6d0c4422adbddeeefddd32ec3409a7095ff2a9
2015-10-23 10:56:56 -07:00
Nick Lockwood cae4761006 Use arrays for module method data
Summary: public

Use arrays instead of dictionaries for encoding module method information.

This further reduces UIExplorer startup JSON from 16104 bytes to 14119 (12% reduction)

Reviewed By: javache

Differential Revision: D2570057

fb-gh-sync-id: 4a53a9ead4365a136e7caeb650375733e1c24c0e
2015-10-23 10:16:26 -07:00
Pieter De Baets 039dab078a Fix configuration for OSS UIExplorer tests
Reviewed By: nicklockwood

Differential Revision: D2575356

fb-gh-sync-id: 0ab5bd29aa3c17a8cb067a8a17abed3e178c5bcf
2015-10-23 09:35:25 -07:00
Nick Lockwood ae5de54f00 Reduced module config data
Summary: public

We're sending a lot of module config data when the app first starts, and much of this is redundant.

UIExplorer current sends 19061 bytes of module config JSON. This diff reduces that to 16104 (15% saving) by stripping modules that have no methods or constants, and removing method types unless method is async.

Reviewed By: tadeuzagallo, javache

Differential Revision: D2570010

fb-gh-sync-id: 8c0abbd1cdee3264b37a4f52e852008caaffb9c5
2015-10-22 05:53:26 -07:00
Tadeu Zagallo 31f9a690f3 Flush queue every 5ms during JS execution
Summary: public

Implement the iOS side of the optmisation previously implemented in android
(D2485402)

Depends on D2540746

Reviewed By: javache

Differential Revision: D2541118

fb-gh-sync-id: f3590600a6defa2da75c5b7b2cced6ad8bfea6cb
2015-10-19 08:04:24 -07:00
Frédéric Sagnes 4a3857ef1d Use JSStringCreateWithUTF8CString and skip NSString decoding when loading the bundle
Summary: public

Benchmarking our startup path has shown we spend a lot of time decoding strings (iPhone 4S / iPhone 5):

* reading a 2MB JS bundle: 35ms / 15ms
* decoding is to an `NSString`: 186ms / 78ms
* transforming that to a `JSString`: 29ms / 10ms

Instead of going through an `NSString` transformation, we generate a null-terminated bundle (0.1ms / 0.05ms to copy the data) and use `JSStringCreateWithUTF8CString` (121ms / 53ms) to generate the string. That makes decoding 70% faster.

Reviewed By: javache

Differential Revision: D2541140

fb-gh-sync-id: 09a016b8edfd46a9b62682c76705564d2024e75e
2015-10-16 08:11:25 -07:00
Tadeu Zagallo 529687f923 Defer calls until bridge finishes loading
Summary: @​public

When de-batching the calls from native -> JS, some calls were being dispatched
before the bridge had finished loading, which would cause lost calls when running
on the `ContextExecutor` and redbox when running in the Chrome debugger

Reviewed By: @javache

Differential Revision: D2540746

fb-gh-sync-id: ece29406648d3cbcb42cef3b32b8774ff0c15fd8
2015-10-14 09:49:23 -07:00
Tadeu Zagallo baf5b7b4d5 De-batch native->js calls and react updates
Summary: @​public

Take a step back and de-batch the bridge calls so we can have better profiling data and a better starting point to work on future optimisations. Also gave a 10~15% win on first render.

Reviewed By: @javache

Differential Revision: D2493674

fb-gh-sync-id: 05165fdd00645bdf43e844bb0c4300a2f63e7038
2015-10-13 06:44:25 -07:00
Tadeu Zagallo f7065e5c0a Support start and stopping systrace from repl
Reviewed By: @jspahrsummers

Differential Revision: D2512911

fb-gh-sync-id: f5441219f9d7063b3602c55efac9f07407e33f56
2015-10-12 09:45:40 -07:00
Alexey Lang e3e9be9efb Log time to prepare native config
Reviewed By: @jspahrsummers

Differential Revision: D2517033

fb-gh-sync-id: fd560304f163b0ab9be592024e2a9b793fb990bc
2015-10-08 08:46:25 -07:00
Alexey Lang 7b514c63df Log native modules init time and config inject time separately
Reviewed By: @jspahrsummers

Differential Revision: D2508010
2015-10-05 11:05:23 -07:00
Abhishek Sood e08a507f75 This reverts D2502620
Differential Revision: D2503381
2015-10-02 11:33:23 -07:00
Alexey Lang 737e011f96 log native modules init time and config inject time separately
Reviewed By: @tadeuzagallo, @jspahrsummers

Differential Revision: D2502620
2015-10-02 09:55:21 -07:00
Alexey Lang e727fc817b Pause JS DisplayLink if nothing to process.
Reviewed By: @jspahrsummers

Differential Revision: D2489107
2015-09-29 09:22:10 -07:00
James Ide 7615d74d14 Check self.isValid in RCTBatchedBridge after initial script evaluation
Summary: I noticed that sometimes the batched bridge would be valid before `[self enqueueApplicationScript:url:onComplete:]` but then become invalid in the completion callback. This diff checks `self.isValid` inside of the callback.

Closes https://github.com/facebook/react-native/pull/2016

Reviewed By: @​trunkagent, @jspahrsummers

Differential Revision: D2443438

Pulled By: @tadeuzagallo
2015-09-24 08:20:05 -07:00
Marc Horowitz a87ba4ab4c Prepare the bridge for C++
Reviewed By: @nicklockwood

Differential Revision: D2432291
2015-09-18 15:04:28 -07:00
Nick Lockwood 789a07c5a4 Added code to sync __DEV__ value to RCT_DEBUG
Summary: @​public

When using bundled JS the `__DEV__` flag is set to false by default, which can cause errors to be missed if used for testing. This diff adds logic to override the `__DEV__` value when running in RCT_DEBUG configuration, so that the JS debug checks are enabled.

Reviewed By: @tadeuzagallo

Differential Revision: D2429533
2015-09-11 07:15:27 -07:00
Tadeu Zagallo 20cd649553 Automatically save and convert JavaScript profile to chrome format
Summary: @​public

Migrate scripts to open source and add new route on the packager
to directly convert profiler outputs to a devtools compatible format.

Reviewed By: @jspahrsummers

Differential Revision: D2425740
2015-09-11 06:40:26 -07:00
James Ide 3f4c7e40c6 [Bridge] Consistently post "DidFailToLoad" notification when there's an error
Summary:
Previously the bridge sometimes never fired RCTJavaScriptDidLoadNotification or RCTJavaScriptDidFailToLoadNotification if there was an error (for example, if the source code loaded but we couldn't inject the JSON config). This diff moves the error handling into a method called `stopLoadingWithError` that the bridge can call whenever there is an error.

Also if the script failed to load, the BatchedBridge still called `executeSourceCode`. With this diff the `_loading` flag is set to NO when the script fails to load, and `executeSourceCode` returns immediately when `_loading` is false. This way the bridge does not try to execute JS when there is a loading error.
Closes https://github.com/facebook/react-native/pull/2520
Github Author: James Ide <ide@jameside.com>
2015-09-04 03:28:51 -08:00