首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

提升 web 应用程序的性能(6)

提升 web 应用程序的性能(6)

解决方案Dojo 网格的性能问题主要与输入/输出操作、大量数据访问和浏览器数据呈现有关。可以通过使用合并网格特性的机制来提升 Dojo 网格小部件的性能。            
回顾缓存机制的使用。当数据从数据库加载到本机时,在内存中保存数据一段时间。这是减小服务器端请求数据的响应时间的好办法。这样直到用户更新或修改网格中的数据时才发送请求。缓存机制一般是通过 Dojo 网格本身实现的,但用户对网格进行某种操作时,问题就会发生。以下场景揭示了这些问题:                  
对网格排序多数情况下,可对网格正确排序,因为网格本身在数据存储层实现了排序函数。但数据存储会影响缓存。例如,如果网格列的类型是汉字,排序结果可能会不正确,而且网格的性能会由于某些不确定因素而严重下降。                                    解决方案是您自己在数据存储层重定义排序函数。下方的  和  演示了怎么做:根据 onHeaderCellMouseDown 函数重写排序逻辑,呈现数据,并更新网格的头部标题视图。                    
清单 13. 重定义排序逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
grid.onHeaderCellMouseDown = function(event){
    var items = DataStore.data.items;
//Sort the "Name" column which might contain characters like Chinese and so on
    if (event.cellIndex == 1) {
        sortAscending = ! sortAscending ;
//Change the string to localestring before comparison with localeCompare method
        if (sortAscending) {
            items.sort(function(m, n){
                return m["name"].toString().
                localeCompare(n["name"].toString());
            });
        }else {
            items.sort(function(m, n){
                return n["name"].toString().
                localeCompare(m["name"].toString());
            });
        }
    }else
    //Sort the "Date" column
    if (event.cellIndex == 2) {
        sortAscending = !sortAscending;
        //Compare the date with milliseconds computed from 1970/07/01
        if (sortAscending) {
            items.sort(function(m, n){
                return  Date.parse(m["date"].toString())
                 - Date.parse(n["date"].toString());
            });
        }else {
            items.sort(function(m, n){
                return Date.parse(n["date"].toString())
                - Date.parse(m["date"].toString());
            });
        }
    }
}




清单 14. 呈现数据,更新网格头部视图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//"sorColIdx" is the index of the column to be sorted
updateGridAfterSort : function(sortColIdx){
    //Render the data of the grid
    var store = new dojo.data.ItemFileWriteStore(DataStore.data);
    grid.setStore(store, null, null);
    grid.update();
    //Update the header view of the gird
    var headerNodeObjs = document.getElementsByTagName("th");
    for (var i = 0; i < 2; ++i) {
//"gridLayout" is a global array defining the layout of the grid
        var headerNodeObjName = gridLayout[0].cells[0].name;
        var headerNodeHtml = ['<div class="dojoxGridSortNode'];
        if (i == sortColIdx){
            headerNodeHtml = headerNodeHtml.concat([' ', (sortAscending ==
             true) ? 'dojoxGridSortUp' : 'dojoxGridSortDown', '"><div
             class="dojoxGridArrowButtonChar">', (sortAscending == true) ?
             '▲' : '▼', '</div ><div class="dojoxGridArrowButtonNode"
              ></div >']);
            headerNodeHtml = headerNodeHtml.concat([headerNodeObjName,
            '</div>']);
            headerNodeObjs.innerHTML = headerNodeHtml.join(" ");
            break;
        }
    }
}




在网格中查找当网格有大量数据时,查找函数将会导致性能低下,尤其是当网格支持实时查找和模糊匹配特性时。解决方案是在它们被转换成数据存储中使用的 JSON 对象前,用额外的存储空间缓存数据;这将避免大量的函数调用,如数据存储的 getItem。 显示了一个样例。                 清单 15. 将从数据库取出的数据缓存到数组中,并查找
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//Fetch data from database
getData : function() {
    function callback(ResultSet) {
//ResultSet is an array of records fetched from database and make variable
//rawData refer to it to cache it in memory  
        GlobalVaribles.rawData = ResultSet;
//Convert the raw data ResultSet to JSON for data store use     
        GlobalVaribles.dataJSON = JSONUtil.convert2JSON(ResultSet);
    }
    DBUtil.fetchAll(callback);
}
//Search functionality
search: function(col, value){
    if (value == null || value == "") {
        return;
    }
//Used here
    var rawData = GlobalVaribles.rawData;
    var newResults = [];
    for (var i = 0; i < rawData.length; i++) {
        var result = rawData;
//Fuzzy match
        if(result[col].toLowerCase().indexOf(value.toLowerCase()) != -1){
            newResults[newResults.length] = result;
        }
    }
//Render the new results
    GridManager.renderNewResults(newResults);
}




延时加载机制Dojo 网格原本就支持延时加载机制,这可以改善性能并提供更好的用户体验。Dojo 网格中的延时加载意味着在数据存储中呈现某些数据,但不是所有网格在您拖动滚动条时再显示其余的数据。                                        默认情况下,网格不会启用延时加载机制;必须显式启动。 演示了用两种方法启动。rowsPerPage 和 keepRows 属性是关键组件。                    
清单 16. 启动演示加载机制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
                //The programmatic way
                var grid = new dojox.grid.DataGrid({
                store: store, //data store
    structure: gridLayout,
    rowsPerPage: 10,  //Render 10 rows every time
    keepRows: 50,       //Keep 50 rows in rendering cache
}, "grid");   
//The declarative way using HTML label
<table
dojoType="dojox.grid.DataGrid"
    id="grid" store="store" structure="gridLayout"
    query="{ id: '*' }"
    rowsPerPage="10" keepRows="50">
    <!--  other definitions  -->
</table>




前置加载机制前置加载机制可提前加载其余的数据,即使用户只是临时使用。对于 Dojo 网格,数据存储中可能有很多的数据;用户可能会拖动滚动条查看其余数据。如果一个页面中有很多数据,看某一特定行就不方便。使用前置机制和分页技术可更方便查看(与 Google 的分页条类似),并获得更好的性能。                                         显示的是分页技术的基本实现。首先,构造一些 JSON 对象,供数据存储用于初始分页条,然后当用户单击分页条的最后一页时添加一些新的 JSON 对象。                    
清单 17. 开始时构建一些 JSON 对象并根据需要切换
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//Fetch data from database and convert them to JSON objects
getData : function() {
    function callback(ResultSet) {
        GlobalVaribles.rawData = ResultSet;
//"convert2JSONs" method convert the raw data to several JSON objects
//stored in Global array "dataJSONs".
        GlobalVaribles.dataJSONs = JSONUtil.convert2JSONs(ResultSet);
    }
    DBUtil.fetchAll(callback);
}
//Initial status
var dataStore = new dojo.data.ItemFileWriteStore({data:GlobalVaribles.dataJSONs[0]});
var grid = new dojox.grid.DataGrid({
    store: dataStore ,
    structure: gridLayout,
}, "grid");
grid.startup();
//Assuming that the user clicks the i-th item in the paging bar, we just update the data  
//store for the grid simply and the performance is still very good.
dataStore = new dojo.data.ItemFileWriteStore({data:GlobalVaribles.dataJSONs[i-1]});
grid.setStore(dataStore, null, null);
grid.update();

返回列表