Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to separate js bundle #5399

Closed
Richard-Cao opened this issue Jan 19, 2016 · 41 comments
Closed

How to separate js bundle #5399

Richard-Cao opened this issue Jan 19, 2016 · 41 comments
Labels
Stale There has been a lack of activity on this issue and it may be closed soon.

Comments

@Richard-Cao
Copy link

How to separate js bundle to frameworkBundle and appBundle?

js bundle is more 500k+, but business code is less then 10%

@Richard-Cao
Copy link
Author

@satya164

@facebook-github-bot
Copy link
Contributor

Hey Richard-Cao, thanks for reporting this issue!

React Native, as you've probably heard, is getting really popular and truth is we're getting a bit overwhelmed by the activity surrounding it. There are just too many issues for us to manage properly.

  • If you don't know how to do something or something is not working as you expect but not sure it's a bug, please ask on StackOverflow with the tag react-native or for more real time interactions, ask on Discord in the #react-native channel.
  • If this is a feature request or a bug that you would like to be fixed, please report it on Product Pains. It has a ranking feature that lets us focus on the most important issues the community is experiencing.
  • We welcome clear issues and PRs that are ready for in-depth discussion. Please provide screenshots where appropriate and always mention the version of React Native you're using. Thank you for your contributions!

@Creemli
Copy link

Creemli commented Jan 19, 2016

Wow, I just wanna fix this issue, and have tried https://github.com/mjohnston/react-native-webpack-server/ but failed.

Also I tried to get a dev version bundle and copy the framework code as framework.jsbundle, but when I package the business code, I cannot analysis the correct dependencies.

Looking forward this solutions~~~~

@Creemli
Copy link

Creemli commented Jan 19, 2016

@Richard-Cao IOS also have this issue~~

@Richard-Cao
Copy link
Author

@Creemli Looking forward……

@Creemli
Copy link

Creemli commented Jan 19, 2016

@Richard-Cao Help to remove the [Android] tag and then more people can search this issue.

@Richard-Cao Richard-Cao changed the title [Android]How to separate js bundle How to separate js bundle Jan 19, 2016
@Richard-Cao
Copy link
Author

@Creemli ok

@corbt
Copy link
Contributor

corbt commented Jan 19, 2016

What's the purpose of splitting the bundle? Is it just to make incremental app updates lighter weight, or is there some runtime goal you're trying to accomplish?

@Richard-Cao
Copy link
Author

both @corbt

@corbt
Copy link
Contributor

corbt commented Jan 19, 2016

To help me understand the scope of this, what are the use cases for this beyond just making lighter-weight app updates (which I get)?

@Creemli
Copy link

Creemli commented Jan 20, 2016

@corbt Yeah, this can make user download less code when updating.
And if we can separate them, we maybe not have to bundle the whole codes, we can combine any business project with the framework code, it's lighter, I think.

@satya164
Copy link
Contributor

I think @martinbigio was looking into this.

@martinbigio
Copy link
Contributor

Yeah, we were looking into this mostly to help on TTI but decided to pursue another approach, namely unbundling. To make code downloading faster it's not actually necessary to have multiple bundles but to use a "more clever" protocol (i.e.: one that could send diffs only).

@hufeng
Copy link

hufeng commented Jan 21, 2016

@martinbigio cool

@corbt
Copy link
Contributor

corbt commented Jan 21, 2016

If the main use case for this is just to have smaller updates, then I don't think bundle-splitting is the best solution. There should just be some library that manages updating the JS bundle file using versioned diffs. Such a solution would perform strictly better than bundle-splitting in the size of the updates it would need to send, and would also require less user intervention (in deciding where to split the bundle) to get right.

This would probably make more sense in something like Code Push than in React Native core.

@jkrems
Copy link

jkrems commented Apr 7, 2016

Another possible use is to lazy load parts of a (bigger) app at runtime to reduce startup time. Or is that unlikely to make a difference?

@dmendis
Copy link

dmendis commented Apr 12, 2016

I can give an example of what is being talked about here.

I have a tabbed UI app that already has a bunch of native code already written (iOS and Android). React Native tabs exist side by side with other webview and native tabs. For this scenario, I am having to load all of the app code (core + tab 1 + tab 2 + tab 3) for each tab. Splitting the bundle would mean that:

  • the app kicks off tabs faster (TTI?)
  • some functionality that is rarely used can be directly loaded from a server without having to be pre-cached all the time
  • updating a tab doesn't mean I have to send few megs down the network each time (I understand some diffing protocol was suggested up in the thread)

Also, what is unbundling?

@dickeylth
Copy link
Contributor

ref #570

@Richard-Cao
Copy link
Author

any solution?

@sheldonhan
Copy link

any updates?

@Creemli
Copy link

Creemli commented Aug 2, 2016

Ah, try this: https://github.com/ctripcorp/moles-packer

@christineRR
Copy link

any progress?

@markzhai
Copy link

looking forward to updates

@cangyue0322
Copy link

Looking forward...and...what is unbundling?

@hzy00
Copy link

hzy00 commented Sep 14, 2016

@Creemli moles-packer only resolve the propblem separate js bundle, but how to load them in native module?

@mc-zone
Copy link

mc-zone commented Nov 2, 2016

Hi @martinbigio, @corbt,

Our guys have been develop APPs with RN Integration for a long time. And we think bundle-splitting is also usefull in these scenarios (maybe not limited to Integration).

  • Decrease initial time (Run base codes previously)
    If we could split some initial and definition codes to a _base.jsbundle_ and run it in JSContext previously before users really enter React Native partition, it can decrease user's waiting time .
  • Update partially
    Just like @Creemli said. If we just use a lock version RN(or update infrequently) , the most of changes and updates is about our business codes. We can also separate some framework code (i.e. React, RN Components, APIs, and even with some other framework) into a base bundle, but business codes in business bundle. So we can fetch business bundle standalone from network and get smaller size with download to hot update. Even without diff it's not too bad. I mean, maybe it's easier to implement than integrate a diff algorithm to the entire work flow.
  • Share common modules between multiple bundle
    If we had the _base.jsbundle_ like the above mentioned, we also can make multiple bundle share it as a common library (it's Just like DllPlugin usecase in webpack). Suppose we have two ReactRootView in our App, currently we should bundle out two _jsbundle_ files both independent and overall with base codes, it includes many duplicated.

Let me generalize my opinion through this picture:

(In order to save space, I omit the --platform, .ios, .android here)

image

This simple way seems like the DllPlugin in webpack:

  1. Compile-time

    Build _base.jsbundle. Meanwhile records it's dependecies list and save it, for example, named by _base.manifest.json (output to --manifest-output by cli).

    Build _index1.jsbundle_ with the _base.manifest.json_ passed through --manifest-file. When resolve modules, use their id from _base.manifest.json_ and skip their definition if they has recorded in the manifest. So a clear business bundle has done!

    Build antoher business bundle like the above (We can set a --id-prefix for module id to prevent override).

  2. Run-time

    Run _base.jsbundle_ in JSContext at a good time (e.g. Native App launch done, enter to a parent Activity/Controller ).

    Run _index1.jsbundle_ when user click/open and will enter to this React Native partition.

    Run _index2.jsbundle_ or other when user will enter to another React Native partition.

    Update business bundle from CDN if needed.

How do you think ? 😄

@njafei
Copy link

njafei commented Feb 4, 2017

android can try unbundle. this will separate mian.jsbundle into pieces of js files。

code like:
react-native unbundle --platform android --dev false --entry-file index.ios.js --bundle-output main.jsbundle

@jimzhao2012
Copy link

@njafei unbundle is not a good design, too many small files in output bundles.
it's very easy to split main.jsbundle to base.bundle.js and business.bundle.js, but you need modify the native code for RN to load different parts.

@Richard-Cao
Copy link
Author

@mc-zone Amazing!

@ckitterl
Copy link

ckitterl commented Mar 3, 2017

@jimzhao2012 I don't is a good idea to modify RN code. Mybe could eval business.bundle.js at base.bundle.js?

@yoution
Copy link

yoution commented Jul 5, 2017

I hava package react-native code using webpack,https://github.com/yoution/rn-pack ;also support hot load; and split code using commonChunk plugin,also can fix module id in chunk; but I do not know how to load the splited bundle

@Creemli
Copy link

Creemli commented Jul 6, 2017

We are trying to load base bundle & business bundle in IOS, Android. I will update this when succeed using in production.

@jsdario
Copy link
Contributor

jsdario commented Jul 31, 2017

@jimzhao2012 is there any resource to look deeper into it?
Also, how could we use and pack with unbundle? I can produce the unbundle files, but I don't know yet how to install and run the unbundle result and I don't find many resources on how to do it.

@fmnxl
Copy link

fmnxl commented Aug 30, 2017

For those who wants to try out unbundle, there's a PR documenting it:
https://github.com/facebook/react-native/pull/15317/files

@JasonHao123
Copy link

JasonHao123 commented Oct 15, 2017

I'm working on an existing app rewrite, to separate js bundles and hot reload are two important feature for me to investigate, reasons are:

  1. We are running agile approach, so would like delivery our artifact for each sprint, but deliver through app store/google play too often definitely is not good for commercial app. So we would like to deliver major version by store, minor version by hot deploy.
  2. splitting bundle is because inside the app, there are different modules developed under different project, and some function is not used quite often, for example help & service. to have separate bundle will reduce the dependency and decrease project risk, since we can deliver and replace modules separately

Beyond that, we are also interested in bundle encryption/decryption, and file patching, which makes it more useful for commercial app.

@zfha
Copy link

zfha commented Oct 19, 2017

+1 mark

@punksta
Copy link

punksta commented Oct 27, 2017

Also that can speed up ci/server-side builds. Most of builds has same versions of libs, only code of app changes. We can --reset-cache for app bundle only.

For example: we have project with 1200 npm packages. android ci build takes about 3m, ios 5. 80% of build time takes building of bunde.js

Also we can bundle it with two package processes to speed up.

@jsdario
Copy link
Contributor

jsdario commented Oct 27, 2017

Would this be the equivalent to webpack DDL plugin? I made the following question in stackoverflow about the unbundle speed for rebuilds and I am interested in finding a guide to follow the same strategy for react-native.

Maybe it won't be possible for code-push updates or faster app initialization, but I am interested in improving the DX.

@stale
Copy link

stale bot commented Dec 26, 2017

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. If you think this issue should definitely remain open, please let us know why. Thank you for your contributions.

@stale stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Dec 26, 2017
@stale stale bot closed this as completed Jan 2, 2018
@jjclose
Copy link

jjclose commented Jan 10, 2018

I never saw a resolution of this issue. it's a very important question and a valuable use-case. unbundling is not a solution and not the same thing as splitting the framework from app. is anyone working on this?

@skizzo
Copy link

skizzo commented Mar 2, 2018

Was anybody able to use unbundling in combination with CodePush?

@facebook facebook locked and limited conversation to collaborators May 15, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Stale There has been a lack of activity on this issue and it may be closed soon.
Projects
None yet
Development

No branches or pull requests