primers

This article is a summary of my recent research and practice on Weex in iOS. The practices mentioned in the article may not be best practices, and the methods described in the article may not be a standard guideline manual, so the title is “Pseudo-best Practices point north.” There is a better way to welcome everyone to leave a message to discuss, learn together.

Since I don’t know much about Android, I won’t cover it in the following articles.

React Native and Weex

Since the day Weex was born, he has been compared to React Native. React Native proclaimed “Learn once, write anywhere,” while Weex proclaimed “Write once, Run Everywhere.” From the day Weex was born, he was expected to unify the three terminals. React Native supports iOS and Android, while Weex supports iOS, Android, and HTML5.

On the Native side, the biggest difference between the two is probably whether the JSBundle is subcontracted. React Native officially only allows the React Native basic JS library and business JS to be bundled into a JS bundle, and does not provide the function of subcontracting. Therefore, if you want to save traffic, you must make a subcontracting package tool. Weex’s default JS bundle contains only business JS code and is much smaller. The basic JS library is included in the Weex SDK. Compared with Facebook’s React Native and Microsoft’s Cordova, Weex is much lighter and smaller.

On the JS side, Weex is also known as Vue Native, so the difference between React Native and Weex is between React and Vue.

The author did not write React Native, so he could not objectively compare the two. However, zhihu has a good article about Weex and React Native comparison, which is recommended for you to read.

Two days ago, @Allen Xu Shuai also posted a post on the Glow Technical team blog titled React Native’s Practice in The Glow. The post also talks a lot about the React Native practice, which is highly recommended for you to read.

Ii. Basic introduction

About Weex, of course, the most basic or read through the document, the document is the best official learning materials. There are two official basic documents:

Tutorial documentation Manual documentation

This document contains all current Weex components, modules, and the usage and attributes of each component and module. If you have a problem, you can come and look it over. It is likely that some components and modules do not have those properties.

1. Weex buckets and scaffolding

After reading the official documentation, you can start building the project.

Our company has written 4 articles on Zhihu about Weex Sinking Guide. These four articles are still well worth reading.

Weex, like the front-end project, has its own scaffolding bucket. Weex – Toolkit + Weexpack + playground + code snippets + weex- devTool.

Weex-toolkit is used to initialize projects, compile, run, debug all tools.

Weexpack is used to package jsBundles and is actually a wrapper around Webpack.

Playground is a launched App that can be used to display actual pages on mobile phones in real time by scanning codes.

Code Snippets This is an online playground.

I’m sure you all have Native apps. If you don’t have any, use weexpack to initialize a new project. If you already have an App project, the WEEx command is only used for running and debugging.

If you already have aN iOS project, you can directly install the Weex SDK through Cocospod. After initializing the SDK, Native can use Weex. Change the loaded JS address to the IP address of your own company server.


#define CURRENT_IP @"your computer device ip"
// ...

// Change the port number to your port number
#define DEMO_URL(path) [NSString stringWithFormat:@"http://%@:8080/%s", DEMO_HOST, #path]

// Change the JS file path
#define HOME_URL [NSString stringWithFormat:@"http://%@:8080/app.weex.js", DEMO_HOST]Copy the code

Then the whole project can run.

Another point to note here is that the project is running, but every time it runs, it needs to start NPM and open up Weex’s front-end environment. There are two ways to do this.

The first approach is to Hook Xcode’s run command directly and add the script to start NPM in the Xcode configuration. Like this:

The second option is to manually NPM run dev yourself before each run. I personally prefer this approach because you can always type these commands on the command line before Xcode is finished running.

The weex-DevTool is used for debugging.

This tool is basically the same experience as debugging the front end in Chrome.

The specific method of use can be seen in these two articles, which will not be repeated here:

Weex Pitting Guide: Debug Is a Manual Work Weex Debugging Artifact – Weex Devtools User Manual

2. Weex Market plug-in

In daily development, we can develop all Weex interfaces ourselves, and of course use some excellent existing wheels. All of Weex’s great wheels are in Weex Market.

In this Market, there are many written wheels, which can be directly used to save a lot of time.

Like weex-Chart, which is very popular here. The Weex-Chart plugin is implemented via G2-Mobile’s reliance on the GCanvas plugin

If you want to use the Weex Market Plugin, you can use the Weex Plugin command:


$ weex plugin add plugin_nameCopy the code

To add a plug-in to your local project remotely, you just need to type the name of the plug-in. For example, to add Weex-chart, we can type the command:


$ weex plugin add weex-chartCopy the code

Plugins can be removed using plugin remove, such as weex-Cahrt:


$ weex plugin remove weex-chartCopy the code

This plug-in library surface I used weex-Router, also good, with it to do WEEX routing management. Recommended.

3. IOS packaging and release

Weex provides the weexpack command. I think this command is for people who don’t understand the front end of iOS. If Native package is used, Xcode Archive package is still used.

Front-end developers who don’t know anything about iOS can use the Weexpack Build iOS package, which asks for credentials, developer accounts, etc. After all input correctly, you can type ipA file. Complete fool operation.

If you’re an iOS developer, you’re still packing the same package. Only a few JS pieces need to be packaged separately. It is recommended that Weex be managed by a separate Git branch and weexpack or Webpack for this branch. The specific configuration of WebPack is up to each company.

Here is an additional point, this point is also the front god told me. After the webpack is finished, you can check the official webpack website to see what files and dependencies are entered into the package. I packed everything in one go, but a veteran front-end developer would probably check to see if there were any more files typed in. Limit compression package volume, 1KB files are not put in.

Let’s talk about publishing. With the introduction of Weex, hotpatches accumulated in the previous version will be repaired in every release, and the latest JSBundle files will be directly built in the new version. The purpose of the built-in JS is also to open the first screen loading seconds.

4. Hot update

We all know about the role of hot update, otherwise the meaning of Weex will be much less. But there is one more thing to be said here — the hot update strategy.

During the daily development process, we debug the phone on the browser, which is not real-time refresh. (However, real-time updates can be achieved by scanning the QR code on the phone and the phone and computer are in the same LAN.)

Therefore, in the actual production environment, the hot update strategy should be like this: when there is a new HotPatch, the client sends it to the client, and then the client compares the version information with the version information at the next startup. If it is a new version, the client loads the latest HotPatch and renders it on the screen.

I once dreamed of real-time online update. That is to say, once the HotPatch is released online, all users can directly load it after the completion of HotPatch delivery when they are connected to the Internet. Users who are connected to the Internet can realize hot update at the level of seconds. This can be done, but it doesn’t make much sense. The method is to specially maintain a set of Websocket, directly connect to the server, after the delivery can call Native notification, Native client can refresh the page by itself. (Not many companies do that right now, right?)

5. JSBundle version management and deployment

Versioning of jsBundles should be left to the front end. The front end might use version numbers to manage the versions of individual packages. Deployment also involves each company’s front-end deployment process. They will know better. Deployment is also typically accelerated on CDN.

Step on pits and avoid pits

It’s impossible to say that Weex has nothing to lose.

For example, when some interface is pushed continuously, there will be lines across the edge of the page. In addition, Weex cannot reliably catch JS errors or exceptions. This needs to be done by Native. After catching exceptions, Native sends events to the JS Runtime for processing.

Calculating the page width and height is the most important point to pay attention to. Weex uses 750 as the standard for interface adaptation. Therefore, you need to convert according to 750. Another point is that Weex has a round operation, which will lose a little precision. For details, please see the “Weex event transmission of those things” this article inside the source analysis.

Weex JS engine also does not support HTML DOM APIs and HTML5 JS APIs, including Document, setTimeout, etc.

Weex’s implementation of Web standards is not 100% yet, so writing Weex in Vue is not supported.

For example, some CSS styles, most surprisingly, do not support < br>, < form>, < table>, < tr>, < TD >, do not support CSS percentage units, and do not support other CSS standards such as EM, REM, pt length units. Does not support HSL (), HSLA (), currentColor, 8-character hexadecimal colors.

Weex also doesn’t fully support the W3C’s FlexBox specification. It doesn’t support inline, nor does it support changes on the Z-axis, but the need for mobile on the Z-axis isn’t there. Weex Layout is used before the Yoga version, the solution to the problem is also more direct, later upgrade to the latest version of the Yoga, you can support more Flex standards.

For details about unsupported Web standards, please refer to the document. For example, what Web standards Weex does not currently support? These had better have a look first, have a number in mind, so as not to encounter some inexplicable bugs when developing, but ultimately because do not support the cause.

Then there are the components that don’t support synchronous methods yet. Vue 2.0 is not supported yet, officially expected in version 0.12.

As an additional note, Weex issued a warning about custom modules due to Apple’s recent ban on JSPatch:

Weex all built-in Module or Component apis exposed to JS are secure and controllable. They do not access system private apis, do not hack runtime, and do not change the original function positioning of the application.

If you need to extend a custom module or component, be careful not to expose OC runtime to JS, and do not respond to selector:, PerformSelector:, method_exchangeImplementations() expose dynamic and uncontrollable methods to JS, and don’t expose the system’s private API to JS

So this warning specifically says don’t use dlopen(), dlsym(), respondsToSelector:, performSelector:, method_exchangeImplementations(). This is also why some people did not pass the audit with Weex, and some people can pass the audit.

I have heard that there are some bugs in Refresh Control on Android. I don’t know much about the Weex performance of Android, but if it appears on iOS, I think it can be replaced by Native.

In short, Weex or more or less some problems, but the current use of the point of view, does not affect the use of, as long as you know how to be flexible, encountered really can not overcome the obstacles, or is really a temporary bug, so much to consider using native to replace.

More advanced gameplay

Now, a little more advanced gameplay. Even if the following operations are not performed, Weex can go online normally.

1. The page is degraded

Weex supports page degradation by default. If something goes wrong, it gets demoted to H5. It is recommended to make a wire switch. Our company has adopted two levels of switches to deal with the problem of page degradation:

  1. App level switch. This switch is to manage whether the user App uses Weex SDK, which can be configured online.
  2. Page level switches. This switch controls whether Weex is enabled on a page. If not, degrade to H5 page.

In addition to the downgrade, the grayscale strategy is also adopted to ensure that online bugs are minimized.

For example, when the user volume is low peak, turn on the switch for gray scale. There is a gray level through the online real-time error monitoring platform to control, if the Crash rate because of an emergency caused by a steep rise, then immediately shut down the Weex switch, immediately degraded processing.

2. Performance monitoring and burying points

In Weex to the official Demo there is a small dot M float box, click to see the following interface:

Here we click on the performance button:

Here we can see that CPU, frame rate, memory, power, flow and other data are monitored, which are also common data monitored in Native APM. Of course, the M dot is not open source. So this needs each company to do a set of their own monitoring system. This may have been done in each company’s front end, so Weex needs to be connected to the front end performance monitoring.

If we open the tool again, we should see the following options:

We’ve got buried surveillance right here. In the early stage, Weex burial point may be buried by Native, because each family has its own Native complete burial point system. The late burial point can also be handed to the front end at the burial point.

3. Incremental and full updates

I haven’t done incremental Weex updates yet, so I won’t mention incremental updates here. The full update is relatively simple, delivering the entire JSBundle and loading the App at the next startup. Weex packets are much smaller than RN packets, typically around 100-200K. Ali mentioned in a Weex share that they can reach 60-80K after gzip compression.

4. Optimized the loading time of the first screen

In a challenge presented by Ali at the Weex Conf, the web request plus the first screen rendering time adds up to less than a second.

There are three factors involved: network download time, JS and Native communication time, and rendering time.

Network download time can be achieved by supporting HTTP / 2, configuring THE Spdy protocol, domain name convergence, supporting HTTP-cache, extreme compression of JSBundle size, and JSBundle preloading.

When the JSBundle is preloaded, you can download JS in advance at App startup. The remote server pushes packets through a long channel Push, which can be a combination of full/incremental, passive/forced updates.

Ali’s optimization of JS and Native communication time and rendering time is shown in the figure above. The author also has no relevant practice in these two aspects.

5. Vue family bucket

Weex has its own family bucket, but with support for Vue 2.0, its family bucket can be replaced with Vue family bucket. Vue, vue-Router, Vuex, used to have vue-Resource, but UVU dropped the vue-Resource in favor of Axios. So the whole family bucket is Vue, Vue-Router, Vuex, Axios.

If everything is changed to Vue, then the speed of the front screen rendering needs to be solved by Vue. In order to improve the first screen rendering speed, WNS cache + straight out is essential. In the Vue 1. x era, there was no server-side-render scheme, so a template for the first screen non-Vue syntax was written. The introduction of Vue2.0 Server-side-render (Vue SSR for short) successfully makes the front and back end rendering template code isomorphic.

If vue-Router is used only, the JSBundle will become very large when the application is packaged and built, affecting page loading. It would be much more efficient if we could split the components corresponding to different routes into different code blocks and then load the components only when the routes are accessed. Combined with Vue’s asynchronous component and Webpack’s Code Splitting feature, lazy loading of routing components can be easily realized. Reduce the size of JSBundle.

Note that vue-router provides three operating modes: Hash: Uses URL hash values for routing. Default mode. History: Relies on the HTML5 History API and server configuration. Support all JavaScript runtime environments, such as node.js server side.

However, the Weex environment only supports the abstract mode!

Just 7 days ago, Vue released v2.3.0, which officially supports SSR. Therefore, after supporting SSR, SEO can be greatly improved, and the first screen can be opened in seconds. So for performance, SSR must do!

Top level gameplay

Finally, there are some “proactive” gameplay options.

1. Powerful JSService

The JS Service and Weex instances run in parallel in the JS Runtime. The Weex instance life cycle invokes the JS Service life cycle. Create, refresh, destroy life cycles are currently provided.

I did not find relevant examples in the official Demo. There are examples in the official documentation. In the official handbook there is a sentence:

Important note: JS services are powerful but dangerous, so use them with care!

So this is a very powerful piece, and it may be able to do a lot of “magical” things.

2. Weex may have bigger “ambitions”

In the chapter of the official manual “Extending JS Framework”, it is mentioned that the JS Framework can be horizontally extended. It’s a feature that companies probably don’t extend.

Weex wants to respect the usage habits of as many developers as possible, so in addition to Weex official support for Vue 2.0, developers can also customize and horizontally extend their own or their favorite JS Framework.

After customizing your JS Framework, the following code might appear:

import * as Vue from '... ' import * as React from '... ' import * as Angular from '... ' export default { Vue, React, Angular };Copy the code

This also extends horizontal support for Vue, React, Angular.

If the JS Bundle starts the file with a comment in the following format:


// { "framework": "Vue" }.Copy the code

The Weex JS engine will then recognize that the JS bundle needs to be resolved using the Vue framework. And distributed to the Vue framework for processing.

Weex allows multiple frameworks to coexist in a mobile application and parse JS bundles based on different frameworks.

The ability to support multiple frameworks is very powerful, but there’s more to it than that.

If you use the API normally, you will not find Rax in the official documentation without opening the source code. There is no mention of it in official documents.

What is Rax?

Rax was introduced in the article “Rax in Taobao Double Promotion” :

Rax is a cross-container JS framework based on React.

Rax is gzip sized at 8K and lighter than Angular, React, and Vue. React’s 43.7 KB is much smaller.

Rax abstracts the concept of Driver in design to support rendering in different containers, such as the current support: Web, Weex, Node.js are all based on the concept of Driver, even if more containers (such as VR, AR, etc.) appear in the future, Rax will be able to cope with it. Rax tries to smooth out the differences on all sides of the design, so developers don’t have to pay too much attention to differences and compatibility.

If RN and Weex are for cross-terminal technologies, Rax is for cross-container technologies: Browser, Weex, Node.js, etc.

So what can Rax do with Weex? It’s worth waiting for!