Hello,
I have made a discovery and I thought I share it here to eventually get feedbacks.
In our application we manage a very long list of customer orders and each customer orders have a long list of lines.
When a user load the page, it used to trigger 1 subscribe and 1 method call for each sub templates and if we have 1000 orders, it is a lot of load on our server.
I have implemented the Intersection Observer API (Intersection Observer API - Web APIs | MDN) and it seems very promising for my use case.
It looks like this :
template.html
<template name="customerOrders">
{{#each customerOrderId in customerOrderIds}}
{{>customerOrder customerOrderId=customerOrderId}}
{{/each}}
</template>
<template name="customerOrder">
<div id="customerOrderDiv-{{customerOrderId}}">
{{customerOrder.num}}
{{#each line in lines}}
{{>customerOrderLine line=line}}
{{/each}}
</div>
</template>
template.js
Template.customerOrder.onCreated(function() {
this.lines = new ReactiveVar(false);
});
Template.customerOrder.onRendered(function() {
const instance = this;
const element = document.querySelector('#customerOrderDiv-' + this.data.coId);
const observer = new IntersectionObserver(function(entries, observer) {
entries.forEach(entry => {
if (entry.isIntersecting) {
observer.unobserve(element);
instance.subscribe('customer-order', instance.data.customerOrderId);
Meteor.call('customer-order/lines', instance.data.customerOrderId, function(err, res) {
if (err) {
console.error(err);
return;
}
instance.lines.set(res);
});
}
});
}, {root: null, rootMargin: '0px', threshold: 0.05});
observer.observe(element);
});
Template.customerOrder.helpers({
customerOrder: function() {
return CustomerOrders.findOne(this.customerOrderId);
},
lines: function() {
return Template.instance().lines.get();
},
});
How it work ?
When the page is displayed, only the firsts visible elements trigger the subscribe and call. As soon as the calls are triggered we can unobserve the observer (to avoid double calls)
When the user scroll down the page, we progressively subscribe and call methods.
I like the approach and will test in production.
Do you see improvements or drawbacks ?
Thanks