Antecedents feed
Now the team is maintaining and updating an App left by the previous team. Later, after we took over, another batch of new functions were added. In addition, the old code was written in OC before, and we used Swift after we took over, so the package size can be imagined. It was horrible to see.
Ha ha, 323MB, the larger the package size, the more we can optimize.
I didn’t have time to optimize the package size because I was busy with the business code of the new function. Last week, when I saw the 300 MB installation package, I couldn’t stand it, so I started to optimize it.
Scheme selection
Our own code optimization must be the most clear, for example, which functions are no longer used, which codes are invalid codes, which pictures are useless, then these are definitely the first step of our optimization.
Before optimization also incidentally turned over the industry optimization scheme, draw some good optimization ideas, pick up some good software, good script. Here are some of the industry’s best practices. I’ve only been removing some useless images and code so far, but the results are impressive.
- Delete useless images
- Useless code removal
- Image compression (lossless, lossy two schemes, not practiced, the effect is unknown)
- Images in the cloud (our own cloud server and Apple’s on-demand Resources have not been implemented, and the effect is unknown)
- Code optimization (repeated method merging, heavy workload)
- Bitcode (seems to only work in the Appstore)
I’m still in the process of deleting useless resources, and I haven’t finished it yet, but the effect is still remarkable. Let’s take a screenshot of the semi-optimized package volume. The optimization is close to 62MB, of course, this is because we did not optimize before, and there are many useless functions in our code, now do not use, of course, can be deleted.
Enter the actual combat
The first step is to delete unnecessary images
We delete the useless images withLSUnusedResources, filter conditions can be directly used by default, fill in their own project path can be used, very convenient.
The second step is to remove the useless code
Delete unnecessary code, this is a gradual process, we should first ensure that the project is running, not based on our experience, know that this part of the code is no longer, directly delete, that way, the error message will make you crash.
In fact, the first thing we need to delete is files that have no import at all.fui, it can help us find and delete files without import, with the command line tool operation, there are two common command lines. We ignore the search target path with ignore-path, generally ignoring Pods and the tripartite library path we imported directly.
fui -x --path=/Users/zsy/LaiPlus --ignore-path=Pods --ignore-path=LaiApp_Swift/AliyunApiClient find
fui -x --path=/Users/zsy/LaiPlus --ignore-path=Pods --ignore-path=LaiApp_Swift/AliyunApiClient delete --perform --prompt
Copy the code
Perform –perform –prompt: Perform perform –prompt: Perform perform –prompt As shown in the figure below, we confirm deletion by typing Y or N.
Delete this step, we need to perform repeatedly, because after some files are deleted, there will be some new files without import.
Tips1: XiB files will not be deleted, so we need to manually delete xiB files. Tips2: If a storyboard has a reference, the library thinks it has a reference, so the storyboard needs to be removed manually.
Step 3 Delete the Project file
After deleting the useless code, we delete the real files in finder, but the Project files in Xcode also have virtual or red files. Running them directly will cause an error. So we also need to delete the project files, which would be very difficult to delete manually, so I went to the group to ask for help, and sure enough, there is a guy on the scene to implement a simple version of Ruby script, but need to install CocoapodsXcodeproj, this simple script at the beginning of a little pit to me, ha ha, also blame me to take the ism, the initial script looks like this.
require 'xcodeproj' project_path = '/Users/zsy/LaiPlus/LaiApp_OC.xcodeproj' def remove_reference_from_project(reference, project) project.targets.each do |target| target.remove_reference(reference) end end project = Xcodeproj::Project.open(project_path) project.files.each do |file| file_path = (file.real_path) unless File.exists? (file_path) file.remove_from_project end end project.saveCopy the code
As a result, ALL of my Framework was deleted, as well as some TBD files referenced by my previous project, and of course. App files were deleted by mistake, but the build was successful and the program was not run. Although the executable could be specified directly, it would not run automatically. At that time, I had a premonition that I had deleted project by mistake, so I reviewed the script again. The project was revised back, and I printed it manually, which confirmed my guess, so the modified script looked like this.
require 'xcodeproj' project_path = '/Users/zsy/LaiPlus/LaiApp_OC.xcodeproj' def remove_reference_from_project(reference, project) project.targets.each do |target| target.remove_reference(reference) end end project = Xcodeproj::Project.open(project_path) project.files.each do |file| file_path = (file.real_path) unless File.exists? (file_path) suffix_path = File.basename(file_path) unless suffix_path.include? (".framework") | suffix_path.include?(".app") | suffix_path.include?(".tbd") file.remove_from_project end end end project.saveCopy the code
We do not need to delete the file suffix judge, perfect deletion.
Step 4 Delete the referenced code
After the previous deletion, you must find that there are still some useless codes that are not deleted, because they are imported from each other, so the library thinks that we are used. Therefore, we need to help the library find the top-level code of import and delete it, for example: A references B,B references C, and C references A. Such strong coupling caused by unreasonable design in the initial stage, we have to break the cycle by ourselves. Of course, fuI library will help us with the subsequent deletion operations.
Cross-check and delete
In fact, the above deletion operation is the need to repeatedly operate, check, useless code deleted, should produce some useless pictures, so go back to delete those useless pictures. Breaking the loop in step 4 is also a manual task, but since our old code is all in the same directory, this process is acceptable and mainly operational.
conclusion
At present, the optimization is still continuing, and the image compression process has not been carried out, visual inspection of useless code and useless images can be optimized to dozens of MB, should be optimized to about 200MB, the specific optimization to how much, will be shared later. Git commits code frequently, but make sure that every code you commit is runnable. Do not be afraid to delete it slowly, because sometimes you will not be able to get back to the process. Ha-ha, don’t ask me why, and I won’t say if I do.
Voiceover: Baby and her mother have slept, he hid in the restaurant sweating code over the rest of the word, you see, and see and cherish.
Whisper beep beep: Whatever it takes to get a thumbs up, 😂😂😂