0

I'm getting JSON data from the API, like this

data = {
  q: 'sugar',
  from: 0,
  to: 10,
  params: {
    sane: [],
    q: [ 'sugar' ]
  },
  more: true,
  count: 1000,
  hits: [{
    recipe: {
      uri: 'http://www.edamam.com/ontologies/edamam.owl#recipe_a46ae0ad4f8320fa6285b25fc7b36432',
      label: 'Bread Pudding with Apple and Brown Sugared Bacon',
      image: 'https://www.edamam.com/web-img/1ae/1ae111af3737d42e9d743445f5605373.JPG   '
    }, 
    recipe: {
      uri: 'http://www.edamam.com/ontologies/edamam.owl#recipe_a36b51f50f102bf5da228af55d2ce040',
      label: 'Vanilla sugar',
      image: 'https://www.edamam.com/web-img/4fd/4fdd2336043aa81dd05a4b6a08934402.jpg',     
    }
  }]
}

And I try to bind the recipe to divs. For example, there is a div with the id columns, Here is that piece of codes.

var list = data.hits;
function Builddivs(list) {
  var array = new Array(0);
  var count = list.length;
  for (var i = 0; i < 10; i++) {
    var p = list[i];
    title = p.recipe.label;
    imgurl = p.recipe.image;
    href = p.recipe.url;
    array.push("<div class='pin'><a href='" + href + "'><img src='" + imgurl + "'/></a><p>" + title + "</p> </div>");
  }

  var html = array.join("");
  $("#columns").html(html);
}

The problem is to generate that html takes like several seconds, so is there a better way to do that? like bind the data directly to existing dynamic number of divs? Thanks!

Cohars
  • 3,822
  • 1
  • 29
  • 50
Wilheim
  • 123
  • 3
  • 13
  • How does that take "like several seconds" ? Did you really measure ? How many items do you have ? Is the time really spent in the HTML generation (vs the redrawing related to all those unsized images) ? – Denys Séguret Sep 15 '16 at 11:29
  • @DenysSéguret I guess OP means that API takes few seconds and so HTML generation is taking time. – Rajesh Sep 15 '16 at 11:45
  • OP Is the question about how to include JSON directly in the HTML file ? Or what ? – Denys Séguret Sep 15 '16 at 11:46
  • He Is asking that,he can improve the code or it is the best to append HTML like that. – Anil Talla Sep 15 '16 at 11:48
  • @Rajesh what I mean is appending the HTML to a div takes more time than to directly changing individual element. But when I have unfixed array of data, then the number of existing html element won't fit with the length of the array. – Wilheim Sep 15 '16 at 12:25
  • @WilheimYou can look at [this](https://jsfiddle.net/RajeshDixit/L0zfr91j/) for reference. You can monitor how much time it takes to actually perform operation – Rajesh Sep 15 '16 at 12:47

2 Answers2

0

Instead of generating a lot of HTML at once, it would be more efficient to edit existing HTML.

Example jsfiddle solution to this question

Editing HTML with jQuery

You can replace or add text or HTML to a div:

$(selector).html('Try <span class="red">this!</span>');
$(selector).text('Just add some text');
$(selector).append('Some HTML');

Adding src to an image or adding href to a link:

$(selector).attr('src','http://example.com/someimage.jpg');
$(selector).attr('href','http://example.com');

Instead of using a for loop, you could use javascript Array.forEach or jquery $.each

Generating HTML for the first time

On every run (every time the list changes) you can check if the HTML element to be edited exists. If not, then you can generate the appropriate HTML. On the first run of the code, the HTML would then be generated for every element from the list. See this question to see how to check if elements exist: How do you check if a selector matches something in jQuery?

Example

Here is a working jsfiddle with an example of how HTML can be edited using $().attr and $().html: https://jsfiddle.net/fyux250p/1/

Community
  • 1
  • 1
-1
 var hitsContent =""
 (list || []).forEach(function(data,index){
    hitsContent += "<div class='pin'><a href='" + data.url + "'><img src='" + data.url + "'/></a><p>" + data.label + "</p> </div>";
 })
 $("#columns").html(hitsContent);
Anil Talla
  • 709
  • 5
  • 19
  • array.push and array.join it will reduce – Anil Talla Sep 15 '16 at 11:41
  • @AnilTalla nothing beats `for`. If you wish to do that, directly concatenate string in `for`. Still this is an optimization and not solution. – Rajesh Sep 15 '16 at 11:49
  • 1
    I just tried for removing array.push and array.join and variables. – Anil Talla Sep 15 '16 at 11:51
  • The best and quickest way to insert huge amount of nodes is to create the content and insert it in one step. This answer is best solution, because there is **no better way to do it**. In this answer he also excluded array manipulations and left only the necessary code - therefore, upvote please. If you wanna play, than go on and beat [this score](https://jsfiddle.net/e5cufnLo/), Firefox ~ 200ms, Chrome < 100ms for 1000 of records. – skobaljic Sep 15 '16 at 12:17
  • In your Fiddle no html is appended and what you tried to do is same as I said and what [Anil Talla](http://stackoverflow.com/users/4478904/anil-talla) did. Faster is not always better. If you think you can do better than jQuery guys, than you should tell them. – skobaljic Sep 15 '16 at 12:53
  • @skobaljic apologies. Provided wrong link. [Updated Link](https://jsfiddle.net/RajeshDixit/gtd2q1ce/). Also apart from performance, its more scalable and easier for anyone to understand. But, better is a relative term and will vary from person to person. But in my understanding, you should try to adapt to functional approach. – Rajesh Sep 15 '16 at 13:09