Web application development tends to run all user logic and interaction code on the client side, leaving the server to expose REST or RPC interfaces. The compiler is targeted at JS as a platform, and the second edition of ECMAScript was designed with this in mind. Client-side frameworks such as Backbone, Ember and Require encourage the creation of feature-rich applications that are not only rich in code, but also have individual components, many interactions between components and data.
This is really nice and may produce some excellent user experiences, but there is no doubt that it is difficult to develop web applications and web pages.
The root cause is that serving your code and data over the internet, running on some random browser, in javascript, a language you need to be especially careful about, is a platform that completely lacks code deployment. And it's not going to improve anytime soon. I feel like if Star Trek were real life, the reason Captain Jean-Luc Picard couldn't fight every once in a while is because he was still a Krillin dashboard loaded.
I want to highlight three relatively common mistakes and easy solutions, and talk about some unique things we’ve encountered and learned from ReadyForZero.
Strip "cache clearing" header information
You may use a CDN to cache static resources, which is certainly reasonable. Be careful if you're requesting non-cached resources from the server (such as using "custom-origin" on the AWS side to point files to a real web site). You may achieve this by adding a cache-clearing string (header information) to the file name after deploying a new version of the file, so that your file name looks like this:
This is easy to do. You can choose any Hash algorithm to generate a piece of fingerprint information as this string, so that it will change as the file content changes. When the new URL is referenced, it cannot be cached, so the new version on the server can be fetched. This is where the error occurs. There are many recommendations on the web to strip off the "cache clearing" header and instead have your server serve the new version of the file directly. If you have multiple server clusters this may result in inconsistent versions of different files (e.g. html, js) on your site (e.g. js has been updated but html (requested from another server) is still old). Not only that, What's more serious is that it can easily cause the CDN to cache the wrong version. This error occurs like this:
·Initially, all servers are HTML1 and JS1.
·Server A is restarted and serves HTML2 and JS2.
·A client requests main__V2__ from the CDN. js, this file is new at this time so there is no cache on the CDN.
·CDN passed this request to the custom origin you set, and it happened that this request was sent to server B.
· Server B strips the "cache clearing" string and returns the old version.
·CDN caches old files as new ones.
This is a simple and straightforward thing to think about, but blindly following advice from the Internet is likely to lead to mistakes. What's worse is that everything looks fine to you and you don't even know that an error has occurred, but users in other regions using different CDNs may have cached the wrong version. The solution is to not strip out the "cache clearing" string and put the static resources somewhere that correctly supports each version.
2. Dealing with huge JS bombs
Everyone knows that we need to compress our javascript files and concatenate them together. But doing so blindly is not a wise move. If the concatenated files are large, a more efficient approach is to parallelize them. In addition, if you need to modify a certain part of the file frequently, you may cause many places to fail, but a large part of the file has not been modified.
If you separate the frequently modified parts, you can solve the problems on both sides. I recommend using require.js - it enables true dependency management for your javascript, is easy to set up the first time (it will be a pain to add later), and helps you understand and manage dependencies , including some advanced options such as asynchronous loading.
Note: require.js will wait for a period of time before giving up loading resources. This can be achieved by specifying the waitSeconds option. The default value of this option seems to be 7 seconds. It depends on where your user is (for example: mobile phone) ), which can be a very short period of time.
3. No aggregation of error events
You can’t just let your javascript go online and not care about its operation. You can't test every browser and every user's state combination. Additionally, different loading times can lead to weird behavior. Therefore, it becomes very important to establish some kind of feedback mechanism to determine whether your users encounter errors. It's easy, you just specify a global error handler that collects errors and sends them to the server. Here is an example:
The tricky part is that many times there will be some non-zero errors because the user may have installed various weird plugins or other. So you need to track what the stable state is and whether there are any deviations.
ReadyForZero, we capture onError events at the top level, send them to the server, and then generate a daily report that summarizes how many users have made errors and where these errors occurred. We find that many times, the error message is not enough, so we also need to return the last few events from our event system. By analyzing the Backbone or JQuery events recently triggered by the user, it is very helpful to obtain the contextual information when the user triggered the error.
Low-hanging fruit improvements
The frustrating part is that these are not things we have to worry about. Companies should focus more on products and produce them quickly and with high quality. But remember that if these low-hanging fruit improvements are implemented, you'll be able to focus more on the big moves.
People spend a lot of time getting bogged down in trivial matters, but just getting your app up and running can lead to big growth.
1. Is there any memory leak in your client code? are you sure? How did you know?
2. At ReadyForZero [Note 1] we have many smart people dedicated to promoting this art.
[Note 1] ReadyForZero: It is a company funded by Y Combinator. The company's purpose is to help consumers get rid of credit card debt through an online platform.