H5 subcontracting to optimize the loading time of the first screen
Why should the first screen load be optimized
For doing a lot of things:
Initialize webView -> request page -> Download data -> parse HTML -> request JS/CSS resources -> DOM render -> parse JS execution -> JS request data -> parse render -> download render image
The user will see a blank screen until dom rendering, and will see the full page after downloading the rendered image. The first screen second on optimization is to reduce the time of this process.
After deducting the network difference, the network request has the greatest impact on the first screen startup speed. Due to business requirements, we have to introduce many third-party packages to implement functions, which can easily affect network requests.
Here, we divide the large-volume package into multiple small-volume packages for loading to reduce the request time
Two, analysis of products
Analyze the product to see the percentage of contents in the typed package
yarn build
Copy the code
After finishing the package, if the following yellow text appears, it indicates that the size of the package is too large, we use Baidu Translation to read the explanation:
The size of the bundle is significantly larger than the recommended value. Consider using code splitting to reduce it: https://goo.gl/9VhYWB You can also analyze project dependencies: https://goo.gl/LeUzfbCopy the code
Your package size exceeds the recommended value and can be subcontracted by analyzing project dependencies.
In umi and ALita projects, execute ANALYZE=1 UMI build or ANALYZE=1 alita Build to ANALYZE the products.
We can see that umi.js is still 1.2m in size after compression.
The largest package under Umi. js is the Echarts introduced by the author, with a size of 211KB. Here, only one Echart package is introduced. If more large packages are introduced in the project, the size of Umi. js will be larger than 1M. Requesting this data severely affects download and render times.
At this time, the dismantling of the bag is particularly important.
Iii. Realization of subcontracting
Open the config/config.ts file (.umirc.js for umi2 projects)
export default {
chainWebpack(config) {
config.optimization.splitChunks({
chunks: 'all'.automaticNameDelimiter: '~'.name: true.minSize: 30000.minChunks: 1.cacheGroups: {
echarts: {
name: 'echarts'.test: /[\\/]node_modules[\\/](echarts)[\\/]/.priority: 9 -.enforce: true,},vendors: {
name: 'vendors'.test: /[\\/]node_modules[\\/]/.priority: - 11.enforce: true,},}})},chunks: ['vendors'.'echarts'.'umi'],}Copy the code
Let’s take a look at the properties under cacheGroups, and the rest of the properties will be covered in the following sections.
Properties in cacheGroups are key-value objects. Keys can be named for themselves.
name
: Split block name, providing string or function so you can use custom name, ifname
与chunks
If the names match, the split is performed.test
: regular match path, match entry will be split, installed toname
Package under the name.priority
: Indicates the priority of unpacking. The larger the priority is, the higher the priority is.Order is importantDivide the big bags first and then the restnode_modules
Divided intovendors
The package.enforce
: No matter the size of the package, it will be subcontracted.
Now run ANALYZE=1 umi build to see the effect:
The echarts package has been separated from umi.js. The size of umi.js has been reduced to about 800K. In this case, the message indicating that the package is too large is no longer displayed when you package it using Yarn Build. But for further demonstration, we can separate out the larger packages shown above, such as ANTD-Mob ILE or antD component library packages.
Add to the code cacheGroups above:
antdm: {
name: 'antdm'.chunks: 'all'.test: /[\\/]node_modules[\\/](@ant-design|antd|antd-mobile)[\\/]/.// The antD situation is simulated here. Please consider and analyze it according to the actual project
priority: - 10.enforce: true,},Copy the code
chunks: ['vendors'.'echarts'.'umi'.'antdm'].Copy the code
As shown in the figure, the package of the component library has been separated out and umi.js has become slightly smaller.
Here, it is not recommended to split too small packages, such as the above ANTDM, because it is not meaningful.
Parse splitChunks
Third, we’ve focused on cacheGroups, but now let’s look at the rest of the cacheGroups fields. The documentation on the cacheGroups website explains them, but it feels a bit awkward for beginners like me to read, so I’ll explain some of the fields in the following sections, which should make them a little easier to understand.
Chunks. Valid values are: all | async | initial
parameter | meaning |
---|---|
all | The dynamic and non-dynamic modules are optimized and packaged simultaneously. All modules are thrown into vendors. Bundle. js. |
async | Package dynamic modules into vendor and leave non-dynamic modules as they are (not optimized) |
initial | Pack non-dynamic modules into vendor and optimize dynamic module packaging |
- Dynamic introduction module:
import ('lodash')
- Non-dynamic import modules:
import 'react'
I recommend an article that explains the meaning of the Chunks parameter in detail: the cryptic SplitChunks Plugin for WebAPck4
MaxAsyncRequests: The maximum number of parallel requests that async does. What is the maximum number of asynchronous requests that can be made during an on-demand load, and a value of 1 will not extract the public chunk
MaxInitialRequests: Initial Specifies the maximum number of parallel requests. Same as above.
MinChunks: Minimum number of modules that must be shared before splitting. The minimum number of entry files that a module is dependent on. When the value is greater than or equal to minChunks, the module is packaged into a common package. Less than this value, the module is packaged with each entry file.
MinSize: Specifies the minimum size of the bundle to be split before it is split. Only bundles >= minSize will be split.
MaxSize: Specifies the maximum size of the bundle to be split before it is split. The default value is 0, indicating that there is no upper limit on the size of the bundle to be split before it is split. If maxSize is not 0, it must not be smaller than minSize.
Star point it out