Цель
В этой статье мы объясним, как реализовать страницу с минимальной загрузкой, используя фреймворк Flask и немного JavaScript.
Страница загрузки будет выглядеть следующим образом:
Для тех, кто не хочет читать мой монолог, весь код доступен здесь.
Для самых смелых, начнем.
Фляжная архитектура
В этом примере я использую довольно распространенную архитектуру приложения Flask:
Файл app.py содержит два маршрута Flask: @app.route('/') и @app.route('/loading/') требуется для нашего отображения.
Корневой маршрут (😂), определенный как «/», отображает шаблон загрузчика с именем loading.html, используя простейший способ Flask:
@app.route('/') def default(): return render_template('loading.html')
Маршрут «/loading/» будет описан позже.
NB: Если этот фрагмент кода для вас непонятен, обратитесь к замечательной Документации по Flask.
Рендеринг загрузчика с использованием HTML и CSS
Файл loading.html представляет собой минимальное средство отображения, использующее пустой тег ‹div›‹/div›, например :
<div class="loader center"></div>
для отображения объекта загрузчика, определенного в файле loader.css:
/* helper to center elements */ .center { width: 100px; height: 100px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; } /* outer part */ .loader { width: 100px; height: 100px; background: #fff; border: solid; border-radius: 50%; animation: roll 1.5s ease-in-out infinite alternate; } /* inner part */ .loader:after{ content:""; position: absolute; inset: 10px; border-radius: 50%; border: 5px solid ; border-color: #ff3d00 transparent; } /* animation */ @keyframes roll { 0% { transform: translateX(-200%) rotate(0deg) ; } 100% { transform: translateX(200%) rotate(360deg); } }
На данный момент ничего сумасшедшего, запустив приложение flask и перейдя по маршруту «/», уже будет отображаться загрузчик, который вечно катится слева направо.
Но как нам загружать данные, пока этот шар катится, и как отображать их, когда наш трудоемкий процесс завершен? Что ж, здесь нас спасает JavaScript.
Использование JavaScript для запуска функций, требующих много времени
Если вы внимательно посмотрите на файл loading.html, вы увидите импорт файла сценария в теге ‹head›‹/head› под названием загрузка.js :
<script type="text/javascript" src="{{ url_for('static', filename='js/loading.js') }}"></script>
Вот где происходит волшебство, в этом файле есть только одна функция, которая вызывается каждый раз при рендеринге файла loading.html, функция load() определена следующим образом:
function load() { fetch("loading").then(async (template) => {document.body.innerHTML = await template.text();}) }
Этот метод извлекает маршрут загрузки, определенный в файле app.py (см. выборка документации на MDN):
@app.route('/loading/') def loading(): time.sleep(5) # time consuming functions return render_template("loaded.html")
Эта выборка запускает функцию loading(), в которой должен быть вызван трудоемкий процесс. В нашем случае вызов time.sleep(5) имитирует пятисекундный процесс (задержка загрузки).
После завершения обработки и окончательного отображения шаблона loaded.html выполняется следующая команда:
async (template) => {document.body.innerHTML = await template.text();}
Он заменяет полный внутренний HTML-код текущего шаблона (loading.htmlотображаемый по маршруту «/») на loaded.html шаблон.
NB: Если страница обновляется, загрузчик будет отображаться, и функция, требующая много времени, снова запустится.
Заключение
В двух словах:
- Маршрут «\» отображает загрузчик при отображении шаблона loading.html
- При каждом отображении шаблона loading.html функция JavaScript обрабатывает требующие много времени функции.
- По завершении обработки HTML-код текущей страницы заменяется шаблоном loaded.html.
Вот и все ! Я надеюсь, что эта краткая статья дала вам то, что вы искали, и, опять же, не стесняйтесь использовать этот код в своем собственном приложении Flask!
Примечание: можно было бы создать новый маршрут к GET (например,'/loaded/'), который отображаетloaded.html после завершения загрузки, но пользователь окажется на новой странице, и перезагрузка этой страницы не приведет к повторному запуску процесса загрузки.
В качестве упражнения я предлагаю вам реализовать это другое решение самостоятельно, чтобы указать на это ограничение 😉.