Как ускорить рендеринг страницы и операции с динамическим HTML-элементом (используйте ngFor и ngSwitchCase)

#javascript #angular #angular-ng-if #angular-dynamic-components #angular-ngfor

#javascript #angular #angular-ng-if #angular-dynamic-components #angular-ngfor

Вопрос:

Проблема:

У меня есть двухслойный ngFor угловой шаблон. Внутри ngFor я использую множество ngSwitchCase , чтобы выбрать, какой HTML-элемент я хочу показывать динамически.

Эта страница успешно показывает то, что я хочу, но скорость рендеринга и операции этой страницы немного медленны в Chrome, не быстро, но приемлемо (но в IE11 это слишком медленно для использования ….)

Вот шаблон:

 <form #qaForm="ngForm">

        <div *ngFor="let qa of qaList;let qIndex= index">

            <div *ngIf="!qa.hide">

                <div class="card-header bg-info text-white h5">
                    <label>{{'Q'   (qIndex 1)   '.'}}{{qa.question.questionContent}}</label>
                </div>

                <br>

                <div [ngStyle]="caseQuestionsService.getStyle(ans)" *ngFor="let ans of qa.answers;let aIndex= index"
                    [ngSwitch]="ans.dataType">

                    <div *ngIf="!ans.hide">
                        <div *ngIf="isDependPage">
                            <h6><span class="badge badge-secondary">{{(qIndex 1)   '-'   (aIndex 1)}}</span></h6>
                        </div>

                        <div *ngSwitchCase="'displayfield'" class = "form-inline">
                            <label class="ma mr-1 ml-1">{{ans.answerContent}}</label>
                        </div>

                        <div *ngSwitchCase="'newline'">
                            <br>
                        </div>

                        <div *ngSwitchCase="'textfield'">
                            <input type="text" class="form-control" name="q-{{qIndex}}-answers-{{aIndex}}" [(ngModel)]="ans.typedAns"
                                (change)="hideQAByIdx(qIndex, aIndex, answers)" #answers="ngModel" required>

                        </div>

                        <div *ngSwitchCase="'numberfield'">
                            <input type="number" class="form-control" name="q-{{qIndex}}-answers-{{aIndex}}"
                                [(ngModel)]="ans.typedAns" (change)="hideQAByIdx(qIndex, aIndex, answers)" #answers="ngModel"
                                required>

                        </div>

                        <div *ngSwitchCase="'textareafield'">

                            <textarea type="text" class="form-control" name="q-{{qIndex}}-answers-{{aIndex}}"
                                [(ngModel)]="ans.typedAns" (change)="hideQAByIdx(qIndex, aIndex, answers)" #answers="ngModel"
                                required></textarea>

                        </div>

                        <div *ngSwitchCase="'singlecombobox'">
                            <select type="text" class="form-control" name="q-{{qIndex}}-answers-{{aIndex}}" [(ngModel)]="ans.typedAns"
                                (change)="hideQAByIdx(qIndex, aIndex, answers)" #answers="ngModel" required>
                                <option [ngValue]="null">select</option>
                                <option *ngFor="let item of ans.answerContentAry" [ngValue]="item.value">{{
                                    item.text
                                    }}</option>
                            </select>
                        </div>

                        <div *ngSwitchCase="'singlecomboboxu'">
                            <!--editable single selects-->
                            <app-input-select class="form-control" [selectAry]="ans.answerContentStringAry" name="q-{{qIndex}}-answers-{{aIndex}}"
                                (click)="hideQAByIdx(qIndex, aIndex, ans.typedAns)" (change)="hideQAByIdx(qIndex, aIndex, ans.typedAns)" [(ngModel)]="ans.typedAns"
                                #answers="ngModel" required></app-input-select>
                        </div>

                        <div *ngSwitchCase="'multicombobox'">
                            <div class="row col">
                                <ng-multiselect-dropdown class="col-12" [placeholder]="'select'" [settings]="dropdownSettings"
                                    [data]="ans.answerContentAry" (onSelect)="hideQAByIdx(qIndex, aIndex, answers)"
                                    (onSelectAll)="hideQAByIdx(qIndex, aIndex, answers)" (onDeSelect)="hideQAByIdx(qIndex, aIndex, answers)"
                                    name="q-{{qIndex}}-answers-{{aIndex}}" [(ngModel)]="ans.typedAns" #answers="ngModel"
                                    required></ng-multiselect-dropdown>
                            </div>
                        </div>

                        <div *ngSwitchCase="'datePicker'">
                            <div class="input-group">
                                <input type="text" class="form-control col-9" ngbDatepicker #dpEnd="ngbDatepicker" name="q-{{qIndex}}-answers-{{aIndex}}"
                                    (ngModelChange)="hideQAByIdx(qIndex, aIndex, answers)" [(ngModel)]="ans.typedAns"
                                    #answers="ngModel" required>
                                <div class="input-group-append">
                                    <button type="button" class="btn btn-outline-secondary" tabindex="-1" (click)="dpEnd.toggle()">
                                        <i class="fas fa-calendar-alt"></i>
                                    </button>
                                </div>
                            </div>
                        </div>

                        <div *ngSwitchCase="'dateTimePicker'">
                            <div class="input-group">
                                <input type="text" class="form-control col-9" appDateTimePicker #dpEnd="appDateTimePicker"
                                    (ngModelChange)="hideQAByIdx(qIndex, aIndex, answers)" name="q-{{qIndex}}-answers-{{aIndex}}"
                                    [(ngModel)]="ans.typedAns" #answers="ngModel" required>
                                <div class="input-group-append">
                                    <button class="btn btn-outline-secondary" type="button" tabindex="-1" (click)="dpEnd.toggle()">
                                        <i class="fas fa-calendar-alt"></i>
                                    </button>
                                </div>
                            </div>
                        </div>

                        <div *ngSwitchCase="'customization'">
                            <input type="text" class="form-control" name="q-{{qIndex}}-answers-{{aIndex}}" [(ngModel)]="ans.typedAns"
                                (change)="hideQAByIdx(qIndex, aIndex, answers)" #answers="ngModel" required>
                        </div>

                    </div>
                </div>
            </div>
        </div>
    </form>
  

getStyle(ans)

     public getStyle(ans) {
        let display = '';
        let width = '';
        if (
            ans.dataType !== 'newline' amp;amp;
            ans.dataType !== 'textareafield' amp;amp;
            ans.dataType !== 'multicombobox'
        ) {
            width = 'fit-content';
            display = 'inline-block';
        }

        return { display: display, width: width };
    }
  

Я думаю…

Я думаю о двух способах повышения скорости этой страницы, но я не уверен в них.

  1. Изменение на использование ComponentFactoryResolver для динамической генерации компонента. (Я не уверен, что это будет быстро или нет)

  2. Создание скомпонованного статического HTML в Typescript, а затем загрузка их в шаблон Angular? (Я не уверен в подробной реализации)

Кто-нибудь даст мне несколько предложений по этим двум способам или новое предложение?

Спасибо за вашу помощь, спасибо.

Комментарии:

1. Можете ли вы попробовать удалить привязку к функции здесь -> [ngStyle]="caseQuestionsService.getStyle(ans)" , а также добавить, что делает эта функция.

2. Спасибо за ваше предложение! Я удалил его, но, похоже, он не очень работал. Я вставил приведенный выше код ( caseQuestionsService.getStyle(ans) )

3. Код выглядит хорошо, по моему опыту, огромный паритет в производительности между ie11 и другими достигается за счет использования полизаполнений для IE, в то время как другие браузеры имеют встроенную реализацию. Но ваш случай, вероятно, связан с большим набором вопросов, можете ли вы дать представление о том, сколько итераций задействовано в каждом ngFor? Или, другими словами, насколько велики ваши данные?

4. Почти 20 * 5 = 200 итераций или 20 * 15 = 300 итераций, может быть, 20 вопросов, и на каждый вопрос 5 ~ 15 ответов, так что у него 200 ~ 300 итераций, это большой размер, я знаю> <