]> source.dussan.org Git - sonarqube.git/commitdiff
decrease initial amount of js (#462)
authorStas Vilchik <stas.vilchik@sonarsource.com>
Wed, 4 Jul 2018 11:38:11 +0000 (13:38 +0200)
committerSonarTech <sonartech@sonarsource.com>
Wed, 4 Jul 2018 18:21:55 +0000 (20:21 +0200)
server/sonar-web/.babelrc
server/sonar-web/config/webpack.config.js
server/sonar-web/src/main/js/app/components/StartupModal.tsx
server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopupHelper.tsx
server/sonar-web/src/main/js/app/components/extensions/exposeLibraries.ts [new file with mode: 0644]
server/sonar-web/src/main/js/app/components/extensions/utils.js
server/sonar-web/src/main/js/app/components/search/Search.js
server/sonar-web/src/main/js/app/index.js
server/sonar-web/src/main/js/app/utils/exposeLibraries.ts [deleted file]
server/sonar-web/src/main/js/components/lazyLoad.tsx
server/sonar-web/src/main/js/components/workspace/Workspace.tsx

index a14ae9bb095a307312159e7b0d15ecb7b634712f..2beb6e05efa79b934f64370e55c66ab580918e54 100644 (file)
             "IE 11"
           ]
         },
-        "useBuiltIns": true
+        "useBuiltIns": true,
+        "exclude": [
+          "es6.math.acosh",
+          "es6.math.asinh",
+          "es6.math.atanh",
+          "es6.math.cbrt",
+          "es6.math.clz32",
+          "es6.math.cosh",
+          "es6.math.expm1",
+          "es6.math.fround",
+          "es6.math.hypot",
+          "es6.math.imul",
+          "es6.math.log1p",
+          "es6.math.log10",
+          "es6.math.log2",
+          "es6.math.sign",
+          "es6.math.sinh",
+          "es6.math.tanh",
+          "es6.math.trunc",
+
+          "es6.reflect.apply",
+          "es6.reflect.construct",
+          "es6.reflect.define-property",
+          "es6.reflect.delete-property",
+          "es6.reflect.get",
+          "es6.reflect.get-own-property-descriptor",
+          "es6.reflect.get-prototype-of",
+          "es6.reflect.has",
+          "es6.reflect.is-extensible",
+          "es6.reflect.own-keys",
+          "es6.reflect.prevent-extensions",
+          "es6.reflect.set",
+          "es6.reflect.set-prototype-of",
+
+          "es6.set",
+          "es6.symbol",
+
+          "es6.typed.array-buffer",
+          "es6.typed.data-view",
+          "es6.typed.int8-array",
+          "es6.typed.uint8-array",
+          "es6.typed.uint8-clamped-array",
+          "es6.typed.int16-array",
+          "es6.typed.uint16-array",
+          "es6.typed.int32-array",
+          "es6.typed.uint32-array",
+          "es6.typed.float32-array",
+          "es6.typed.float64-array",
+
+          "es6.weak-map",
+          "es6.weak-set",
+
+          "transform-regenerator"
+        ]
       }
     ],
     "react"
index e62bb11f6b4f48cad89917ae0f501172918e0336..9030b4b41eb8d1c86831cf548dd0efe827963e27 100644 (file)
@@ -153,8 +153,8 @@ module.exports = ({ production = true }) => ({
   performance: production
     ? {
         hints: 'error',
-        maxEntrypointSize: 710000, // ~700kb, recommended: 250kb
-        maxAssetSize: 400000 // ~400kb, recommended: 250kb
+        maxEntrypointSize: 600000, // recommended: 250kb
+        maxAssetSize: 320000 // recommended: 250kb
       }
     : undefined
 });
index 914adc7b3ea58f1cfa0ed912c0429896c58ac9f7..bbd6c574eecacf038dfb6e6cf2994e7033533b6c 100644 (file)
 import * as React from 'react';
 import * as PropTypes from 'prop-types';
 import { connect } from 'react-redux';
-import Onboarding from '../../apps/tutorials/Onboarding';
-import CreateOrganizationForm from '../../apps/account/organizations/CreateOrganizationForm';
-import LicensePromptModal from '../../apps/marketplace/components/LicensePromptModal';
-import ProjectOnboardingModal from '../../apps/tutorials/projectOnboarding/ProjectOnboardingModal';
-import TeamOnboardingModal from '../../apps/tutorials/teamOnboarding/TeamOnboardingModal';
 import { CurrentUser, isLoggedIn, Organization } from '../types';
 import { differenceInDays, parseDate, toShortNotSoISOString } from '../../helpers/dates';
 import { EditionKey } from '../../apps/marketplace/utils';
@@ -35,6 +30,23 @@ import { hasMessage } from '../../helpers/l10n';
 import { save, get } from '../../helpers/storage';
 import { isSonarCloud } from '../../helpers/system';
 import { skipOnboarding } from '../../api/users';
+import { lazyLoad } from '../../components/lazyLoad';
+
+const CreateOrganizationForm = lazyLoad(() =>
+  import('../../apps/account/organizations/CreateOrganizationForm')
+);
+const Onboarding = lazyLoad(() => import('../../apps/tutorials/Onboarding'));
+const LicensePromptModal = lazyLoad(
+  () => import('../../apps/marketplace/components/LicensePromptModal'),
+  'LicensePromptModal'
+);
+const ProjectOnboardingModal = lazyLoad(
+  () => import('../../apps/tutorials/projectOnboarding/ProjectOnboardingModal'),
+  'ProjectOnboardingModal'
+);
+const TeamOnboardingModal = lazyLoad(() =>
+  import('../../apps/tutorials/teamOnboarding/TeamOnboardingModal')
+);
 
 interface StateProps {
   canAdmin: boolean;
index 06b7bc02b0217eaee6815b75f8364b787b0d3b66..f9671bc289e7b131e08fde992da289673596d52f 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
-import EmbedDocsPopup from './EmbedDocsPopup';
 import { SuggestionLink } from './SuggestionsProvider';
 import { CurrentUser } from '../../types';
 import Toggler from '../../../components/controls/Toggler';
 import HelpIcon from '../../../components/icons-components/HelpIcon';
+import { lazyLoad } from '../../../components/lazyLoad';
+
+const EmbedDocsPopup = lazyLoad(() => import('./EmbedDocsPopup'));
 
 interface Props {
   currentUser: CurrentUser;
diff --git a/server/sonar-web/src/main/js/app/components/extensions/exposeLibraries.ts b/server/sonar-web/src/main/js/app/components/extensions/exposeLibraries.ts
new file mode 100644 (file)
index 0000000..026979b
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import * as ReactRedux from 'react-redux';
+import * as ReactRouter from 'react-router';
+import throwGlobalError from '../../utils/throwGlobalError';
+import addGlobalSuccessMessage from '../../utils/addGlobalSuccessMessage';
+import Suggestions from '../../components/embed-docs-modal/Suggestions';
+import * as measures from '../../../helpers/measures';
+import * as request from '../../../helpers/request';
+import DateFromNow from '../../../components/intl/DateFromNow';
+import DateFormatter from '../../../components/intl/DateFormatter';
+import DateTimeFormatter from '../../../components/intl/DateTimeFormatter';
+import FavoriteContainer from '../../../components/controls/FavoriteContainer';
+import HomePageSelect from '../../../components/controls/HomePageSelect';
+import ListFooter from '../../../components/controls/ListFooter';
+import Modal from '../../../components/controls/Modal';
+import HelpTooltip from '../../../components/controls/HelpTooltip';
+import SearchBox from '../../../components/controls/SearchBox';
+import Select from '../../../components/controls/Select';
+import Tooltip from '../../../components/controls/Tooltip';
+import SelectList from '../../../components/SelectList/SelectList';
+import CoverageRating from '../../../components/ui/CoverageRating';
+import DuplicationsRating from '../../../components/ui/DuplicationsRating';
+import Level from '../../../components/ui/Level';
+import { EditButton, Button, SubmitButton, ResetButtonLink } from '../../../components/ui/buttons';
+import Checkbox from '../../../components/controls/Checkbox';
+import DeferredSpinner from '../../../components/common/DeferredSpinner';
+import Dropdown from '../../../components/controls/Dropdown';
+import ReloadButton from '../../../components/controls/ReloadButton';
+import AlertErrorIcon from '../../../components/icons-components/AlertErrorIcon';
+import AlertSuccessIcon from '../../../components/icons-components/AlertSuccessIcon';
+import AlertWarnIcon from '../../../components/icons-components/AlertWarnIcon';
+import CheckIcon from '../../../components/icons-components/CheckIcon';
+import ClearIcon from '../../../components/icons-components/ClearIcon';
+import DropdownIcon from '../../../components/icons-components/DropdownIcon';
+import HelpIcon from '../../../components/icons-components/HelpIcon';
+import LockIcon from '../../../components/icons-components/LockIcon';
+import QualifierIcon from '../../../components/icons-components/QualifierIcon';
+import Rating from '../../../components/ui/Rating';
+import BranchIcon from '../../../components/icons-components/BranchIcon';
+import LongLivingBranchIcon from '../../../components/icons-components/LongLivingBranchIcon';
+import PullRequestIcon from '../../../components/icons-components/PullRequestIcon';
+import ActionsDropdown, { ActionsDropdownItem } from '../../../components/controls/ActionsDropdown';
+
+const exposeLibraries = () => {
+  const global = window as any;
+
+  global.ReactRedux = ReactRedux;
+  global.ReactRouter = ReactRouter;
+  global.SonarMeasures = measures;
+  global.SonarRequest = { ...request, throwGlobalError, addGlobalSuccessMessage };
+  global.SonarComponents = {
+    ActionsDropdown,
+    ActionsDropdownItem,
+    AlertErrorIcon,
+    AlertSuccessIcon,
+    AlertWarnIcon,
+    BranchIcon,
+    Button,
+    Checkbox,
+    CheckIcon,
+    ClearIcon,
+    CoverageRating,
+    DateFormatter,
+    DateFromNow,
+    DateTimeFormatter,
+    DeferredSpinner,
+    Dropdown,
+    DropdownIcon,
+    DuplicationsRating,
+    EditButton,
+    FavoriteContainer,
+    HelpIcon,
+    HelpTooltip,
+    HomePageSelect,
+    Level,
+    ListFooter,
+    LockIcon,
+    LongLivingBranchIcon,
+    Modal,
+    PullRequestIcon,
+    QualifierIcon,
+    Rating,
+    ReloadButton,
+    ResetButtonLink,
+    SearchBox,
+    Select,
+    SelectList,
+    SubmitButton,
+    Suggestions,
+    Tooltip
+  };
+};
+
+export default exposeLibraries;
index c62cb61ee4a7ae6933909a676daf4d08a9745158..98600e2558147a00ce25828c90300646aea80620 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 // @flow
+import exposeLibraries from './exposeLibraries';
 import { getExtensionFromCache } from '../../utils/installExtensionsHandler';
 
 function installScript(key /*: string */) {
   return new Promise(resolve => {
+    exposeLibraries();
     const scriptTag = document.createElement('script');
     scriptTag.src = `${window.baseUrl}/static/${key}.js`;
     scriptTag.onload = resolve;
@@ -33,7 +35,8 @@ export function getExtensionStart(key /*: string */) {
   return new Promise((resolve, reject) => {
     const fromCache = getExtensionFromCache(key);
     if (fromCache) {
-      return resolve(fromCache);
+      resolve(fromCache);
+      return;
     }
 
     installScript(key).then(() => {
@@ -43,6 +46,6 @@ export function getExtensionStart(key /*: string */) {
       } else {
         reject();
       }
-    });
+    }, reject);
   });
 }
index cd315cbfacf0f34c8d8c0b4c9d3cc3312fc75d58..db4a2b7949445e253c1845b93a1ccb51b4ad7b82 100644 (file)
@@ -23,21 +23,23 @@ import PropTypes from 'prop-types';
 import key from 'keymaster';
 import { debounce, keyBy, uniqBy } from 'lodash';
 import { FormattedMessage } from 'react-intl';
-import SearchResults from './SearchResults';
-import SearchResult from './SearchResult';
 import { sortQualifiers } from './utils';
 /*:: import type { Component, More, Results } from './utils'; */
 import RecentHistory from '../../components/RecentHistory';
 import DeferredSpinner from '../../../components/common/DeferredSpinner';
+import { DropdownOverlay } from '../../../components/controls/Dropdown';
 import ClockIcon from '../../../components/icons-components/ClockIcon';
 import OutsideClickHandler from '../../../components/controls/OutsideClickHandler';
 import SearchBox from '../../../components/controls/SearchBox';
+import { lazyLoad } from '../../../components/lazyLoad';
 import { getSuggestions } from '../../../api/components';
 import { translate, translateWithParameters } from '../../../helpers/l10n';
 import { scrollToElement } from '../../../helpers/scrolling';
 import { getProjectUrl } from '../../../helpers/urls';
 import './Search.css';
-import { DropdownOverlay } from '../../../components/controls/Dropdown';
+
+const SearchResults = lazyLoad(() => import('./SearchResults'));
+const SearchResult = lazyLoad(() => import('./SearchResult'));
 
 /*::
 type Props = {|
index ee6cfb479d74788aadf1694910c3905e3fa404ec..6fe8aa8dc409e3dad4f89b92cc376ad53af587aa 100644 (file)
@@ -17,7 +17,6 @@
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
-import exposeLibraries from './utils/exposeLibraries';
 import startReactApp from './utils/startReactApp';
 import installExtensionsHandler from './utils/installExtensionsHandler';
 import { installGlobal } from '../helpers/l10n';
@@ -26,5 +25,4 @@ import './styles/sonar.css';
 
 installGlobal();
 startReactApp();
-exposeLibraries();
 installExtensionsHandler();
diff --git a/server/sonar-web/src/main/js/app/utils/exposeLibraries.ts b/server/sonar-web/src/main/js/app/utils/exposeLibraries.ts
deleted file mode 100644 (file)
index 03bb25e..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-import * as ReactRedux from 'react-redux';
-import * as ReactRouter from 'react-router';
-import throwGlobalError from './throwGlobalError';
-import addGlobalSuccessMessage from './addGlobalSuccessMessage';
-import Suggestions from '../components/embed-docs-modal/Suggestions';
-import * as measures from '../../helpers/measures';
-import * as request from '../../helpers/request';
-import DateFromNow from '../../components/intl/DateFromNow';
-import DateFormatter from '../../components/intl/DateFormatter';
-import DateTimeFormatter from '../../components/intl/DateTimeFormatter';
-import FavoriteContainer from '../../components/controls/FavoriteContainer';
-import HomePageSelect from '../../components/controls/HomePageSelect';
-import ListFooter from '../../components/controls/ListFooter';
-import Modal from '../../components/controls/Modal';
-import HelpTooltip from '../../components/controls/HelpTooltip';
-import SearchBox from '../../components/controls/SearchBox';
-import Select from '../../components/controls/Select';
-import Tooltip from '../../components/controls/Tooltip';
-import SelectList from '../../components/SelectList/SelectList';
-import CoverageRating from '../../components/ui/CoverageRating';
-import DuplicationsRating from '../../components/ui/DuplicationsRating';
-import Level from '../../components/ui/Level';
-import { EditButton, Button, SubmitButton, ResetButtonLink } from '../../components/ui/buttons';
-import Checkbox from '../../components/controls/Checkbox';
-import DeferredSpinner from '../../components/common/DeferredSpinner';
-import Dropdown from '../../components/controls/Dropdown';
-import ReloadButton from '../../components/controls/ReloadButton';
-import AlertErrorIcon from '../../components/icons-components/AlertErrorIcon';
-import AlertSuccessIcon from '../../components/icons-components/AlertSuccessIcon';
-import AlertWarnIcon from '../../components/icons-components/AlertWarnIcon';
-import CheckIcon from '../../components/icons-components/CheckIcon';
-import ClearIcon from '../../components/icons-components/ClearIcon';
-import DropdownIcon from '../../components/icons-components/DropdownIcon';
-import HelpIcon from '../../components/icons-components/HelpIcon';
-import LockIcon from '../../components/icons-components/LockIcon';
-import QualifierIcon from '../../components/icons-components/QualifierIcon';
-import Rating from '../../components/ui/Rating';
-import BranchIcon from '../../components/icons-components/BranchIcon';
-import LongLivingBranchIcon from '../../components/icons-components/LongLivingBranchIcon';
-import PullRequestIcon from '../../components/icons-components/PullRequestIcon';
-import ActionsDropdown, { ActionsDropdownItem } from '../../components/controls/ActionsDropdown';
-
-const exposeLibraries = () => {
-  const global = window as any;
-
-  global.ReactRedux = ReactRedux;
-  global.ReactRouter = ReactRouter;
-  global.SonarMeasures = measures;
-  global.SonarRequest = { ...request, throwGlobalError, addGlobalSuccessMessage };
-  global.SonarComponents = {
-    ActionsDropdown,
-    ActionsDropdownItem,
-    AlertErrorIcon,
-    AlertSuccessIcon,
-    AlertWarnIcon,
-    BranchIcon,
-    Button,
-    Checkbox,
-    CheckIcon,
-    ClearIcon,
-    CoverageRating,
-    DateFormatter,
-    DateFromNow,
-    DateTimeFormatter,
-    DeferredSpinner,
-    Dropdown,
-    DropdownIcon,
-    DuplicationsRating,
-    EditButton,
-    FavoriteContainer,
-    HelpIcon,
-    HelpTooltip,
-    HomePageSelect,
-    Level,
-    ListFooter,
-    LockIcon,
-    LongLivingBranchIcon,
-    Modal,
-    PullRequestIcon,
-    QualifierIcon,
-    Rating,
-    ReloadButton,
-    ResetButtonLink,
-    SearchBox,
-    Select,
-    SelectList,
-    SubmitButton,
-    Suggestions,
-    Tooltip
-  };
-};
-
-export default exposeLibraries;
index 7043b40f4407771a7dbf4a63b19d10aa1b4173f0..2b4268bf08ae6c8ecd58b5ed7cf96099b33a7a9d 100644 (file)
@@ -29,7 +29,7 @@ interface Loader<P> {
 
 export const LAST_FAILED_CHUNK_STORAGE_KEY = 'sonarqube.last_failed_chunk';
 
-export function lazyLoad<P>(loader: Loader<P>) {
+export function lazyLoad<P>(loader: Loader<P>, displayName?: string) {
   interface ImportError {
     request?: string;
   }
@@ -43,6 +43,7 @@ export function lazyLoad<P>(loader: Loader<P>) {
   // and let the child component decide if it needs to change
   return class LazyLoader extends React.Component<any, State> {
     mounted = false;
+    static displayName = displayName;
     state: State = {};
 
     componentDidMount() {
index 65950494d588cda5f0b4d8afa6671e68c74c0bc6..ea0cc484b7fa35ec122fa0001cb0038f75d622b2 100644 (file)
@@ -21,13 +21,13 @@ import * as React from 'react';
 import * as PropTypes from 'prop-types';
 import { omit, uniqBy } from 'lodash';
 import { WorkspaceContext, ComponentDescriptor, RuleDescriptor } from './context';
-import WorkspaceNav from './WorkspaceNav';
 import WorkspacePortal from './WorkspacePortal';
 import { get, save } from '../../helpers/storage';
 import { lazyLoad } from '../lazyLoad';
 import './styles.css';
 
 const WORKSPACE = 'sonarqube-workspace';
+const WorkspaceNav = lazyLoad(() => import('./WorkspaceNav'));
 const WorkspaceRuleViewer = lazyLoad(() => import('./WorkspaceRuleViewer'));
 const WorkspaceComponentViewer = lazyLoad(() => import('./WorkspaceComponentViewer'));
 
@@ -190,15 +190,17 @@ export default class Workspace extends React.PureComponent<{}, State> {
       <>
         {this.props.children}
         <WorkspacePortal>
-          <WorkspaceNav
-            components={components}
-            onComponentClose={this.closeComponent}
-            onComponentOpen={this.reopenComponent}
-            onRuleClose={this.closeRule}
-            onRuleOpen={this.reopenRule}
-            open={this.state.open}
-            rules={this.state.rules}
-          />
+          {(components.length > 0 || rules.length > 0) && (
+            <WorkspaceNav
+              components={components}
+              onComponentClose={this.closeComponent}
+              onComponentOpen={this.reopenComponent}
+              onRuleClose={this.closeRule}
+              onRuleOpen={this.reopenRule}
+              open={this.state.open}
+              rules={rules}
+            />
+          )}
           {openComponent && (
             <WorkspaceComponentViewer
               component={openComponent}