如何减少Code Push的更新包大小

1、code push的更新包逻辑

  发布codepush更新的时候使用的命令行一般是这样的:

code-push release YourApp ./your_jsbundle_and_imgs/ 3.0.0 --des "TEST code Push"

这个命令行上传了个3.0.0版本的目录上去,而这个目录会包含你的jsbundle和许多图片,假设当前3.0.0版本的文件如下:

your_jsbundle_and_imgs/
├── drawable-mdpi
│   ├── 1.png
│   ├── 2.png
│   └── 3.png
└── index.android.jsbundle

假设2.0.0版本的文件如下,比3.0.0少了个图片:

your_jsbundle_and_imgs/
├── drawable-mdpi
│   ├── 1.png
│   └── 2.png
└── index.android.jsbundle

如果用户是在2.0.0版本之下且之前都没有过code push升级过,我们在code push获取升级包的时候会怎么样?正常的思维就是把不一样的index.android.jsbundle和新增的3.png两个文件下载下来然后升级即可。然而并非如此。

如果之前都没有过codepush升级,codepush会下载3.0.0版本下所有的jsbundle和其他资源文件,所以第一次更新的时候会消耗更多的流量。

而如果之前用户是1.0.0版本通过codepush升级到2.0.0版本,再升级到3.0.0版本,这个时候codepush就只会下载index.android.jsbundle和新增的3.png两个文件。

造成这个现象的主要原因还是react native的图片加载流程并没有那么智能,rn加载图片资源的主要逻辑代码如下:

defaultAsset(): ResolvedAssetSource {           
  if (this.isLoadedFromServer()) {              
    return this.assetServerURL();               
  }                                             
                                                
  if (Platform.OS === 'android') {              
    return this.isLoadedFromFileSystem()        
      ? this.drawableFolderInBundle()           
      : this.resourceIdentifierWithoutScale();  
  } else {                                      
    return this.scaledAssetURLNearBundle();     
  }                                             
}                                               

scaledAssetURLNearBundle(): ResolvedAssetSource {                 
  const path = this.jsbundleUrl || 'file://';                     
  return this.fromSource(path + getScaledAssetPath(this.asset));  
}                                                                 

首先看android,如果是从文件系统加载,即从/data/data/com.....之类的目录或者sd卡加载而不是从assets目录加载的情况下,会从相对该目录下的drawable的目录下加载图片。比如我们加载的jsbundle的文件路径是/data/data/com.your.app.package/codepush/index.android.jsbundle,就会从/data/data/com.your.app.package/codepush/目录下找图片;      而如果不是从文件系统加载,即从assets中加载,这个时候就会从apk包中的drawable中加载图片。

再看iOS,iOS是直接从jsbundle当前目录下寻找assets目录。

code push是从文件系统加载jsbundle,所以其图片资源也要放到相应的目录下,因此code push第一次更新的时候会把所有图片全部下载下来,这样做也是为了方便统一管理,第二次更新的情况下codepush就会做一次patch,通过新老版本比对把有用的资源复制留下而没有就不复制。

             

2、如何减少code push第一次更新的包大小

通过上面的代码分析大家应该有想法了,我们可以只上传需要更新的图片而不是上传所有的图片资源,然后更改RN加载图片的流程,让其可加载文件系统的图片和包中的图片。

           if (Platform.OS === 'android') {
                 if(this.isLoadedFromFileSystem()){//begin assets ios begin drawable android
                     let resolvedAssetSource = this.drawableFolderInBundle();
                     let resPath = resolvedAssetSource.uri;
                     if(drawablePathInfos.includes(resPath)){//已经在bundle目录中有
                         return resolvedAssetSource;
                     }
                     let isFileExist =  Smartassets.isFileExist(resPath);
                     if(isFileExist===true){
                         return resolvedAssetSource;
                     }else {
                         return this.resourceIdentifierWithoutScale();
                     }
                 }else {
                     return this.resourceIdentifierWithoutScale();
                 }
             } else {
                 let iOSAsset = this.scaledAssetURLNearBundle();
                 let isFileExist =  Smartassets.isFileExist(iOSAsset.uri);
                 isFileExist = false;
                 if(isFileExist) {
                     return iOSAsset;
                 }else{
                     let oriJsBundleUrl = 'file://'+defaultMainBundePath+'/'+iOSRelateMainBundlePath;
                     iOSAsset.uri = iOSAsset.uri.replace(this.jsbundleUrl, oriJsBundleUrl);
                     return iOSAsset;
                 }
             }

具体的代码写成了一个库放在了github上:

https://github.com/smallnew/react-native-smartassets

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值