代码之家  ›  专栏  ›  技术社区  ›  vector

Vuetify对话框-在ACE编辑器中格式化2.5MB XML的速度非常慢

  •  0
  • vector  · 技术社区  · 5 年前

    我有一个Vue/Vuefify项目,我正在使用vkbeutify库格式化XML,然后在Ace编辑器中显示它。编辑器在模式对话框(全屏模式)中打开,当XML量很小时,所有这些都能很好地工作。

    我必须解析大约2.5MB+的XML(在Notepad++中格式化时大约为2500000个字符),然后Ace变得不可用(它最终会显示XML,但需要很长时间)。

    我创建了一个简单的测试页面,其中包含一个文本区域和编辑器,格式化和显示速度非常快。该页面执行的操作与此完全相同: https://www.webtoolkitonline.com/xml-formatter.html (这使用Ace和vkbeautify来格式化xml)

    我尝试在将XML传递给子对话框之前在文本区域中对其进行预格式化,尝试颠覆Vue并通过直接获取DOM内容在mounted()函数中填充编辑器容器。

    独立测试页面:

        <!DOCTYPE html>
    <html lang="en">
    <head>
        <title>ACE in Action</title>
        <style type="text/css" media="screen">#editor {position: absolute;top: 0;right: 0;bottom: 0;left: 0;}</style>
        <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
        <script src="https://pagecdn.io/lib/ace/1.4.5/ace.js" integrity="sha256-5Xkhn3k/1rbXB+Q/DX/2RuAtaB4dRRyQvMs83prFjpM=" crossorigin="anonymous"></script>
        <script src="https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/vkbeautify/vkbeautify.0.99.00.beta.js"></script>
    </head>
    <body>
    <div style="position: relative; width: 100%; height: 500px;">
    <div id="editor">
        <tag><inner_tag>sce to aux</inner_tag></tag>
    </div>
    </div>
    <div>
    <form>
        <textarea id="xml"><?xml version="1.0" encoding="UTF-8"?><tag><inner_tag>hi</inner_tag></tag></textarea>
        <fieldset><input type="button" id="format" value="Format"></fieldset>
    </form>
    </div>
    <script>
        var editor = ace.edit("editor");
        editor.setTheme("ace/theme/cobalt");
        editor.session.setMode("ace/mode/xml");
        $( function() {
            $( "#format").click(
                async function() {
                    var content = document.getElementById("xml").value;
                    try {
                        editor.setValue(  content  );
                        editor.setValue( vkbeautify.xml( editor.getValue()  ) );
                    } catch( err ) {
                        alert( "Your document is invalid" );
                    }
                }
            );
        });
    </script>
    </body>
    </html>
    

    Vue组件:

        <template>
      <div>
        <b>Open In Editor </b>
        <v-btn icon color="transparent" depressed small @click="openInEditor()"><v-icon color="#666666">mdi-pencil</v-icon>
        </v-btn>
        <v-dialog v-model="showAceEditorModal" fullscreen hide-overlay eager>
          <v-card>
            <v-toolbar dark color="primary">
              <v-btn icon dark @click="closeAceEditor">
                <v-icon>mdi-close</v-icon>
              </v-btn>
              <v-toolbar-title>{{title}}</v-toolbar-title>
              <v-card-text v-if="editable===false"> Read Only Mode - you won't be able to edit or save changes</v-card-text>
              <v-spacer></v-spacer>
              <v-toolbar-items>
                <v-btn dark text @click="sendEditsToParent">
                  {{ closeLabelTxt }}
                </v-btn>
              </v-toolbar-items>
            </v-toolbar>
            <div :id=editorIdX >
              {{ v }}
            </div>
            <div id="test"></div>
          </v-card>
        </v-dialog>
      </div>
    </template>
    <script>
    import * as ace from '@/assets/js/ace/src-min-noconflict/ace.js';
    import * as v from '@/assets/js/ace/vkbeautify.js';
    export default {
      name: "AceEditor",
      props:['title', 'editable', 'value', 'originalItem', 'editorIdX'],
    
      data(){
        return {
          v : "",
          oldItem : this.originalItem,
          showAceEditorModal: false
        }
      },
    
      computed : {
        closeLabelTxt : function (){
          return this.editable?"Save":"Close Me";
        }
      },
      mounted(){
        this.v = document.getElementById("textArea_0").value
        document.getElementById("test").innerText = document.getElementById("textArea_0").value
      },
      methods:{
        openInEditor(){
          this.editorId = this.editorIdX;
          this.editor = ace.edit(  this.editorIdX  );
          if( this.editable === false ){
            this.editor.setReadOnly( true );
          }
    
          //  deprecation fix
          this.editor.$blockScrolling = Infinity;
          //  ignore doctype warnings
          const session = this.editor.getSession();
          session.on("changeAnnotation", () => {
            const a = session.getAnnotations();
            const b = a.slice(0).filter( (item) => item.text.indexOf('DOC') == -1 );
            if(a.length > b.length) session.setAnnotations(b);
          });
    
          //  editor options
          this.options = this.options || {};
    
          //  opinionated option defaults
          this.options.maxLines = this.options.maxLines || Infinity;
          this.options.printMargin = this.options.printMargin || false;
          this.options.highlightActiveLine = this.options.highlightActiveLine || false;
    
          //  hide cursor
          if(this.options.cursor === 'none' || this.options.cursor === false){
            this.editor.renderer.$cursorLayer.element.style.display = 'none';
            delete this.options.cursor;
          }
    
          //  add missing mode and theme paths
          if(this.options.mode && this.options.mode.indexOf('ace/mode/')===-1) {
            this.options.mode = `ace/mode/${this.options.mode}`;
          }
          if(this.options.theme && this.options.theme.indexOf('ace/theme/')===-1) {
            this.options.theme = 'ace/theme/${this.options.theme}';
          }
          this.editor.setOptions(this.options);
          this.showAceEditorModal = true;
        },
    
        closeAceEditor(){
          this.showAceEditorModal = false;
        },
        sendEditsToParent(){
          if( this.editor.getReadOnly() === false ){
            this.$emit('editedItem', [ {"editedItem": this.editor.getValue() }, {"originalItem":this.oldItem}]);
          }
          this.showAceEditorModal = false
        },
        reformatContent(){
          let x = this.editor.session.getValue();
          this.editor.session.setValue("");
          x = vkbeautify.xml( x );
          this.editor.session.setValue( x );
        }
      }
    }
    </script>
    
    0 回复  |  直到 5 年前
        1
  •  1
  •   a user    5 年前

    这是因为您正在设置 maxLines 到 Infinity ,通过禁用编辑器的虚拟屏幕优化。 maxLines 适用于小于窗口高度的小片段。