Преглед изворни кода

Faster initial loading of script editor and settings/about (#621)

* speedup and deflicker for initial options page load

* skip rendering the aside when starting in the editor for a new script
* skip rendering the script list when starting in the editor

* actually mount the editor on history nav

* use history back navigation instead of replacing the state
tophf пре 6 година
родитељ
комит
bf74cf9935
3 измењених фајлова са 42 додато и 10 уклоњено
  1. 3 0
      src/common/router.js
  2. 9 1
      src/options/views/app.vue
  3. 30 9
      src/options/views/tab-installed.vue

+ 3 - 0
src/common/router.js

@@ -12,9 +12,12 @@ function parse(pathInfo) {
 }
 
 export const route = {};
+export const lastRoute = {};
+
 updateRoute();
 
 function updateRoute() {
+  Object.assign(lastRoute, route);
   Object.assign(route, parse(window.location.hash.slice(1)));
 }
 

+ 9 - 1
src/options/views/app.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="page-options flex h-100">
-    <aside :class="{ 'show-aside': aside }">
+    <aside :class="{ 'show-aside': aside }" v-if="canRenderAside">
       <div v-if="aside" class="aside-backdrop visible-sm" @click="aside = false" />
       <div class="aside-content">
         <img src="/public/images/icon128.png">
@@ -53,8 +53,12 @@ export default {
     Icon,
   },
   data() {
+    const [tab, tabFunc] = store.route.paths;
     return {
       aside: false,
+      // Speedup and deflicker for initial page load:
+      // skip rendering the aside when starting in the editor for a new script.
+      canRenderAside: tab !== 'scripts' || (tabFunc !== '_new' && !Number(tabFunc)),
       store,
     };
   },
@@ -72,6 +76,10 @@ export default {
     'store.title'(title) {
       document.title = title ? `${title} - ${extName}` : extName;
     },
+    'store.route.paths'() {
+      // First time showing the aside we need to tell v-if to keep it forever
+      this.canRenderAside = true;
+    },
   },
 };
 </script>

+ 30 - 9
src/options/views/tab-installed.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="tab-installed flex flex-col">
-    <div class="flex flex-col flex-auto">
+    <div class="flex flex-col flex-auto" v-if="canRenderScripts">
       <header class="flex">
         <div class="flex-auto" v-if="!showRecycle">
           <dropdown
@@ -109,7 +109,7 @@ import SettingCheck from '#/common/ui/setting-check';
 import hookSetting from '#/common/hook-setting';
 import Icon from '#/common/ui/icon';
 import LocaleGroup from '#/common/ui/locale-group';
-import { setRoute } from '#/common/router';
+import { setRoute, lastRoute } from '#/common/router';
 import ScriptItem from './script-item';
 import Edit from './edit';
 import { store, showMessage } from '../utils';
@@ -169,16 +169,16 @@ export default {
       showRecycle: false,
       filteredScripts: [],
       removing: null,
+      // Speedup and deflicker for initial page load:
+      // skip rendering the script list when starting in the editor.
+      canRenderScripts: !store.route.paths[1],
     };
   },
   watch: {
     search: 'updateLater',
     'filters.sort.value': 'updateLater',
     showRecycle: 'onUpdate',
-    scripts() {
-      this.onUpdate();
-      this.onHashChange();
-    },
+    scripts: 'refreshUI',
     'store.route.paths.1': 'onHashChange',
   },
   computed: {
@@ -199,6 +199,10 @@ export default {
     },
   },
   methods: {
+    refreshUI() {
+      this.onUpdate();
+      this.onHashChange();
+    },
     onUpdate() {
       const { search, filters: { sort }, showRecycle } = this;
       const lowerSearch = (search || '').toLowerCase();
@@ -293,15 +297,27 @@ export default {
       this.menuNewActive = active;
     },
     onEditScript(id) {
-      setRoute(['scripts', id].filter(Boolean).join('/'), true);
+      const pathname = ['scripts', id].filter(Boolean).join('/');
+      if (!id && pathname === lastRoute.pathname) {
+        window.history.back();
+      } else {
+        setRoute(pathname);
+      }
     },
     onHashChange() {
-      const id = this.store.route.paths[1];
+      const [tab, id] = this.store.route.paths;
       if (id === '_new') {
         this.script = {};
       } else {
         const nid = id && +id || null;
         this.script = nid && this.scripts.find(script => script.props.id === nid);
+        if (!this.script) {
+          // First time showing the list we need to tell v-if to keep it forever
+          this.canRenderScripts = true;
+          // Strip the invalid id from the URL so |App| can render the aside,
+          // which was hidden to avoid flicker on initial page load directly into the editor.
+          if (id) setRoute(tab, true);
+        }
       }
     },
     toggleRecycle() {
@@ -332,7 +348,12 @@ export default {
   },
   created() {
     this.debouncedUpdate = debounce(this.onUpdate, 200);
-    this.onUpdate();
+  },
+  mounted() {
+    // Ensure the correct UI is shown when mounted:
+    // * on subsequent navigation via history back/forward;
+    // * on first initialization in some weird case the scripts got loaded early.
+    if (!store.loading) this.refreshUI();
   },
 };
 </script>