javascript - Meteor / Blaze: updating list properties with minimal redraw -
i'm encountering serious performance issues related blaze redraw. know data structure @ fault can't find way fix it. bit of long one: i'll best lay out clearly.
the goal / problem
want create schedule view users can schedule tests. users should able drag , drop test slots, resulting redraw slow thing unworkable.
the data
have sittings
collection stores details testing times. each sitting has list of schedulegroups
(i.e. exam1 , exam2 happen on tuesday, exam3 , exam4 happen on wednesday) structure looks more or less this:
var sitting = { "_id" : "sittingid", "name" : "amazing sitting", "locationids" : [ "room1_id", "room2_id" ], "startdate" : isodate("2015-07-01t04:00:00z"), "enddate" : isodate("2015-07-02t04:00:00z"), "schedulegroups" : [ { "_id" : "deb3mc7h8rukagpg3", "name" : "new group", "booths" : [ { "boothnumber" : 1, "slots" : [ { "examid" : "exam1", "daynumber" : 1, "starttime" : { "hour" : 8, "minutes" : 0 }, "endtime" : { "hour" : 9, "minutes" : 30 }, "candidateid" : "odubbd42khdcr8egc", "examinerids" : [ "gqmvyxbcmmckenkmb", "gfoby4beqhfynyowg" ] } ] } ] "locationid" : "room1_id" }], "examids" : [ "exam1", "exam2", "exam3" ]
};
the html
sitting defined global context in router.current().data
hook. part of redraw problem. anyway, following html produces following layout (img below).
<template name='scheduler'> <div class='container'> <div class='tabpanel'> <div class='tab-content' id='scheduler-content'> {{#each getschedulegroups}} <div class='container-fluid schedule-wrapper'> <div class='row'> <div class='scheduler-inner-box placeholder-box'></div> {{#each booths}} <div class='group-column-head scheduler-inner-box'>{{boothnumber}}</div> {{/each}} </div> <!-- sittings can take place on several days, 2 days --> {{#each sittingdays}} <div class='day-wrapper'> <h3 class='text-center'>day {{this}}</h3> <!-- helper returns list of start times: [june 1 9am, june 1 915am....] --> {{#each getscheduletimes ..}} <div class='row time-row'> <div class='group-row-head scheduler-inner-box'> <span class='box-content'>{{this}}</span> </div> <!-- loop through each booth, each slot has square boot i.e. june 1 9am has space booth 1, , booth 2, , booth 3, etc --> {{#each ../../booths}} <!-- paper starting tells if there slot scheduled begin @ time or wher empty--> <div class='scheduler-inner-box {{#unless paperstartingnow ../.. ..}}open-booth{{/unless}}'> {{#with paperstartingnow ../.. .. boothnumber}} <!-- getslotstyle calculates height , colour, depending on how long paper , whether it's ready go: i.e. have candidate , right number of examiners? --> <div class='paper-tile tile' {{getslotstyle ../boothnumber 'paper'}}> <span class='slot-name'>{{getslotname}}</span> </div> {{#if slothascandidate}} <div class='candidate-tile tile' {{getslotstyle ../boothnumber 'candidate'}}> <span class='slot-name candidate-name'>{{getcandidatedisplay}}</span> </div> {{/if}} {{#each slotexaminers}} <div class='examiner-tile tile' {{getslotstyle .. ../../boothnumber 'examiner' index}}> <span class='slot-name examiner-name'>{{profile.name}}</span> </div> {{/each}} {{/with}} </div> {{/each}} </div> {{/each}} </div> {{/each}} </div> {{/each}} </div> </div> </div>
the issue when user drops slot (purple tile) onto empty space, or drags candidate or examiner tile, update collection , let meteor redraw. whole thing redraws , can't find way isolate.
here's code moving whole slot, candidates examiners , all.
moveslot: function (originalboothnumber, originalslot, dropboothnumber, newslot) { check( originalboothnumber, number ); check( originalslot, object ); check( dropboothnumber, number ); check( newslot, object ); //pull old slot var originalbooth = _.findwhere( this.booths, {boothnumber: originalboothnumber} ); originalbooth.slots = _.without( originalbooth.slots, originalslot ); //insert new 1 var dropbooth = _.findwhere( this.booths, {boothnumber: dropboothnumber} ); dropbooth.slots.push( newslot ); var modifier = { $set: {} }; modifier["$set"]["schedulegroups." + this.getindex() + ".booths"] = this.booths; return sittings.update({_id: this.getsitting()._id }, modifier); },
do need change way store sitting.booths
? if can recommend better data structure trigger redraw of slot, i'd appreciate it. i've found hack puts every slot session variable there's got way.
thanks patience , help, db
problem
it's because store whole set of slots
inside 1 document of booth
. once update slot
, whole document consider updated.
solutions
imho, don't think need change structure, unless have build feature search slot
or booth
. can set create series of reactivevariable
or reactivedictionary
, template should depends on reactive variable. every time updated, consider sync between 2 of them, either manually or automatically.
ps. i'm not doing affiliate site: https://www.sportsplus.me. if sign -> home -> mlb -> anycontest -> click on plus, can see masterpiece infinite scroll partly redraw. (open dev-console , watch changes in element). same thing you're trying minimum redraw.
Comments
Post a Comment