Summary:
public
Standardises the image decoding logic for all image sources, meaning we get the benefits of efficient downscaling of images from all sources, not just ALAssets.
Reviewed By: javache
Differential Revision: D2647083
fb-gh-sync-id: e41456f838e4c6ab709b1c1523f651a86ff6e623
Summary:
public
By doing this we fix 2 problems:
1. We use the same url, both the first time the simulator starts with Hot Loading disabled (no `hot` attribute), and after HL has been enabled and then disabled ('hot=false'). By doing so, the packager will rebuild more than one bundle as file changes. We could have ignored this attribute on the packager but I'd rather not contaminate the server with it and instead make the clients send only 2 types of URLs.
2. The code on `RCTBatchedBridge.m` that decides whether or not to enable HMR does so by looking at presence of the query string parameter `hot`. If the parameter is present, even when it's false, it will try to enable HL, which is wrong.
Reviewed By: nicklockwood
Differential Revision: D2807512
fb-gh-sync-id: 728b680c2383c328d8967d34c10e7a6288e455ac
Summary:
public
Unfortunately, it turns out that NSURLComponents.queryItems only works on iOS 8 and above. This diff re-implements the RCTGetURLQueryParam and RCTURLByReplacingQueryParam functions using functionality available in iOS 7.
Reviewed By: javache
Differential Revision: D2803679
fb-gh-sync-id: 56f10bef4894d16197975b6023b7aa5ab106d8cb
Summary:
public
This exposes a proper API for adding synchronous callbacks to JS, as an optional feature of the executor.
This is based on nicklockwood's work in D2764492, but avoids refactoring bridge/executor interactions for the time being, since we agree on this API and can move the actual callsites around later.
Reviewed By: nicklockwood
Differential Revision: D2799506
fb-gh-sync-id: af209d9a0be927f3404205feb16e59745cc37aec
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
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
Summary:
public
This diff replaces the RegEx module method parser with a handwritten recursive descent parser that's faster and easier to maintain.
The new parser is ~8 times faster when tested on the UIManager.managerChildren() method, and uses ~1/10 as much RAM.
The new parser also supports lightweight generics, and is more tolerant of white space.
(This means that you now can – and should – use types like `NSArray<NSString *> *` for your exported properties and method arguments, instead of `NSStringArray`).
Reviewed By: jspahrsummers
Differential Revision: D2736636
fb-gh-sync-id: f6a11431935fa8acc8ac36f3471032ec9a1c8490
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
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
Summary: See #3888 for why this is necessary. Essentially, `[NSBundle mainBundle]` loads the file path for the target app which is the only way to reference images.
cc javache nicklockwood
Closes https://github.com/facebook/react-native/pull/3889
Reviewed By: svcscm
Differential Revision: D2615580
Pulled By: nicklockwood
fb-gh-sync-id: d06ce0987dde666b06bb5a7edf609ed45f325d2c
Summary: public
White space between the end of the first part of the method selector and the first colon was being included in the JS method name.
(See: https://github.com/facebook/react-native/issues/3804)
Reviewed By: javache
Differential Revision: D2605713
fb-gh-sync-id: b4402c9ede5eb31dd38021c902f046a4e0557814
Summary: public
We moved to using `new` instead of `alloc] init` but there was still some calls
left.
Reviewed By: javache
Differential Revision: D2604679
fb-gh-sync-id: ff7300ecbedb55dd5e93873592598810c9b87808
Summary: public
UIExplorer tests were broken due to a refactor that didn't update the RCTShadowViewTests + an off-by-one error in the logic for exporting async methods.
Reviewed By: javache
Differential Revision: D2595810
fb-gh-sync-id: c25a8b8956bff1ef2754bba4a8f10d72a16e2954
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
Summary: public
Added RCTDataRequestHandler, which is responsible for loading data URLs. This moves the logic for data URL handling out of RCTImageDownloader (no longer needed) and into the RCTNetwork library, where it makes more sense.
This also means that it is now possible to load data URLs via XHR, and use them for purposes other than just images.
Reviewed By: javache
Differential Revision: D2540964
fb-gh-sync-id: 4f0418bd6b9186f047cc8297276bb970795af104
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
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
Summary:
Two of the allocation were disabled due to eventual failures on Travis, but
haven't failed internally nor locally. I'm bumping the time out and re-enabling
them to see if that was the case.
Summary:
The arg block for handling structs did not return a value, which was being intepreted as failure. This diff returns YES for success, and also adds an error log for this case so future regressions won't fail silently.
Summary:
There's no good reason for initialProperties to be mutable after the RCTRootView has been created. Passing it in through the constructor means we can skip one dispatch_async.
Summary:
Our events all follow a common pattern, so there's no good reason why the configuration should be so verbose. This diff eliminates that redundancy, and gives us the freedom to simplify the underlying mechanism in future without further churning the call sites.
Summary:
Moved the view creation & property binding logic out of RCTUIManager into a separate RCTComponentData class - this follows the pattern used with the bridge.
I've also updated the property binding to use pre-allocated blocks for setting the values, which is more efficient than the previous system that re-contructed the selectors each time it was called. This should improve view update performance significantly.