In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces the relevant knowledge of "how to optimize AngularJS". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
At Scalyr, we recently started to rewrite our web client. Scalyr Logs is a multi-purpose monitoring and log analysis tool. Most query execution in our dedicated log database is controlled in tens of milliseconds, but each page response needs to load the page, which may take several seconds to present to the user.
The single-page design architecture promised not to drag back the strong performance of the background, so we began to look for the right framework, a person named AngularJS stood out, and following the principle of "fail fast", we began a challenging journey: a rewriting of the log view.
Testing an application framework is indeed a serious challenge, when users click on any word in the log, we have to search for relevant information, and there are countless elements that can be clicked on the page; we want to get instant feedback on the paging function of the log. In fact, we have already obtained the log data of the next page in advance, so the update of the user interface has become a bottleneck. If you use AngularJS to directly implement the page fetch function of the log view, it takes 1.2 seconds, but if you carefully optimize it, it can be reduced to 35 milliseconds. These optimizations have been shown to be applicable to other parts of the application as well, and are also well adapted to AngularJS. But we have to break some rules to realize our ideas, which we will discuss later.
A log demo for Github updates
An AngularJS log viewer
In essence, the log view is a list of log messages that can be clicked on every word. So add the Angular instruction to the DOM element and simply implement it as follows:
{{token | formatToken}}
It's normal to have thousands of tokens in a single-page application, and in early tests, we found that it took several seconds to execute JavaScript on the next page of the log. To make matters worse, irrelevant operations (such as clicking on the navigation drop-down box) are also delayed. AngularJS's god says * keep the number of data element bindings below 200. For us, where a word is an element, it has long exceeded this number.
Analysis.
With Chrome's JavaScript profiler tool, we can quickly locate two procrastination points. First of all, each update spends a lot of time creating and destroying DOM elements, and if the new view has a different number of lines, or if any line has a different number of words, Angular's ng-repeat instruction will create or destroy the DOM element, which is too expensive.
Second, each word has its own change watcher,AngularJS to watch these words, which is triggered by a mouse click, which is the culprit that affects the delay of irrelevant operations (drop-down menu navigation).
Optimize # 1: cache DOM elements
We created a variant of the ng-repeat directive. In our version, if the number of bound data is reduced, the excess DOM elements will be hidden rather than destroyed, and if the number of elements increases later, we will reuse these cached elements.
Optimize # 2:Aggregate watchers
Most of the time spent calling change watchers is wasted, and in our application, data bindings on specific words will never change unless the entire log message changes, and to achieve this, we created an instruction "hides" to hide the change watchers of child elements, calling them only when the expression of a particular parent element is modified. In this way, we avoided the full change watchers caused by every mouse click or other minor modification (to achieve this idea, we slightly modified the abstraction layer of AngularJS, which we'll talk about later).
Optimize # 3: defer element creation
As mentioned earlier, we have built a DOM for each word list in the log, and we can get the same visual rendering using a single DOM element in each line; the other elements are created in response to mouse clicks, so we decided to postpone the creation of this part, and we will create it only when the mouse moves over a line.
To achieve this, we created two versions for each line, one is a simple text element to display the complete log information, and the other line is a placeholder to show the effect of the final filling for each word. The placeholder is hidden at first and appears only when the mouse moves to that line, while the simple text line is hidden at this time. As we'll see below, we'll show how placeholders populate word elements.
Optimization # 4: avoid monitoring of hidden elements
We have created another instruction to prevent the monitoring of hidden elements, which supports optimization # 1. We have more hidden DOM nodes than the original data, so we must eliminate the monitoring of the extra DOM nodes. This also supports optimization # 3, making it easier to postpone the creation of word nodes. Because we won't create him until the tokenized version of this line of data appears.
The following code is what all the optimizations look like, and our custom instructions are shown in bold.
{{logLine | formatLine}} {{token | formatToken}}
Sly-repeat is a variant of ng-repeat and is used to hide extra DOM elements rather than destroy them. Sly-evaluate-only-when blocks internal change watchers unless the "logLines" variable is modified. Sly-prevent-evaluation-when-hidden is mainly responsible for displaying the hidden div when the mouse moves over the specified line.
This shows AngularJS's control over encapsulation and separation, and we do complex optimizations without affecting the structure of the template (the code shown here is not the code in the real product, but it shows all the main points).
Result
Let's take a look at the effect, and we add some code to measure it from the click of the mouse to the end of the Angular's $digest loop (which means the end of the update DOM).
We measure the performance of clicking the "next page" button through the Tomcat log, the environment uses Chrome on MacBook Pro, and the results are shown in the following table (each data is the average of 10 tests):
The data has been cached to get data from the server. Simple implementation of 1190 ms1300 ms optimized 35 ms201 ms
This data does not include the time the browser spent on DOM layout and redrawing (after the JavaScript execution is complete), about 30 milliseconds at a time. Still, the effect is obvious; the response time for the next page plummeted from 1200 milliseconds to 35 milliseconds (65 milliseconds if rendering is included).
The data in "getting data from the server" includes the time we used AJAX to get log data from the back end. This is different from clicking the next page button because we prefetch the log data from the next page, but it may apply to other UI responses. Even so, the optimized program can be updated in real time.
This is the end of "how to optimize AngularJS". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.