2012-01-04 16 views
8

में जोड़ें। मेरे पास सर्वर से एक JSON सरणी आ रही है जिसमें 200 ऑब्जेक्ट्स की एक सरणी है जिसमें प्रत्येक 10 ऑब्जेक्ट्स हैं जिन्हें मैं एक टेबल प्रारूप में प्रदर्शित करना चाहता हूं। सबसे पहले मैं प्रत्येक पुनरावृत्ति के लिए <tr> बना रहा था और सरणी मानों से <tr> पर निर्मित <td> संलग्न करने के लिए jQuery का उपयोग कर रहा था। यह क्रोम में लगभग 30 सेकंड और आईई 8 में 1 9 सेकेंड ले रहा था। यह बहुत लंबा समय ले रहा था इसलिए मैंने Array.join() विधि पर स्विच करने का प्रयास किया, जहां मैं प्रत्येक स्ट्रिंग को स्टोर करता हूं जो पूरे टेबल को सरणी में बना देगा, और अंत में $('#myTable').append(textToAppend) करें। यह वास्तव में लगभग 5 सेकंड तक मेरे पहले संस्करण से भी बदतर प्रदर्शन किया।जावास्क्रिप्ट प्रभावी रूप से जेएसओएन से टेबल बनाएं और इसे डीओएम

मैं इसे लगभग 10 सेकंड तक प्राप्त करना चाहता हूं। क्या मुझे उस पर कोई मौका है? यदि नहीं, तो मैं एक समय में एक पंक्ति जोड़ रहा हूं, लेकिन मैं ऐसा नहीं करूँगा।

for(allIndex = 0; allIndex < entries.alumnus.length; allIndex++){ 

    var entry = '<tr id="entry' + allIndex + '" class="entry"></tr>'; 
    $('#content_table').append(entry); 

    $('#entry' + allIndex).append(($.trim(entries.alumnus[allIndex].title) != '' ? 
     '<td id="title' + allIndex + '" class="cell"><span class="content">' + 
     entries.alumnus[allIndex].title + '</span></td>' : '<td width="5%">' + 
     filler + '</td>'));  
    . 
    . 
    . 
    .//REST OF ELEMENTS 
    . 
    . 
    . 
} 

अद्यतन: मैं कल कुछ, jQuery का उपयोग किए बिना गड़बड़ होना चाहिए क्योंकि मैं डोम से बाहर जोड़कर तत्वों की कोशिश कर रहा है और फिर उन्हें बाद में संलग्न करने के लिए वापस चला गया, और मैं 85 के लिए नीचे अपने समय मिल गया है क्रोम में एमएस और आईई 7 में 450 एमएस !!! तुम लड़के गजब हो!!! मैंने उपयोगकर्ता 1 को जवाब दिया क्योंकि वह अधिक व्यापक था, और टुकड़ों का उपयोग करने से वास्तव में क्रोम में मेरे समय में काफी बदलाव नहीं आया और आईई 7 में लगभग 20ms जोड़ा गया। लेकिन मैं अभी भी @Emre Erkan के उत्तर की सराहना करता हूं, और अधिक बार उपयोग करता हूं :)

+0

क्या आपका मतलब है कि आपके पास 200 तत्वों के साथ एक JSON सरणी है, जिनमें से प्रत्येक 10 तत्वों की सरणी है? –

+0

हाँ, गलती से मेरी शब्दावली मिश्रित :) – Eliezer

+0

क्या आप हमें अपना कोड दिखा सकते हैं? –

उत्तर

13

सबसे तेजी से कुछ इस तरह दिखेगा:

var oldTable = document.getElementById('example'), 
    newTable = oldTable.cloneNode(true); 
for(var i = 0; i < json_example.length; i++){ 
    var tr = document.createElement('tr'); 
    for(var j = 0; j < json_example[i].length; j++){ 
     var td = document.createElement('td'); 
     td.appendChild(document.createTextNode(json_example[i][j])); 
     tr.appendChild(td); 
    } 
    newTable.appendChild(tr); 
} 

oldTable.parentNode.replaceChild(newTable, oldTable); 

और मिलीसेकेंड में चलाने चाहिए। यहां एक उदाहरण दिया गया है: http://jsfiddle.net/Paulpro/YhQEC/ यह 200 टेबल पंक्तियां बनाता है जिनमें प्रत्येक 10 टीडी है।

आप स्ट्रिंग्स नहीं, तत्वों का उपयोग करके जोड़ना चाहते हैं, लेकिन जब तक आप पूरी संरचना (आपके लूप में रिफ्लो से बचने के लिए) नहीं कर लेते हैं, तब तक आप डोम को कुछ भी जोड़ना नहीं चाहते हैं। तो आप मूल तालिका को क्लोन कर सकते हैं और क्लोन में जोड़ सकते हैं, फिर अपने लूप को पूरा करने के बाद क्लोन डालें।

आप jQuery से बचकर और सीधे डीओएम के साथ बातचीत करके गति का एक उचित हिस्सा प्राप्त करेंगे।

आपका कोड देखने की तरह हो सकता है:

var oldTable = document.getElementById('content_table'), 
    newTable = oldTable.cloneNode(true), 
    tr, td; 
for(var i = 0; i < entries.alumnus.length.length; i++){ 
    tr = document.createElement('tr'); 
    tr.id = 'entry' + i; 
    tr.className = 'entry'; 

    if(entries.alumnus[i].title){ 
     td = document.createElement('td'); 
     td.id = 'title' + i; 
     td.className = 'cell'; 
     var span = document.createElement('span'); 
     span.className = 'content'; 
     span.appendChild(document.createTextNode(entries.alumnus[i].title); 
     td.appendChild(span); 
     tr.appendChild(td); 
     tr.appendChild(createFiller(filler)); 
    } 

    // REST OF ELEMENTS 

    newTable.appendChild(tr); 

} 

oldTable.parentNode.replaceChild(newTable, oldTable); 

function createFiller(filler){ 
    var td = document.createElement('td'); 
    td.style.width = '5%'; 
    td.appendChild(document.createTextNode(filler); 
    return td; 
} 
+0

एक टाइमर शामिल करने के लिए संपादित: http://jsfiddle.net/Paulpro/tPrcK/ मेरे लैपटॉप पर क्रोम संस्करण 16 में लगभग 15-25 मिलीसेकंड लेता है। उस समय – Paulpro

+0

8 एमएस। – Paulpro

+0

उनको ठीक करने के लिए धन्यवाद, एमरे! – Paulpro

0

यह निश्चित रूप से सक्षम है। मुझे नहीं लगता कि स्ट्रिंग कॉन्सटेनेशन जाने का रास्ता है। आम तौर पर यह तत्व बनाने के लिए तेज़ी से प्रतीत होता है और जब वे मुख्य डोम से जुड़े नहीं होते हैं तो उन्हें कुशल बनाते हैं; इसलिए पूरे तालिका पहले तो बनाने में जोड़ें। सादा जावास्क्रिप्ट में मुझे लगता है कि नीचे कोड मूल रूप से है कि आप क्या हासिल करना चाहते हैं ..

//mock up the data (this will come from you AJAX call).. 
    var data = []; 
    for(var i = 0; i < 200; i++){ 
     var rowData = []; 
     for(var j = 0; j < 10; j++){ 
      rowData.push("This is a string value"); 
     } 
     data.push(rowData); 
    } 

    //create table.. 
    var table = document.createElement("table"); 
    for(var i = 0; i < data.length; i++){ 
     var rowData = data[i]; 
     var row = document.createElement("tr"); 
     for(var j = 0; j < rowData.length; j++){ 
      var cell = document.createElement("td"); 
      cell.innerHTML = rowData[j]; 
      row.appendChild(cell); 
     } 
     table.appendChild(row); 
    } 
    //finally append the whole thing.. 
    document.body.appendChild(table); 

जब मैं सफारी में कंसोल में इस छड़ी, यह < 1 में चलता है दूसरा तो आपको ठीक होना चाहिए।

+0

-1 'आंतरिक HTML' के लिए –

+0

@EmreErkan - 'innerHTML' के साथ ___nothing___ गलत नहीं है, हालांकि इस उदाहरण में जिस तरह से किया गया है :) –

+0

' आंतरिक HTML' [बुरा] है (http: // erik.eae.net/archives/2005/04/08/18.13.31/) –

5

सबसे महत्वपूर्ण बात यह है कि डोम से पूरी तालिका सामग्री बनाना और फिर तालिका में डालना है। क्रोम में यह एक समाप्त होता है के बारे में 3 5ms करने के बाद:

function createTableFromData(data) { 
    var tableHtml = ''; 
    var currentRowHtml; 
    for (var i = 0, length = data.length; i < length; i++) { 
     currentRowHtml = '<tr><td>' + data[i].join('</td><td>') + '</td></tr>'; 
     tableHtml += currentRowHtml;   
    } 
    return tableHtml;  
} 

var textToAppend= createTableFromData(yourData); 
$('#myTable').append(textToAppend); 
+1

उप-मतदान क्योंकि यह अब तक का सबसे अच्छा प्रदर्शन करने वाला समाधान होने जा रहा है। चूंकि ओपी व्यक्तिगत पंक्तियों के साथ कुछ भी नहीं कर रहा है (उदाहरण के लिए ईवेंट श्रोताओं को जोड़ना), 'आंतरिक HTML' ___always___ प्रति डोम से अधिक तेज़ हो जाएगा। यद्यपि आपका 'currentRowHtml' var कुछ चीजों को धीमा करने जा रहा है। –

+0

मैं वास्तव में श्रोताओं को जोड़ रहा हूं। मैंने अभी उन तत्वों का उपयोग नहीं किया जो मैं उपरोक्त मेरे उदाहरण में करता हूं। – Eliezer

+1

@ एलीज़र घटना प्रतिनिधिमंडल का उपयोग करें। – c69

9

मैं तुम्हें सुझाव है DocumentFragment उपयोग करने के लिए और बड़े पैमाने डोम हेरफेर के इस प्रकार के लिए देशी जावास्क्रिप्ट का उपयोग करें। मैंने एक उदाहरण तैयार किया है, आप इसे here देख सकते हैं।

var fragment = document.createDocumentFragment(), 
    tr, td, i, il, key; 
for(i=0,il=data.length;i<il;i++) { 
    tr = document.createElement('tr'); 
    for(key in data[i]) { 
     td = document.createElement('td'); 
     td.appendChild(document.createTextNode(data[i][key])); 
     tr.appendChild(td); 
    } 
    fragment.appendChild(tr); 
} 
$('#mytable tbody').append(fragment); 

मुझे लगता है कि यह ऐसा काम करने का सबसे तेज़ तरीका है।

+0

क्या jQuery पर सीधे जावास्क्रिप्ट का उपयोग करने के साथ संघर्ष करने के लिए क्रॉस-ब्राउज़र समस्याएं हैं? – krillgar

+1

कोई भी जो मुझे पता है। लेकिन अगर आप इसे सही इस्तेमाल करते हैं, तो मूल जावास्क्रिप्ट तेज़ी से काम करेगा, jQuery, क्या आपको नहीं लगता? –

+0

ओह, मैं jQuery की तुलना में जावास्क्रिप्ट तेज होने के बारे में बहस नहीं कर रहा हूं। मैंने क्रोम, फ़ायरफ़ॉक्स और विशेष रूप से आईई 8 के बीच कई मुद्दों पर भाग लिया है कि अधिकांश भाग के लिए मुझे jQuery के साथ रहना पसंद है क्योंकि यह सब उस परीक्षण को हटाने के लिए परीक्षण किया जाता है जो दर्द हो सकता है। लेकिन यह शुद्ध जावास्क्रिप्ट कितना आसान है (इसके साथ लुभावनी रूप से फैंसी करने की कोशिश नहीं कर रहा है), मैं इसे पूरे दिन ऐसा करना चाहता हूं। – krillgar

1

यदि आपके पास सर्वर से JSON की एक मान्य स्ट्रिंग है और संरचना विश्वसनीय रूप से तारों के सरणी की सरणी है, तो नीचे आपको JSON पार्स से बचने की अनुमति मिलेगी, और इसके बजाय HTML पीढ़ी को नियमित रूप से निरंतर श्रृंखला के साथ प्रतिस्थापित कर दिया जाएगा अभिव्यक्ति संचालन जो देशी कोड में लागू किया जाता है जो देशी बफर का उपयोग करता है। यह एक पार्स को पूरी तरह से टालना चाहिए और निरंतर के लिए के, ओ (एन) बफर प्रतियों के साथ ओ (एन ** 2) की लागत वाले किसी भी बफर प्रतियों को प्रतिस्थापित करना चाहिए।

var jsonContent 
    = ' [ [ "foo", "bar", "[baz\\"boo\\n]" ], ["1","2" , "3"] ] '; 

var repls = { // Equivalent inside a JSON string. 
    ',': "\\u002b", 
    '[': "\\u005b", 
    ']': "\\u005d" 
}; 
var inStr = false; // True if the char matched below is in a string. 
// Make sure that all '[', ']', and ',' chars in JSON content are 
// actual JSON punctuation by re-encoding those that appear in strings. 
jsonContent = jsonContent.replace(/[\",\[\]]|\\./g, function (m) { 
    if (m.length === 1) { 
    if (m === '"') { 
     inStr = !inStr; 
    } else if (inStr) { 
     return repls[m]; 
    } 
    } 
    return m; 
}); 

// Prevent XSS. 
jsonContent = jsonContent.replace(/&/g, "&amp;") 
    .replace(/</g, "&lt;"); 
// Assumes that the JSON generator does not encode '<' as '\u003c'. 

// Remove all string delimiters and space outside of strings. 
var html = jsonContent 
    .replace(/\"\s*([,\]])\s*\"?|\s*([\[,])\s*\"/g, "$1$2"); 
// Introduce the table header and footer. 
html = html.replace(/^\s*\[/g, "<table>") 
html = html.replace(/]\s*$/g, "</table>") 
// Introduce row boundaries. 
html = html.replace(/\],?/g, "</tr>") 
html = html.replace(/\[/g, "<tr><td>") 
// Introduce cell boundaries. 
html = html.replace(/,/g, "<td>") 

// Decode escape sequences. 
var jsEscs = { 
    '\\n': '\n', 
    '\\f': '\f', 
    '\\r': '\r', 
    '\\t': '\t', 
    '\\v': '\x0c', 
    '\\b': '\b' 
}; 
html = html.replace(/\\(?:[^u]|u[0-9A-Fa-f]{4})/g, function (m) { 
     if (m.length == 2) { 
     // Second branch handles '\\"' -> '"' 
     return jsEscs[m] || m.substring(1); 
     } 
     return String.fromCharCode(parseInt(m.substring(2), 16)); 
    }); 

// Copy and paste with the below to see the literal content and the table. 
var pre = document.createElement('pre'); 
pre.appendChild(document.createTextNode(html)); 
document.body.appendChild(pre); 
var div = document.createElement('div'); 
div.innerHTML = html; 
document.body.appendChild(div);