(turn) from four minutes to two seconds--talk about some best practices for client performance optimization

Source: Internet
Author: User

Turn: http://www.cnblogs.com/marvin/p/WinformOptimizSkill.html background

Recently with the after-sales manager to eat, he and I again talk about two years ago for the company temporarily wrote a client, still very excited to tell me that this client has been blown out of the company's other versions of the client, including the oldest Delphi write, ASP, and the latest WPF write client. No matter how large the interface (the integrated computer room), this system is instantaneous open, and the operation is very stable, once successfully deployed after the basic no problem.

This version of the client is just a temporary replacement version: The original Delphi client is too slow, in large data center monitoring takes 4-5 minutes to enter the main monitoring interface, and the ASP. NET version of the client is often unstable (ie browser does not support 7* 24 Hours of asynchronous refresh), the latest WPF client is still in the design phase, so stepped decided to develop a temporary transition version, then only developed for one months, did not expect to be so successful, so far still let our after-sales department relish. In fact, there is not much advanced technology, but there are a lot of development skills and programming ideas. I still see a lot of people making simple mistakes (such as the VS2010 Toolbox add-ons), causing their systems to be very slow, but they are always complaining about programming language problems, Windows system problems, machine performance is not ...

I decided to share some of my practical experience with you: it is not necessary that you have the skills to make a stable and fast system, more often, it depends on whether you have a product awareness, whether to let your software really close to the user.

System interface and function

First look at the original system interface is how the child:

Its functionality is as follows, and my newly written client adds the ability to support the generation of OCX controls:

The physical architecture of the entire system is this:

Problems existing in the original system
    • Load Main Page Slow

      • As the number of interfaces increases, more load times are required
      • As locations and devices increase, loading can take more time
    • Switch cards between pages
    • Slow data display
    • The alarm status of the location is inaccurate and has a delay
    • More severe when the alarm is more complicated

Basic methods of client performance optimization

Let's take a look at some of the ways to solve these problems with the original system.

Get It On demand

Most of the cases, what we can actually see is extremely limited, no matter how large the system is, how rich the function, in fact, presented to the user is extremely limited.

On-demand access to the monitoring interface

Said before, monitoring the interface of the main interface are configured, is by the engineer to drag the control up to achieve, we also see the above graph is also rich, mainly using a large number of images, so our system in the preservation of these configuration interface, but also saved the interface picture of the stream of bytes. Large data centers can add up to 1G in size because of the interface. Such a large interface, if all are directly loaded into the interface, the first time, even in the case of the intranet, assuming that your network can 1s download 20M about, also 50 seconds, close to 1 minutes, meet the network peak, spend 1-2 minutes is not strange.

Is it necessary for us to have all the interfaces loaded in, of course not. We only need to load the first interface, the other interface when needed (user click or alarm need to jump) before loading, so that our speed inside the upgrade, which is on demand loading!

Of course, the light, the actual work will have a lot of problems. For example, how do you implement a page that does not implement and know if the page is alert (you must parse the controls on each interface to know which controls are included in an interface before you know which interface the monitoring indicator alarms are on)?

My steps are as follows:

    • When saving the interface, store the ID list of the control on the interface to the device record.
    • Load all device records only (name + list of control IDs)
    • Append the corresponding information to the tree node
    • Generates an interface based on the corresponding tree node's alarm information when the interface needs to be displayed
Refresh the data on the interface as needed

Do monitoring system, in addition to the alarm page must be real-time notification to the customer, monitoring the data interface, in fact, just show the current display page data can be.

What to do, we can provide a separate program to manage all the received data, and then provide an interface to get the current data to the client, see the following changes to the schema.

Some people may wonder, why not provide this interface directly in the collector? Because this is the configuration interface, the interface of the control to take which collector data is unknown, so it is more convenient to put the data together in a unified management. And the collector can work in the hour, and the client is often to open the closed ...

The inverse example in VS2010

If you have used VS2010 to develop custom WinForm components, then everyone to its toolbox load custom components This feature is definitely impressive, every time you choose to add items, and then choose a custom control DLL, it is very painful, especially my computer is busy and loaded with a lot of plug-in cases, For a very simple function, I need to spend 4 minutes to open the interface of the select file, which loads a lot of COM components I do not use most of the time, I really can not imagine the development of this feature of the program Ape is how to think. Fortunately, Microsoft has finally improved this feature in VS2013, but not enough. In my opinion, it is entirely possible to load the COM component asynchronously, give the prompt to load, and immediately display the " Select " button, so that the experience immediately rises to a level.

Lazy Loading

Lazy loading refers to the use of time, and then to the actual construction.

Lazy Loading of the tree menu

The tree-shaped node of the tree menu is constructed as an example of the most appropriate explanation. You can try to load 1000 tree nodes and build them into a tree to see how long it takes to get in the WinForm. Is there any need to do so in our practice?

You can think about it when you look at the tree navigation, is not from the root node to the child node finally to the leaf node such a step-by-step look down, most of the time, in fact, we only need to see the root node first. For example, the following:

In this case, we can get all the tree nodes, but only one tree with the root node is created, the child node is loaded after the user clicks, and if it has been judged, the loaded operation is not performed. The basic method is to append a field in the tag to indicate whether the child node has already been loaded and the reference code is as follows:

private void TreeDevices_BeforeSelect(object sender, TreeViewCancelEventArgs e){    var myNode = e.Node.Tag as NTier.Model.MyTreeNode; if (myNode == null) return; if (myNode.IsSubNodeLoaded == false) { //还没有加载数据,主要是指机房节点 LoadNodesOfSubMainForm(e.Node, myNode); //加载树形子节点 } //已加载了数据,则生成相应的界面 LoadFormModel(myNode);}

Here the lazy load is a bit like on-demand loading, except that lazy loading has to load all the data, but it doesn't build into a UI tree, but instead builds it when it's used.

Right-click Deferred initialization

Another place is the right-click menu for each control. Because each context menu displays content that needs to be judged based on the type of control and the permissions associated with it, we see that the right-click menu must be artificially manipulated to show it, so there is no need to generate a corresponding context menu for each control in the process of creating the interface. Instead, when the context menu is popped up, the relevant judgment is made, delaying the creation of the right-click menu.

The Warp is Straight

We know that if you want to see all the nodes of a tree, the common approach is to use recursion for breadth traversal or deep traversal. However, traversal is very time-consuming when there are more tree nodes. In our system, alarms have to be processed first, so I use types in my system to Dictionary cache the data types () associated with each attribute node so that I ID can locate the specified tree node immediately when an alarm occurs.

Cache, or cache cache interface

Our system is a configuration interface, which restricts the generation of interfaces to be dynamic. If we use on-demand loading, then the interface is generated in real-time, how can we do a quick page switching?

var tempPanel = _panelCache.CreatePanel(this, formModel, myNode.AgentBm); //创建Panel

Here, I specifically wrote an interface of the cache class, if there is no cache, then dynamically created, if there is a cache, directly return to the cached interface. At the same time, the cached interface is managed based on the latest opening times and clicks of the interface. We know that the entire large-scale system, in fact, the user's attention to the interface is also limited, generally they will only focus on the most important interface, the most commonly used is also these several interfaces. Through the management of the cache, not only can realize the fast switching between interfaces, but also reduce the memory occupied by the system. My entire client program file size after compression within 500k, while the running period of memory consumption basically maintained around 50M .

Cache data

Looking at the modified architecture above, we know that getting the data is now available after opening the interface, until the connection is made and the data is obtained before it can be displayed on the interface, which can take up to 1-2 seconds, and the network is worse. How can you make sure that our system is running faster? Here we have a simple way to centralize the server by timing the current monitored data into the properties of the control, while the system loads the control while the value is displayed, so that it can appear as if the system is getting the data immediately . And because the cached value is timed to write the latest value, this practice to a large extent to ensure that the value in the cache is correct.

asynchronous, or asynchronous

Async is the Magic Weapon for improving program responsiveness and user experience. The controls in C # and most of the flow-action classes provide methods to support asynchronous operations: BeginXXX and EndXXX . The principle is also very simple, BeginXXX when used, the operation is added to the thread pool, after completion of the call a callback function.

a user-friendly system should be able to use asynchronous operations reasonably, ensuring that UI updates are performed and time-consuming operations are not blocked . Most people write code, always call directly, when the control is less or complete simple tasks, you generally do not feel, but in the number of controls, we can easily feel the interface card, not smooth.

When I was developing the new system, I was conscious of using asynchronous operations in the control load, control data refresh, control alarm state switching, and so on, so that the system could not feel the card at all when the interface was opened.

But using async to remember, async can improve the user experience, but there is no real improvement in performance , if you feel the data response is delayed, you still have to spend effort to find the root cause.

Merge processing interface data Refresh merge processing

Let's see how the original interface refreshes the data:

Open interface, refresh data, new thread--timer Refresh data--close the thread.

People who know enough about Windows systems know that a new thread is very resource-intensive. In this case, we can provide a unified managed refresh thread throughout the system, simply refresh the interface that currently needs to be refreshed:

Refresh Thread---determine if the current interface exists---timed refresh data

In conjunction with the above asynchronous operation, our controls are very fluid when refreshing data.

Alarm Jump Merge Processing

We mentioned above, in the system alarm, you have to jump to the alarm page, this mechanism in a large number of alarm concurrency, there will be very large problems, it is likely that our system will be in a different interface to jump to die. For the users of the system, in 1-3 seconds of multiple alarms, we can actually handle as an alarm, we just go to the last alarm occurred page jump can, so that both achieve the corresponding effect, but also reduce the pressure of the system. This is the merging process when the alarm is concurrent.

Visual Deception

In some cases, we do not have a short time to improve performance, it takes so much time, in this case, we have some good practice?

Give a hint or a progress bar

If you often use mobile phone to log on Weibo, and so on, certainly to these apps loaded pictures have some experience, especially if you are in the network poor situation, the same is to wait 1 minutes to load the picture, if the app does not have any hint, then, after 30 seconds or 20 seconds, you may not be able to take him off, Because you feel like it's been a few minutes, and it may be far away, and if the app can prompt the current number of bytes downloaded, the current download progress, then, 1 minutes of waiting, you seem to be able to accept, after all, the network caused the problem. This is a kind of visual deception.

In a system loading process, there are hints and no information, there is a progress bar and no progress bar, give people feel the speed is not the same, even from the actual situation of the two without any difference.

Secretly loaded

Many times, the operation of our system needs to get some up-to-date data from the server to support the basic operation. This part of the time is essential to you, many people think that there is no way to optimize, not actually. Many of our programs actually provide a user name and password input box, in fact, in the process of user input, we can still use. In the process of ejecting the login window and entering the account and password into the system, there will usually be 3-5 seconds of time.

I see a lot of people write programs, pop-up login box to be honest pop-up, and then after entering the user name and password in the data acquisition and loading, in fact, we have wasted these times. If you can use these 3-5 seconds effectively, then you have won the starting line.

Simplifying data

Another important use of visual deception is in the rendering of curves. In the computer room monitoring, we have some equipment monitoring more frequently, a day to produce up to tens of thousands of of the data, so much of the data drawn to a 24-hour curve, we will see a lot of dense points, drawing these points is very time-consuming and resource-intensive. And we provide the curve to the user to see what the purpose is to see the trend of the day changes, too much dense point is actually not necessary, we see, if the data points more, the second curve will be more dense, looks like a thick line:

After compressing the curve with a simple algorithm, the speed of the historical trend is very fast and very smooth. We compare the above two curves, in fact, for the user, may prefer the first curve, because his reaction trend is more beautiful, there are wood?

Using unit test-assisted development

In my blog post, I've always emphasized the use of unit testing, whether it's development or refactoring. I don't think it's too much to emphasize.

In the development process, we should consciously build our functions, classes, and assemblies for unit testing purposes, and if your functions conform to unit testing requirements, it is generally easier to refactor and maintain. In addition, in our development process, many times need to verify that a feature is available, the use of unit testing, will be very quick to help you to complete this verification operation. I think a lot of our programmers development efficiency is not high, especially in the development of a large system, like the whole system to debug, or in the system with a variety of configuration or conditional compilation to debug, this habit is very bad. Add configuration in the program is easy to confuse the program structure, the code reading experience is not good, many times if we forget to remove this configuration, it is easy to release the system has a greater impact.

Another benefit of using unit testing is that we can perform performance tests on a method at any time, and find out which code has a big impact on our system. I'm used to adding private functions to the test together, and here's an auxiliary method for calling a private function:

PublicStaticObjectInvokepmethod (type type, string methodName, object classinstance, object[] @params) { const BindingFlags Flags = BindingFlags.  NonPublic | BindingFlags. Instance | BindingFlags. Static; var methodInfo = type.  GetMethod (methodName, flags); var result = MethodInfo.  Invoke (Classinstance, @params); return result;}                 
Provide complete log information

In daily development, I have been telling my colleagues about the importance of journaling. Believe that there is a certain development experience to know in the system to write logs, but, how to write a good log, many people can not grasp. Here I make a few suggestions:

    • Level by importance and verbosity of logs
    • Provides debug level and run level logs
    • Note Record System Information and configuration information
    • Record when the state changes
    • Merge the same information
    • Business logic capable of reacting to program runs

Before our system was our own implementation of the log components, I rewrite in C #, introduced the Nlog log component, I think this log component is very useful. In addition, I have provided a debugging window for the UI interface so that the implementation engineer can quickly locate the problem when commissioning the site.

In the actual running process, because of good log information, I can quickly troubleshoot a lot of problems, and most of the problems are caused by the configuration. I have consistently stressed to colleagues that, as far as possible, do not trust the field engineer to give you the judgment, should be the field engineer to provide evidence to you, and to provide what kind of evidence, as a research and development, you are the most clear. A good log system should be able to accurately locate the problem according to the log information, in the case of offline to the maximum extent possible to respond to the current system configuration, operation status, and error messages.

Results of optimization

The end of the client in C # rewrite All aspects are very good, the system is very stable, the whole system into about 2s, the page switch around 1s, most importantly, the client and the size of the system is not related to the size of the data center. Let's look at a comparison of the new and old systems in the loading process:

Obviously, after some optimization in the above-mentioned way, our system has been improved in each step, and some steps can be synchronized by asynchronous, caching, spoofing, and so on, which greatly accelerates the system loading and corresponding.

Summarize

I hope that through this article, the client optimization of some methods to share, for your reference. There is no such thing as a deep knowledge, nor a programming language that you have to use, just a few simple tricks and a combination of applications that can increase the response speed of a system from 4 minutes to just two seconds. Of course, we have many other methods, such as distributed ... Whatever the skill, I think there are some basic principles to follow:

    • Think in terms of users
    • Never give your choice to a user
    • The most extreme conditions must be considered.

Review What this article says:

      • The basic method of accelerating system response

        • Get It On demand
        • Lazy Loading
        • The Warp is Straight
        • Cache
        • Asynchronous
        • Merge processing
        • Visual Deception

          • Give a hint or a progress bar
          • Secretly loaded
          • Simplifying data
      • Program stability

        • Using Unit Tests
        • Provide complete log information

(turn) from four minutes to two seconds--talk about some best practices for client performance optimization

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.