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

Comments

Projects
None yet
@Richard-Cao

How to separate js bundle to frameworkBundle and appBundle?

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

@Richard-Cao

This comment has been minimized.

Show comment
Hide comment
@facebook-github-bot

This comment has been minimized.

Show comment
Hide comment
@facebook-github-bot

facebook-github-bot Jan 19, 2016

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!

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

This comment has been minimized.

Show comment
Hide comment
@Creemli

Creemli 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 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

This comment has been minimized.

Show comment
Hide comment
@Creemli

Creemli Jan 19, 2016

@Richard-Cao IOS also have this issue~~

Creemli commented Jan 19, 2016

@Richard-Cao IOS also have this issue~~

@Richard-Cao

This comment has been minimized.

Show comment
Hide comment
@Richard-Cao

Richard-Cao Jan 19, 2016

@Creemli Looking forward……

@Creemli Looking forward……

@Creemli

This comment has been minimized.

Show comment
Hide comment
@Creemli

Creemli Jan 19, 2016

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

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 from [Android]How to separate js bundle to How to separate js bundle Jan 19, 2016

@Richard-Cao

This comment has been minimized.

Show comment
Hide comment
@corbt

This comment has been minimized.

Show comment
Hide comment
@corbt

corbt Jan 19, 2016

Contributor

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?

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

This comment has been minimized.

Show comment
Hide comment
@corbt

This comment has been minimized.

Show comment
Hide comment
@corbt

corbt Jan 19, 2016

Contributor

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)?

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

This comment has been minimized.

Show comment
Hide comment
@Creemli

Creemli 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.

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

This comment has been minimized.

Show comment
Hide comment
@satya164

satya164 Jan 20, 2016

Collaborator

I think @martinbigio was looking into this.

Collaborator

satya164 commented Jan 20, 2016

I think @martinbigio was looking into this.

@martinbigio

This comment has been minimized.

Show comment
Hide comment
@martinbigio

martinbigio Jan 21, 2016

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).

Contributor

martinbigio commented Jan 21, 2016

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

This comment has been minimized.

Show comment
Hide comment
@corbt

This comment has been minimized.

Show comment
Hide comment
@corbt

corbt Jan 21, 2016

Contributor

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.

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

This comment has been minimized.

Show comment
Hide comment
@jkrems

jkrems 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?

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

This comment has been minimized.

Show comment
Hide comment
@dmendis

dmendis 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?

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

This comment has been minimized.

Show comment
Hide comment
@dickeylth

dickeylth Apr 20, 2016

Contributor

ref #570

Contributor

dickeylth commented Apr 20, 2016

ref #570

@Richard-Cao

This comment has been minimized.

Show comment
Hide comment
@Richard-Cao

Richard-Cao May 23, 2016

any solution?

any solution?

@sheldonhan

This comment has been minimized.

Show comment
Hide comment
@sheldonhan

sheldonhan Jul 29, 2016

any updates?

any updates?

@Creemli

This comment has been minimized.

Show comment
Hide comment
@christineRR

This comment has been minimized.

Show comment
Hide comment
@christineRR

christineRR Aug 16, 2016

any progress?

any progress?

@markzhai

This comment has been minimized.

Show comment
Hide comment
@markzhai

markzhai Aug 22, 2016

looking forward to updates

looking forward to updates

@cangyue0322

This comment has been minimized.

Show comment
Hide comment
@cangyue0322

cangyue0322 Aug 29, 2016

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

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

@hzy00

This comment has been minimized.

Show comment
Hide comment
@hzy00

hzy00 Sep 14, 2016

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

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

This comment has been minimized.

Show comment
Hide comment
@mc-zone

mc-zone 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 ? 😄

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

This comment has been minimized.

Show comment
Hide comment
@njafei

njafei 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

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

This comment has been minimized.

Show comment
Hide comment
@jimzhao2012

jimzhao2012 Feb 24, 2017

@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.

@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

This comment has been minimized.

Show comment
Hide comment

@mc-zone Amazing!

@ckitterl

This comment has been minimized.

Show comment
Hide comment
@ckitterl

ckitterl 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?

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

This comment has been minimized.

Show comment
Hide comment
@yoution

yoution 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

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

This comment has been minimized.

Show comment
Hide comment
@Creemli

Creemli Jul 6, 2017

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

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

This comment has been minimized.

Show comment
Hide comment
@jsdario

jsdario Jul 31, 2017

Contributor

@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.

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.

@freemanon

This comment has been minimized.

Show comment
Hide comment
@freemanon

freemanon 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

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

@JasonHao123

This comment has been minimized.

Show comment
Hide comment
@JasonHao123

JasonHao123 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.

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

This comment has been minimized.

Show comment
Hide comment
@zfha

zfha Oct 19, 2017

+1 mark

zfha commented Oct 19, 2017

+1 mark

@punksta

This comment has been minimized.

Show comment
Hide comment
@punksta

punksta 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.

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

This comment has been minimized.

Show comment
Hide comment
@jsdario

jsdario Oct 27, 2017

Contributor

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.

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

This comment has been minimized.

Show comment
Hide comment
@stale

stale bot 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 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 label Dec 26, 2017

@stale stale bot closed this Jan 2, 2018

@virtuallyjeff

This comment has been minimized.

Show comment
Hide comment
@virtuallyjeff

virtuallyjeff 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?

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

This comment has been minimized.

Show comment
Hide comment
@skizzo

skizzo Mar 2, 2018

Was anybody able to use unbundling in combination with CodePush?

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.