From 444fb9ecacf8391887f246d2fa2d2126d775713d Mon Sep 17 00:00:00 2001 From: TheGoddessInari Date: Sat, 4 Aug 2018 03:56:51 -0700 Subject: [PATCH] Save lots of CPU usage by default. We now default to passive event listeners on all services, as well as 100ms minimum granularity on setTimeout. This is because many of the web-wrapped services constantly fire totally unnecessary repaint events as fast as they can, as well as actively listening for mouse events which also cause unnecessary reflow. On my machine, this cuts the CPU usage by ~70% while not affecting the usability of any services. There's a user-toggle available there. There's not a per-service option for the ServiceList because it shouldn't affect anything except in truly abnormal cases. If there needs to be one, we can add it. --- app/model/Service.js | 8 ++++++++ app/store/Services.js | 2 ++ app/ux/WebView.js | 15 +++++++++++++++ app/view/add/Add.js | 18 +++++++++++++++++- app/view/add/AddController.js | 4 ++++ app/view/main/MainController.js | 2 ++ 6 files changed, 48 insertions(+), 1 deletion(-) diff --git a/app/model/Service.js b/app/model/Service.js index 8a08e427..a381c5b3 100644 --- a/app/model/Service.js +++ b/app/model/Service.js @@ -73,6 +73,14 @@ Ext.define('Rambox.model.Service', { name: 'custom_css_complex' ,type: 'boolean' ,defaultValue: false + },{ + name: 'passive_event_listeners' + ,type: 'boolean' + ,defaultValue: true + },{ + name: 'slowed_timers' + ,type: 'boolean' + ,defaultValue: true },{ name: 'zoomLevel' ,type: 'number' diff --git a/app/store/Services.js b/app/store/Services.js index ae5872a8..1905943b 100644 --- a/app/store/Services.js +++ b/app/store/Services.js @@ -40,6 +40,8 @@ Ext.define('Rambox.store.Services', { ,includeInGlobalUnreadCounter: service.get('includeInGlobalUnreadCounter') ,displayTabUnreadCounter: service.get('displayTabUnreadCounter') ,custom_css_complex: service.get('custom_css_complex') + ,passive_event_listeners: service.get('passive_event_listeners') + ,slowed_timers: service.get('slowed_timers') ,enabled: service.get('enabled') ,record: service ,tabConfig: { diff --git a/app/ux/WebView.js b/app/ux/WebView.js index 0ef54f4a..842f7356 100644 --- a/app/ux/WebView.js +++ b/app/ux/WebView.js @@ -459,6 +459,21 @@ Ext.define('Rambox.ux.WebView',{ js_inject += js_preventBlink; } + // Use passive listeners by default + if (me.record.get('passive_event_listeners')) + { + // 3rdparty: This uses npm 'default-passive-events' 1.0.10 inline. Link to license: + // https://github.com/zzarcon/default-passive-events/blob/master/LICENSE + const passive_event_listeners = `const eventListenerOptionsSupported=()=>{let supported=!1;try{const opts=Object.defineProperty({},"passive",{get(){supported=!0}});window.addEventListener("test",null,opts),window.removeEventListener("test",null,opts)}catch(e){}return supported},defaultOptions={passive:!0,capture:!1},supportedPassiveTypes=["scroll","wheel","touchstart","touchmove","touchenter","touchend","touchleave","mouseout","mouseleave","mouseup","mousedown","mousemove","mouseenter","mousewheel","mouseover"],getDefaultPassiveOption=(passive,eventName)=>void 0!==passive?passive:-1!==supportedPassiveTypes.indexOf(eventName)&&defaultOptions.passive,getWritableOptions=options=>{const passiveDescriptor=Object.getOwnPropertyDescriptor(options,"passive");return passiveDescriptor&&!0!==passiveDescriptor.writable&&void 0===passiveDescriptor.set?Object.assign({},options):options},overwriteAddEvent=superMethod=>{EventTarget.prototype.addEventListener=function(type,listener,options){const usesListenerOptions="object"==typeof options&&null!==options,useCapture=usesListenerOptions?options.capture:options;(options=usesListenerOptions?getWritableOptions(options):{}).passive=getDefaultPassiveOption(options.passive,type),options.capture=void 0===useCapture?defaultOptions.capture:useCapture,superMethod.call(this,type,listener,options)},EventTarget.prototype.addEventListener._original=superMethod},supportsPassive=eventListenerOptionsSupported();if(supportsPassive){const addEvent=EventTarget.prototype.addEventListener;overwriteAddEvent(addEvent)}`; + js_inject += '{' + passive_event_listeners + '}'; + } + + // Use slowed timers by default + if (me.record.get('slowed_timers')) + { + const slowed_timers = `window.setTimeout=window.setTimeout;const __setTimeout=window.setTimeout;window.setTimeout=function(func,time){let a=time;return a<100&&(a=100),__setTimeout(func,a)};`; + js_inject += '{' + slowed_timers + '}'; + } // Scroll always to top (bug) js_inject += 'document.body.scrollTop=0;'; diff --git a/app/view/add/Add.js b/app/view/add/Add.js index 8d7ecd43..dda3c3d1 100644 --- a/app/view/add/Add.js +++ b/app/view/add/Add.js @@ -19,7 +19,7 @@ Ext.define('Rambox.view.add.Add',{ // defaults ,modal: true ,width: 500 - ,height: 700 + ,height: 750 ,autoShow: true ,resizable: false ,draggable: false @@ -191,6 +191,22 @@ Ext.define('Rambox.view.add.Add',{ ,uncheckedValue: false ,inputValue: true } + ,{ + xtype: 'checkbox' + ,boxLabel: "Use passive listeners" + ,name: 'passive_event_listeners' + ,checked: me.edit ? me.record.get('passive_event_listeners') : true + ,uncheckedValue: false + ,inputValue: true + } + ,{ + xtype: 'checkbox' + ,boxLabel: "100ms timer granularity" + ,name: 'slowed_timers' + ,checked: me.edit ? me.record.get('slowed_timers') : true + ,uncheckedValue: false + ,inputValue: true + } ,{ xtype: 'checkbox' ,boxLabel: locale['app.window[19]'] diff --git a/app/view/add/AddController.js b/app/view/add/AddController.js index 15c1afe2..2198cb0a 100644 --- a/app/view/add/AddController.js +++ b/app/view/add/AddController.js @@ -42,6 +42,8 @@ Ext.define('Rambox.view.add.AddController', { ,custom_js: formValues.custom_js ,custom_css: formValues.custom_css ,custom_css_complex: formValues.custom_css_complex + ,passive_event_listeners: formValues.passive_event_listeners + ,slowed_timers: formValues.slowed_timers }); var view = Ext.getCmp('tab_'+win.record.get('id')); @@ -97,6 +99,8 @@ Ext.define('Rambox.view.add.AddController', { ,custom_js: formValues.custom_js ,custom_css: formValues.custom_css ,custom_css_complex: formValues.custom_css_complex + ,passive_event_listeners: formValues.passive_event_listeners + ,slowed_timers: formValues.slowed_timers }); service.save(); Ext.getStore('Services').add(service); diff --git a/app/view/main/MainController.js b/app/view/main/MainController.js index 7eb5d5ce..d55acba8 100644 --- a/app/view/main/MainController.js +++ b/app/view/main/MainController.js @@ -107,6 +107,8 @@ Ext.define('Rambox.view.main.MainController', { ,includeInGlobalUnreadCounter: rec.get('includeInGlobalUnreadCounter') ,displayTabUnreadCounter: rec.get('displayTabUnreadCounter') ,custom_css_complex: rec.get('custom_css_complex') + ,passive_event_listeners: rec.get('passive_event_listeners') + ,slowed_timers: rec.get('slowed_timers') ,enabled: rec.get('enabled') ,record: rec ,hidden: hideTab