Bug 1305161 - New console frontend: Improve performance of showing cached messages. r=bgrins

MozReview-Commit-ID: 8NIDqj5nRol
This commit is contained in:
Lin Clark 2016-09-27 10:09:51 -07:00
Родитель 700269e5cd
Коммит 0a27dfb295
19 изменённых файлов: 130 добавлений и 48 удалений

Просмотреть файл

@ -0,0 +1,20 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { BATCH_ACTIONS } = require("../constants");
function batchActions(batchedActions) {
return {
type: BATCH_ACTIONS,
actions: batchedActions,
};
}
module.exports = {
batchActions
};

Просмотреть файл

@ -0,0 +1,18 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const actionModules = [
"enhancers",
"filters",
"messages",
"ui",
].map(filename => require(`./${filename}`));
const actions = Object.assign({}, ...actionModules);
module.exports = actions;

Просмотреть файл

@ -10,7 +10,7 @@ const {
prepareMessage
} = require("devtools/client/webconsole/new-console-output/utils/messages");
const { IdGenerator } = require("devtools/client/webconsole/new-console-output/utils/id-generator");
const { batchActions } = require("devtools/client/webconsole/new-console-output/actions/enhancers");
const {
MESSAGE_ADD,
MESSAGES_CLEAR,
@ -22,21 +22,22 @@ const {
const defaultIdGenerator = new IdGenerator();
function messageAdd(packet, idGenerator = null) {
return (dispatch) => {
if (idGenerator == null) {
idGenerator = defaultIdGenerator;
}
let message = prepareMessage(packet, idGenerator);
if (message.type === MESSAGE_TYPE.CLEAR) {
dispatch(messagesClear());
}
dispatch({
type: MESSAGE_ADD,
message
});
if (idGenerator == null) {
idGenerator = defaultIdGenerator;
}
let message = prepareMessage(packet, idGenerator);
const addMessageAction = {
type: MESSAGE_ADD,
message
};
if (message.type === MESSAGE_TYPE.CLEAR) {
return batchActions([
messagesClear(),
addMessageAction,
]);
}
return addMessageAction;
}
function messagesClear() {
@ -59,7 +60,9 @@ function messageClose(id) {
};
}
exports.messageAdd = messageAdd;
exports.messagesClear = messagesClear;
exports.messageOpen = messageOpen;
exports.messageClose = messageClose;
module.exports = {
messageAdd,
messagesClear,
messageOpen,
messageClose,
};

Просмотреть файл

@ -4,7 +4,9 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'enhancers.js',
'filters.js',
'index.js',
'messages.js',
'ui.js',
)

Просмотреть файл

@ -12,9 +12,9 @@ const {
const { connect } = require("devtools/client/shared/vendor/react-redux");
const { getAllFilters } = require("devtools/client/webconsole/new-console-output/selectors/filters");
const { getAllUi } = require("devtools/client/webconsole/new-console-output/selectors/ui");
const { filterTextSet, filtersClear } = require("devtools/client/webconsole/new-console-output/actions/filters");
const { messagesClear } = require("devtools/client/webconsole/new-console-output/actions/messages");
const uiActions = require("devtools/client/webconsole/new-console-output/actions/ui");
const { filterTextSet, filtersClear } = require("devtools/client/webconsole/new-console-output/actions/index");
const { messagesClear } = require("devtools/client/webconsole/new-console-output/actions/index");
const uiActions = require("devtools/client/webconsole/new-console-output/actions/index");
const {
MESSAGE_LEVEL
} = require("../constants");

Просмотреть файл

@ -8,7 +8,7 @@ const {
DOM: dom,
PropTypes
} = require("devtools/client/shared/vendor/react");
const actions = require("devtools/client/webconsole/new-console-output/actions/filters");
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
const FilterButton = createClass({

Просмотреть файл

@ -18,7 +18,7 @@ const GripMessageBody = createFactory(require("devtools/client/webconsole/new-co
const MessageRepeat = createFactory(require("devtools/client/webconsole/new-console-output/components/message-repeat").MessageRepeat);
const MessageIcon = createFactory(require("devtools/client/webconsole/new-console-output/components/message-icon").MessageIcon);
const CollapseButton = createFactory(require("devtools/client/webconsole/new-console-output/components/collapse-button").CollapseButton);
const actions = require("devtools/client/webconsole/new-console-output/actions/messages");
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
ConsoleApiCall.displayName = "ConsoleApiCall";

Просмотреть файл

@ -15,7 +15,7 @@ const {
const MessageIcon = createFactory(require("devtools/client/webconsole/new-console-output/components/message-icon").MessageIcon);
const CollapseButton = createFactory(require("devtools/client/webconsole/new-console-output/components/collapse-button").CollapseButton);
const { l10n } = require("devtools/client/webconsole/new-console-output/utils/messages");
const actions = require("devtools/client/webconsole/new-console-output/actions/messages");
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
NetworkEventMessage.displayName = "NetworkEventMessage";

Просмотреть файл

@ -18,7 +18,7 @@ const CollapseButton = createFactory(require("devtools/client/webconsole/new-con
const MessageRepeat = createFactory(require("devtools/client/webconsole/new-console-output/components/message-repeat").MessageRepeat);
const MessageIcon = createFactory(require("devtools/client/webconsole/new-console-output/components/message-icon").MessageIcon);
const actions = require("devtools/client/webconsole/new-console-output/actions/messages");
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
PageError.displayName = "PageError";

Просмотреть файл

@ -6,6 +6,7 @@
"use strict";
const actionTypes = {
BATCH_ACTIONS: "BATCH_ACTIONS",
MESSAGE_ADD: "MESSAGE_ADD",
MESSAGES_CLEAR: "MESSAGES_CLEAR",
MESSAGE_OPEN: "MESSAGE_OPEN",

Просмотреть файл

@ -8,7 +8,7 @@ const React = require("devtools/client/shared/vendor/react");
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
const { Provider } = require("devtools/client/shared/vendor/react-redux");
const actions = require("devtools/client/webconsole/new-console-output/actions/messages");
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
const { configureStore } = require("devtools/client/webconsole/new-console-output/store");
const ConsoleOutput = React.createFactory(require("devtools/client/webconsole/new-console-output/components/console-output"));
@ -51,6 +51,10 @@ NewConsoleOutputWrapper.prototype = {
dispatchMessageAdd: (message) => {
store.dispatch(actions.messageAdd(message));
},
dispatchMessagesAdd: (messages) => {
const batchedActions = messages.map(message => actions.messageAdd(message));
store.dispatch(actions.batchActions(batchedActions));
},
dispatchMessagesClear: () => {
store.dispatch(actions.messagesClear());
},

Просмотреть файл

@ -5,8 +5,14 @@
const {FilterState} = require("devtools/client/webconsole/new-console-output/reducers/filters");
const {PrefState} = require("devtools/client/webconsole/new-console-output/reducers/prefs");
const { applyMiddleware, combineReducers, createStore } = require("devtools/client/shared/vendor/redux");
const {
applyMiddleware,
combineReducers,
compose,
createStore
} = require("devtools/client/shared/vendor/redux");
const { thunk } = require("devtools/client/shared/redux/middleware/thunk");
const constants = require("devtools/client/webconsole/new-console-output/constants");
const { reducers } = require("./reducers/index");
const Services = require("Services");
@ -28,10 +34,33 @@ function configureStore() {
return createStore(
combineReducers(reducers),
initialState,
applyMiddleware(thunk)
compose(applyMiddleware(thunk), enableBatching())
);
}
/**
* A enhancer for the store to handle batched actions.
*/
function enableBatching() {
return next => (reducer, initialState, enhancer) => {
function batchingReducer(state, action) {
switch (action.type) {
case constants.BATCH_ACTIONS:
return action.actions.reduce(batchingReducer, state);
default:
return reducer(state, action);
}
}
if (typeof initialState === "function" && typeof enhancer === "undefined") {
enhancer = initialState;
initialState = undefined;
}
return next(batchingReducer, initialState, enhancer);
};
}
// Provide the store factory for test code so that each test is working with
// its own instance.
module.exports.configureStore = configureStore;

Просмотреть файл

@ -2,7 +2,7 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const actions = require("devtools/client/webconsole/new-console-output/actions/filters");
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
const {
FILTER_TEXT_SET,
FILTER_TOGGLE,

Просмотреть файл

@ -26,16 +26,16 @@ describe("Message actions:", () => {
const store = mockStore({});
store.dispatch(actions.messageAdd(packet));
const expectedActions = store.getActions();
expect(expectedActions.length).toEqual(1);
const actualActions = store.getActions();
expect(actualActions.length).toEqual(1);
const addAction = expectedActions[0];
const addAction = actualActions[0];
const {message} = addAction;
const expected = {
const expectedAction = {
type: constants.MESSAGE_ADD,
message: stubPreparedMessages.get("console.log('foobar', 'test')")
};
expect(message.toJS()).toEqual(expected.message.toJS());
expect(message.toJS()).toEqual(expectedAction.message.toJS());
});
it("dispatches expected actions given a console.clear packet", () => {
@ -43,19 +43,19 @@ describe("Message actions:", () => {
const store = mockStore({});
store.dispatch(actions.messageAdd(packet));
const expectedActions = store.getActions();
expect(expectedActions.length).toEqual(2);
const actualActions = store.getActions();
expect(actualActions.length).toEqual(1);
const [clearAction, addAction] = expectedActions;
const [clearAction, addAction] = actualActions[0].actions;
expect(clearAction.type).toEqual(constants.MESSAGES_CLEAR);
const {message} = addAction;
const expected = {
const expectedAction = {
type: constants.MESSAGE_ADD,
message: stubPreparedMessages.get("console.clear()")
};
expect(addAction.type).toEqual(constants.MESSAGE_ADD);
expect(message.toJS()).toEqual(expected.message.toJS());
expect(message.toJS()).toEqual(expectedAction.message.toJS());
});
});

Просмотреть файл

@ -2,7 +2,7 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const actions = require("devtools/client/webconsole/new-console-output/actions/ui");
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
const {
FILTER_BAR_TOGGLE
} = require("devtools/client/webconsole/new-console-output/constants");

Просмотреть файл

@ -58,7 +58,7 @@ function timeit(cb) {
window.onload = Task.async(function* () {
const { configureStore } = browserRequire("devtools/client/webconsole/new-console-output/store");
const { filterTextSet, filtersClear } = browserRequire("devtools/client/webconsole/new-console-output/actions/filters");
const { filterTextSet, filtersClear } = browserRequire("devtools/client/webconsole/new-console-output/actions/index");
const NewConsoleOutputWrapper = browserRequire("devtools/client/webconsole/new-console-output/new-console-output-wrapper");
const wrapper = new NewConsoleOutputWrapper(document.querySelector("#output"), {});

Просмотреть файл

@ -7,7 +7,7 @@ let ReactDOM = require("devtools/client/shared/vendor/react-dom");
let React = require("devtools/client/shared/vendor/react");
var TestUtils = React.addons.TestUtils;
const actions = require("devtools/client/webconsole/new-console-output/actions/messages");
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
const { configureStore } = require("devtools/client/webconsole/new-console-output/store");
const { IdGenerator } = require("devtools/client/webconsole/new-console-output/utils/id-generator");
const { stubPackets } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index");

Просмотреть файл

@ -5,8 +5,8 @@
const expect = require("expect");
const actions = require("devtools/client/webconsole/new-console-output/actions/filters");
const { messageAdd } = require("devtools/client/webconsole/new-console-output/actions/messages");
const actions = require("devtools/client/webconsole/new-console-output/actions/index");
const { messageAdd } = require("devtools/client/webconsole/new-console-output/actions/index");
const { ConsoleCommand } = require("devtools/client/webconsole/new-console-output/types");
const { getAllMessages } = require("devtools/client/webconsole/new-console-output/selectors/messages");
const { getAllFilters } = require("devtools/client/webconsole/new-console-output/selectors/filters");

Просмотреть файл

@ -3272,6 +3272,13 @@ WebConsoleConnectionProxy.prototype = {
});
},
/**
* Batched dispatch of messages.
*/
dispatchMessagesAdd: function(packets) {
this.webConsoleFrame.newConsoleOutput.dispatchMessagesAdd(packets);
},
/**
* The "cachedMessages" response handler.
*
@ -3301,9 +3308,7 @@ WebConsoleConnectionProxy.prototype = {
// Filter out CSS page errors.
messages = messages.filter(message => !(message._type == "PageError"
&& Utils.categoryForScriptError(message) === CATEGORY_CSS));
for (let packet of messages) {
this.dispatchMessageAdd(packet);
}
this.dispatchMessagesAdd(messages);
} else {
this.webConsoleFrame.displayCachedMessages(messages);
if (!this._hasNativeConsoleAPI) {