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
This is an early release and there are several things that are known
not to work if you're porting your iOS app to Android.
See the Known Issues guide on the website.
We will work with the community to reach platform parity with iOS.
Summary:
This will throw an error message with the problematic callback module/method. Previously we would get an invariant in this case when we try to access `callback.apply` later in the method.
Summary:
@public
After refactoring the MessageQueue a guard was missing on around `batchedUpdates`
call.
Test Plan: Introduce an error on `getInitialState` of `AdsManagerTabsModalView.ios.js`
Summary:
### TL/DR:
```
a="function() {return [22]}"
a.substring(a.indexOf("{")+1,a.indexOf("}")-1) // "return [22"
a.substring(a.indexOf("{")+1,a.indexOf("}")) // "return [22]"
```
### In long: why it is broken now and why it worked before:
I've installed latest iOS 9 and started to see really strange issues when code is minified:
```
Invariant Violation: Application app has not been registered."
2015-06-18 16:29:05.898 [error][tid:com.facebook.React.JavaScript] "Error: Unexpected identifier 'transformMatrix'. Expected ']' to end a subscript expression
```
After some investigation it turns out that new Safari returned a bit different string representation for a MatrixOps.unroll. On old safari:
`function(e,t,n,r,o,i,a,s,u,c,l,p,d,h,f,m,g){t=e[0],n=e[1],r=e[2],o=e[3],i=e[4],a=e[5],s=e[6],u=e[7],c=e[8],l=e[9],p=e[10],d=e[11],h=e[12],f=e[13],m=e[14],g=e[15];}`
while using latest iOS:
`function (e,t,n,r,o,i,a,s,u,c,l,p,d,h,f,m,g){t=e[0],n=e[1],r=e[2],o=e[3],i=e[4],a=e[5],s=e[6],u=e[7],c=e[8],l=e[9]
Closes https://github.com/facebook/react-native/pull/1672
Github Author: Artem Yarulin <artem.yarulin@fessguid.com>
Test Plan: Imported from GitHub, without a `Test Plan:` line.
Summary:
@public
Add PerformanceLogger to keep track of JS download, initial script execution and
full TTI.
Test Plan:
The Native side currently calls `addTimespans` when it's finish initializing
with the six values (start and end for the three events), so I just checked it
with a `PerformanceLogger.logTimespans()` at the end of the function.
```
2015-06-18 16:47:19.096 [info][tid:com.facebook.React.JavaScript] "ScriptDownload: 48ms"
2015-06-18 16:47:19.096 [info][tid:com.facebook.React.JavaScript] "ScriptExecution: 106ms"
2015-06-18 16:47:19.096 [info][tid:com.facebook.React.JavaScript] "TTI: 293ms"
```
Summary:
@public
The current implementation of `MessageQueue` is huge, over-complicated and spread
across `MethodQueue`, `MethodQueueMixin`, `BatchedBridge` and `BatchedBridgeFactory`
Refactored in a simpler way, were it's just a `MessageQueue` class and `BatchedBridge`
is only an instance of it.
Test Plan:
I had to make some updates to the tests, but no real update to the native side.
There's also tests covering the `remoteAsync` methods, and more integration tests for UIExplorer.
Verified whats being used by Android, and it should be safe, also tests Android tests have been pretty reliable.
Manually testing: Create a big hierarchy, like `<ListView>` example. Use the `TimerMixin` example to generate multiple calls.
Test the failure callback on the `Geolocation` example.
All the calls go through this entry point, so it's hard to miss if it's broken.
Summary:
@public
This removes the last piece of data that was still stored on the DATA section,
`RCT_IMPORT_METHOD`. JS calls now dynamically populate a lookup table simultaneously
on JS and Native, instead of creating a mapping at load time.
Test Plan: Everything still runs, tests are green.
Summary:
@public
`[Bridge] Add support for JS async functions to RCT_EXPORT_METHOD` was imported but broke some internal code, reverting the `MessageQueue` that caused the issues and add a test, since the method is not used yet.
Test Plan: Run the test o/
Summary:
Adds support for JS async methods and helps guide people writing native modules w.r.t. the callbacks. With this diff, on the native side you write:
```objc
RCT_EXPORT_METHOD(getValueAsync:(NSString *)key
resolver:(RCTPromiseResolver)resolve
rejecter:(RCTPromiseRejecter)reject)
{
NSError *error = nil;
id value = [_nativeDataStore valueForKey:key error:&error];
// "resolve" and "reject" are automatically defined blocks that take
// any object (nil is OK) and an NSError, respectively
if (!error) {
resolve(value);
} else {
reject(error);
}
}
```
On the JS side, you can write:
```js
var {DemoDataStore} = require('react-native').NativeModules;
DemoDataStore.getValueAsync('sample-key').then((value) => {
console.log('Got:', value);
}, (error) => {
console.error(error);
// "error" is an Error object whose message is the NSError's description.
// The NSError's code and domain are also set, and the native trace i
Closes https://github.com/facebook/react-native/pull/1232
Github Author: James Ide <ide@jameside.com>
Test Plan: Imported from GitHub, without a `Test Plan:` line.
Summary:
This allows you to select the displayed owner hierarchy, and see the styles,
props, and position.
@public
Test Plan:
Open the inspector, select something in the middle of the page. Click the
breadcrumb train in the inspector, and verify that:
- styles are reflected
- margin/padding/box is correct
- the highlight updates to show the selected item
See video as well.
[Video](https://www.latest.facebook.com/pxlcld/mqnl)
Screenshot
{F22518618}
Summary:
@public
Right now the profiler shows how long the executor took on JS but doesn't show
how long each of the batched calls took, this adds a *very* high level view of JS
execution (still doesn't show properly calls dispatched with setImmediate)
Also added a global property on JS to avoid trips to Native when profiling is
disabled.
Test Plan:
Run the Profiler on any app
{F22491690}
Summary:
Wraps the setImmediate handlers in a `batchUpdates` call before they are synchronously executed at the end of the JS execution loop.
Closes https://github.com/facebook/react-native/pull/1242
Github Author: James Ide <ide@jameside.com>
Test Plan:
Added two `setImmediate` calls to `componentDidMount` in UIExplorerApp. Each handler calls `setState`, and `componentWillUpdate` logs its state. With this diff, we can see the state updates are successfully batched.
```javascript
componentDidMount() {
setImmediate(() => {
console.log('immediate 1');
this.setState({a: 1});
});
setImmediate(() => {
console.log('immediate 2');
this.setState({a: 2});
});
},
componentWillUpdate(nextProps, nextState) {
console.log('componentWillUpdate with next state.a =', nextState.a);
},
```
**Before:**
"immediate 1"
"componentWillUpdate with next state.a =", 1
"immediate 2"
"componentWillUpdate with next state.a =", 2
**After:**
"immediate 1"
"immediate 2"
"componentWillUpdate with next state.a =", 2
Addresses the batching issue in #1232. cc @vjeux @spicyj
Summary:
Adds support for JS async methods and helps guide people writing native modules w.r.t. the callbacks. With this diff, on the native side you write:
```objc
RCT_EXPORT_METHOD(getValueAsync:(NSString *)key
resolver:(RCTPromiseResolver)resolve
rejecter:(RCTPromiseRejecter)reject)
{
NSError *error = nil;
id value = [_nativeDataStore valueForKey:key error:&error];
// "resolve" and "reject" are automatically defined blocks that take
// any object (nil is OK) and an NSError, respectively
if (!error) {
resolve(value);
} else {
reject(error);
}
}
```
On the JS side, you can write:
```js
var {DemoDataStore} = require('react-native').NativeModules;
DemoDataStore.getValueAsync('sample-key').then((value) => {
console.log('Got:', value);
}, (error) => {
console.error(error);
// "error" is an Error object whose message is the NSError's description.
// The NSError's code and domain are also set, and the native trace i
Closes https://github.com/facebook/react-native/pull/1232
Github Author: James Ide <ide@jameside.com>
Test Plan: Imported from GitHub, without a `Test Plan:` line.
Summary:
`mountSafeCallback` simply wraps a callback in an `isMounted()` check to prevent crashes when old callbacks are called on unmounted components.
@public
Test Plan:
Added logging and made sure callbacks were getting called through
`mountSafeCallback` and that things worked (e.g. photo viewer rotation etc).
Summary:
Add `AlertIOS.prompt`
It's compatible with the js spec, with the exception that I had to add
a callback param since it's async. Also supports the same button configuration
as `AlertIOS.alert`.
@public
Test Plan:
I've updated the `AlertIOS` example on UIExplorer with every
valid combination of
parameters, so just going through it should be fine.
Summary:
The curly braces seems to be redundant.
Closes https://github.com/facebook/react-native/pull/811
Github Author: xcatliu <xcatliu@gmail.com>
Test Plan: Imported from GitHub, without a `Test Plan:` line.
Summary:
As it was implemented, the jsdoc parser would look only the first non-blank line immediately preceding a function declaration. However, the line that was set as the beginning of a function declaration was where the opening bracket (`{`) was. This is insufficient for functions whose definitions span multiple lines. For example, this declaration would not find the comments above it:
```
/**
* Clones rows
**/
cloneWithRows(
dataBlob: Array<any> | {[key: string]: any},
rowIdentities: ?Array<string>
): ListViewDataSource {
...
}
```
With this change, the parser will first check if we have a closing parenthesis. If we do and don't have a matching open parenthesis we continue moving up the lines until we find it. Then we set previous line to be the line before that, the true beginning of the function declaration.
Closes https://github.com/facebook/react-native/pull/360
Github Author: Peter Janak <pjanak@nhl.com>
Test Plan: Run the website