Avalon is able to process 1W bindings on the page (the angular corresponds to 2000), for two important designs-the event-driven two-way binding chain and the intelligent CG recovery mechanism.
Avalon's two-way binding chain is the object.defineproperties and VBScript that will manipulate VM properties into an accessor property. The accessor property is a special property that requires that we specify a setter, getter method for it (which is, of course, generated within the framework, only the computed properties can do some intervention), and when the user assigns the property, the setter method is called, and when it is read, The Getter method will be used. We do all sorts of things by hack into these two methods, such as relying on collection and event broadcasts, triggering $watch callbacks, the most important of which is to trigger the object that is associated with the subscription array above it, to update the view, which is also the principle of the two-way binding chain. For example
vm.me = 111<div ms-text= "Me" ></div>
The Me will have a subscription array with an object that contains the information to manipulate the div, and if there are two values of the binding property, there are two objects in the array. The trigger occurs immediately when the user modifies vm.me, does not require the $apply or $digest method to be called like angular, nor does it detect all bound objects once as angular. Angular is stuck because once the page is bound to many objects, this detection time is also scary, and this detection may be a deep traversal of the properties of the object to compare. Avalon detects only the corresponding fractional group on one of its properties at a time, so the detection pressure is much less.
Because the binding property transforms the bound object, and the binding object contains the element node or text feature to manipulate the existence of this Convention, the second question is raised, if these bound objects are recycled? Angular Although a $destroy has been added for the $scope object, there is no finer-grained action for the bound object. Avalon before 1.36 in notifysubscribers the element of the bound object is detected in the DOM tree, not all properties of the bound object are set to null and removed from the current subscription array.
avalon1.36/1.4 introduces a new CG recycling mechanism, the {{}} interpolation expression ms-* property on the page, which, after scanning, becomes a bound object that contains name, value, type, param, vmodels, priority, args, Vmodels, evaluator, Handler and other properties and methods, some bound objects will also be more than template, group, $repeat, Proxies attributes (more than 1.36 ago, are now greatly streamlined), so the binding object is also a larger JS object, the more binding properties on the page, these binding objects are more natural, occupying large memory. If there are some removal node operations on the page that involve the element nodes where the binding properties are originally located, then these binding objects should also be destroyed, and we must set the binding.element to NULL to facilitate CG recycling. Before it was in the Notifysubscribers method, but it dealt with a very small array, not all bound objects, so there is always a slip, so bit by bit, on the mobile side is a big problem, will be broken mobile browser.
In 1.36/1.4, a global $ $subscribers array is defined internally, all the generated binding objects are placed inside, and then whenever I let the VM's properties change, it is bound to go through the Notifysubscribers method, when $$ Subscribers an array of objects for detection. And this detection also has the skill, in order to reduce the detection frequency to the browser to cause the pressure, each detection at least through 333MS only then will carry on once.
Detection means, is to determine whether Binding.element is located in the DOM tree, because element may be elements node, text node or note node, IE's native contains method also has a bug, so the detection is also various.
var $ $subscribers = []function removesubscribers () {for (var i = $ $subscribers. length, obj; obj = $ $subscribers [-I.]; ) {var data = obj.data var el = data.element var remove = el = = = null? 1: (El.nodetype = = = 1? typ EOF El.sourceindex = = = "Number"? El.sourceindex = = = 0:!root.contains (EL):!avalon.contains (Root, El)) if (remove) {//If it is not in the DOM tree $ $sub Scribers.splice (i, 1) Avalon. Array.remove (obj.list, data)//log ("Debug:remove" + data.type) obj.data = Obj.list = Data.evaluat or = Data.element = Data.vmodels = null}}}var beginTime = new Date (), Removeidfunction notifysubscribers (acces SOR) {//Notify Subscribers dependent on this accessor to update their own var currenttime = new Date () cleartimeout (RemoveID) if (Currenttime-begintime > 333) {removesubscribers () BeginTime = currenttime} else {RemoveID = SetTimeout (removesubscriber S, 333)} var list = Accessor[subscribers] if (list && list.length) {var args = Aslice.call (arguments, 1) for (var i = list.length, fn; fn = list[- -I.]; {var el = fn.element if (typeof fn = = = "function") {fn.apply (0, args)//force recalculation itself } else if (fn. $repeat) {fn.handler.apply (FN, args)///method to process the monitored array} else if (fn.element ) {var fun = Fn.evaluator | | NoOp fn.handler (fun.apply (0, Fn.args | | []), El, fn)}}}
Of course this is the two key point, in order to improve performance, Avalon is also good at using caching mechanisms like some large applications. Before the FIFO cache algorithm was used, 1.4 was changed to LRU.
<! DOCTYPE html>Mini MVVM Framework Avalonjs Learning Tutorial 22, Avalon Performance Disclosure