简体   繁体   中英

Page Loads Slowly

I have an admin panel that the admin can use to edit events; so I fetch the events from the DB and display them there for the admin to edit. And this takes 1.5min on average .

Here are the relevant files:

Controller

    public function editEvent($result = null)
    {
        if ($this->adminIsLoggedIn()) {

            $db = new DB();

            $events = $db->getEvents();
            $venues = $db->getVenues();
            $types = $db->getEventTypes();

            echo $this->twig->render('editEvent.twig', array('result'=>$result, 'events'=>$events, 'venues'=>$venues, 'types'=>$types));

        } else {
            $this->login();
        }
    }

The html page (I am using Twig)

{% extends "master.twig" %}

{% block content %}

    <div class="right_col" role="main">
        <div class="">
            <div class="page-title">
                <div class="title_left">
                    <h3>Edit Event</h3>
                </div>
            </div>

            <div class="clearfix"></div>

            <div class="row">
                <div class="col-md-12 col-sm-12 col-xs-12">
                    <div class="x_panel">
                        <div class="x_title">
                            <h2>Click on the fields to edit</h2>
                            <ul class="nav navbar-right panel_toolbox">
                                <li><a class="collapse-link"><i class="fa fa-chevron-up"></i></a>
                                </li>
                            </ul>
                            <div class="clearfix"></div>
                        </div>
                        <div class="x_content">

                            {% if result.success == true %}
                                <h3 style="color: forestgreen">{{ result.message }}</h3>
                            {% else %}
                                <h3 style="color: tomato">{{ result.message }}</h3>
                            {% endif %}

                            <form action="/admin/editEvent" method="post">
                                <table id="datatable"
                                       class="table table-striped table-bordered responsive-utilities jambo_table">
                                    <thead>
                                    <tr>
                                        <th>ID</th>
                                        <th>Title</th>
                                        <th>Description</th>
                                        <th>Source URL</th>
                                        <th>Type</th>
                                        <th>Start Date</th>
                                        <th>End Date</th>
                                        <th>Date Created</th>
                                        <th>Start Time</th>
                                        <th>End Time</th>
                                        <th>Venue</th>
                                    </tr>
                                    </thead>

                                    <tbody>
                                    {% for event in events %}

                                        <tr>
                                            <td>
                                                <input type="checkbox" name="events[]" value="{{ event.id }}"/>
                                            </td>
                                            <td>
                                                <input style="border: 1px solid lightblue;" type="text" name="title[{{ event.id }}]" value="{{ event.title}}">
                                            </td>
                                            <td>
                                                <textarea style="border: 1px solid lightblue;" class="mce_ta" type="text" name="description[{{ event.id }}]">{{ event.description }}</textarea>
                                            </td>
                                            <td>
                                                <input style="border: 1px solid lightblue;" type="text" name="source_url[{{ event.id }}]" value="{{ event.source_url }}">
                                            </td>
                                            <td>
                                                <select name="type_id[{{ event.id }}]" class="form-control">
                                                    <option selected value="{{ event.type_id }}">{{ event.type_name }}</option>
                                                    {% for type in types %}
                                                        <option value="{{ type.id }}">{{ type.type_name }}</option>
                                                    {% endfor %}
                                                </select>
                                            </td>
                                            <td><input class="event_start_date date-picker" type="text" name="event_start_date[{{ event.id }}]" value="{{ event.event_start_date }}"></td>
                                            <td><input class="event_end_date date-picker" type="text" name="event_end_date[{{ event.id }}]" value="{{ event.event_end_date }}"></td>
                                            <td><input class="creation_date date-picker" type="text" name="event_date[{{ event.id }}]" value="{{ event.creation_date }}"></td>
                                            <td><input class="time_pick clockpicker" type="text" name="start_time[{{ event.id }}]" value="{{ event.start_time }}"></td>
                                            <td><input class="time_pick clockpicker" type="text" name="end_time[{{ event.id }}]" value="{{ event.end_time }}"></td>
                                            <td>
                                                <select name="venue_id[{{ event.id }}]" class="form-control">
                                                    <option selected value="{{ event.venue_id }}">{{ event.venue_name }}</option>
                                                    {% for venue in venues %}
                                                        <option value="{{ venue.id }}">{{ venue.venue_name }}</option>
                                                    {% endfor %}
                                                </select>
                                            </td>


                                        </tr>
                                    {% endfor %}
                                    </tbody>
                                </table>

                                <div class="form-group-lg" style="margin: 10px auto;">
                                    <button style="margin: 30px auto;" type="submit"
                                            class="btn btn-warning btn-block pull-left">
                                        Edit Selected Events
                                    </button>
                                </div>

                            </form>

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

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

{% endblock content %}

{% block scripts %}

    <!-- bootstrap-daterangepicker -->
    <script>
        $(document).ready(function () {
            $('.date-picker').daterangepicker({
                singleDatePicker: true,
                calender_style: "picker_4",
                locale: {

                    format: 'YYYY-MM-DD'
                }
            }, function (start, end, label) {
                console.log(start.toISOString(), end.toISOString(), label);
            });
        });
    </script>
    <!-- /bootstrap-daterangepicker -->

    <!-- clockpicker -->
    <script>
        $(document).ready(function () {
            $('.time_pick').clockpicker({
                placement: 'left',
                align: 'top',
                autoclose: true,
                'default': '21:30'
            });
        });
    </script>
    <!-- /clockpicker -->

{% endblock scripts %}

And the DB query - Retrieves 330 rows

public function getEvents()
    {
        $result = array();
        try {
            $stmt = $this->conn->prepare("
SELECT Events.id AS id, Events.title AS title, Events.description AS description, Events.source_url AS source_url, Events.type_id AS type_id, EventTypes.type_name AS type_name, Events.event_start_date AS event_start_date, Events.event_end_date AS event_end_date, Events.creation_date AS creation_date, TIME_FORMAT(start_time, '%H:%i') AS start_time, TIME_FORMAT(end_time, '%H:%i') AS end_time, Events.venue_id AS venue_id, Venues.venue_name AS venue_name
FROM $this->dbname.Events
INNER JOIN $this->dbname.EventTypes  
ON Events.type_id = EventTypes.id
INNER JOIN $this->dbname.Venues  
ON Events.venue_id = Venues.id
ORDER BY creation_date DESC, id DESC;");
            $stmt->execute();

            // set the resulting array to associative
            $stmt->setFetchMode(PDO::FETCH_ASSOC);
            $result = $stmt->fetchAll();

        } catch (PDOException $e) {
            return $errorMsg = $e->getMessage();
        }

        return $result;
    }

The query takes an average of 2.5 secs so this is not the problem. I think the problem is the loop in the html page that displays all the events one by one. Namely:

  {% for event in events %}

    <tr>
        <td>
            <input type="checkbox" name="events[]" value="{{ event.id }}"/>
        </td>
        <td>
            <input style="border: 1px solid lightblue;" type="text" name="title[{{ event.id }}]" value="{{ event.title}}">
        </td>
        <td>
            <textarea style="border: 1px solid lightblue;" class="mce_ta" type="text" name="description[{{ event.id }}]">{{ event.description }}</textarea>
        </td>
        <td>
            <input style="border: 1px solid lightblue;" type="text" name="source_url[{{ event.id }}]" value="{{ event.source_url }}">
        </td>
        <td>
            <select name="type_id[{{ event.id }}]" class="form-control">
                <option selected value="{{ event.type_id }}">{{ event.type_name }}</option>
                {% for type in types %}
                    <option value="{{ type.id }}">{{ type.type_name }}</option>
                {% endfor %}
            </select>
        </td>
        <td><input class="event_start_date date-picker" type="text" name="event_start_date[{{ event.id }}]" value="{{ event.event_start_date }}"></td>
        <td><input class="event_end_date date-picker" type="text" name="event_end_date[{{ event.id }}]" value="{{ event.event_end_date }}"></td>
        <td><input class="creation_date date-picker" type="text" name="event_date[{{ event.id }}]" value="{{ event.creation_date }}"></td>
        <td><input class="time_pick clockpicker" type="text" name="start_time[{{ event.id }}]" value="{{ event.start_time }}"></td>
        <td><input class="time_pick clockpicker" type="text" name="end_time[{{ event.id }}]" value="{{ event.end_time }}"></td>
        <td>
            <select name="venue_id[{{ event.id }}]" class="form-control">
                <option selected value="{{ event.venue_id }}">{{ event.venue_name }}</option>
                {% for venue in venues %}
                    <option value="{{ venue.id }}">{{ venue.venue_name }}</option>
                {% endfor %}
            </select>
        </td>


    </tr>
{% endfor %}

In addition to the pagination suggestion, you should definitely look at building those two selects once at the beginning (as a Twig block) and then reusing it for every iteration. This post tells you how to do that:

How can I reuse a block multiple times?

Food for thought:

  • Do you have an index in the database?
  • Do you really need the inner joins or does that just make things easier?
  • Couldn't you only load tinymce for an element when someone clicks it?
  • Couldn't you only load datePicker for an element when someone clicks it?

Is the machine you are using so slow?

Hope that helps, Taff

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM