-
Notifications
You must be signed in to change notification settings - Fork 156
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve performance by reducing number of inputs from / outputs to localStorage #105
Comments
I love it. I think, though, that can't be the default. I'd love to see this in an Ember.js app: DS.LSAdapter.reopen({
enableFastPersistence: true
}); and then, the code would be routed inside of the adapter to use the one you have above. Also, it should not be inside of the adapter; it should be its own object to keep things sane and clean. What do you think? |
Sound reasonable, as long as users of the LSAdapter are aware that using default settings will very probably slow down their ember app a lot. |
We can add it to the README. Not losing data is more important than speed. Em qua, 25 de mar de 2015 às 13:33, Leooo [email protected]
|
|
Update on this, as I think this is a huge problem with the localstorage adapter to push /pull to the localstorage for every request (see performance times above). I now use a I'm not good with pull requests, but the code itself is quite short, I hope I'm adding everything this is as below: DS.LSAdapter.reopen({
_storage: null,//where the copy of the data of localStorage will be stored
useSnapshot: true,//set to false if ever anyone would like to come back to previous behavior
timeOutSnapshot: 200,//play with the parameter, shorter time = performance decreased, higher value=risk of losing data when reloading the page
_hasChanged: false,//flag to detect pushed data,
loadData: function () {
var storage,arr,arr_cp;
if (!this._storage||!this.useSnapshot) {
storage = this.getLocalStorage().getItem(this.adapterNamespace());
arr = storage ? JSON.parse(storage) : {};
if (this.useSnapshot) {
this._storage=arr;
}
}
else {
arr=this._storage;
}
var cp=Ember.copy(arr,true);
return cp;
},
timerPushLocalStorage: null,
_launchPushLocalStorage: function() {
if (this.get('_hasChanged')) {
Ember.run.debounce(this,'_pushLocalStorage',this.timeoutSnapshot);
}
}.observes('_hasChanged'),
_pushLocalStorage: function() {
if (!this.useSnapshot || !this._storage) {return false;}
if (this.get('_hasChanged')) {
this.getLocalStorage().setItem(this.adapterNamespace(), JSON.stringify(this._storage));
this.set('_hasChanged',false);
}
},
persistData: function(modelClass, data) {
var modelNamespace = this.modelNamespace(modelClass);
if (this.useSnapshot) {
if (!this._storage) {this._storage=this.loadData();}
this._storage[modelNamespace] = Ember.copy(data);
this.set('_hasChanged',true);
}
else {
var localStorageData = this.loadData();
localStorageData[modelNamespace] = data;
this.getLocalStorage().setItem(this.adapterNamespace(), JSON.stringify(localStorageData));
}
}, |
@Leooo the code is a very good start. No one starts good at anything. Give a try in the PR and we can guide you through the process. No one best than you to push forward this nice solution. |
Done, but my version of the adapter diverged too much to be able to merge it: I pulled the last LS adapter version and added changes which I think should be self-contained. |
Hello,
As of now the performance of the LSAdapter seems not great, due to the fact that each record fetched from / saved to the store is a direct copy of the one in localStorage.
Indeed the whole store-hash has to be loaded / saved to the localStorage everytime (and due to the namespace parameter one can not benefit from the localStorage.getItem / setItem methods). And as the localStorage operations are synchronous, this freezes the screen of the users.
One solution for at least some people, and probably any big application using LSAdapter would be to fetch the localStorage hash on initialization, and work on a javascript object copy of this hash, updating it for each request and storing it only at determined intervals. We would admittedly lose some information if the page is reloaded before saving the last copy, but providing the users with a method to force the update of the localStorage when needed would solve this problem.
Below is an implementation of such a method.
Benchmarking on a couple hundred objects + relationships fetched from the server using SSE:
So the performance seems to be improved by a factor of 30.
EDIT2 Added Ember.copy(x,true) as default implementation of Ember.copy doesn't deep-copy hashes!.
The text was updated successfully, but these errors were encountered: