Рендеринг JavaScript на уровне сервера. Хорошая или плохая идея? - PullRequest
4 голосов
/ 17 мая 2010

Теперь вики-сообщество!

Сначала я хочу уточнить : Это не вопрос по отношению к Javascript на стороне сервера или к запуску Javascript на стороне сервера. Это вопрос относительно рендеринга кода Javascript (который будет выполняться на стороне клиента) из кода на стороне сервера.

Сказав это, взгляните на приведенный ниже код ASP.net, например:

hlRemoveCategory.Attributes.Add("onclick", "return confirm('Are you sure you want to delete this?');")

Это предписывает клиентское событие onclick на стороне сервера.

В отличие от написания Javascript на стороне клиента:

$('a[rel=remove]').bind('click', function(event) {
    return confirm('Are you sure you want to delete this?');
}

Теперь Я хочу задать вопрос: : В чем преимущество рендеринга javascript из кода на стороне сервера? Или наоборот?

Лично я предпочитаю второй способ подключения пользовательского интерфейса / поведения на стороне клиента к элементам HTML по следующим причинам:

  • Серверная сторона делает все, что нужно, включая проверку данных, делегирование событий и т. Д .; и
  • То, что на стороне сервера воспринимается как событие, не обязательно совпадает с процессом на стороне клиента. то есть, на стороне клиента гораздо больше событий (просто посмотрите на пользовательские события); и
  • Что происходит на стороне клиента и на стороне сервера, во время события может быть совершенно неактуальным и не связанным; и
  • То, что когда-либо происходит на стороне клиента, происходит на стороне клиента, не нужно , чтобы сервер знал. Сервер должен обрабатывать и запускать то, что ему дано, то, как процесс оживает, на самом деле не им решать в случае событий на стороне клиента; и так далее и тому подобное.

Это мои мысли, очевидно . Я хочу знать, что думают другие, и были ли какие-либо дискуссии на эту тему.

Темы, ответвляющиеся от этого аргумента, могут достигать:

  • Управление кодом: проще ли рендерить все со стороны сервера?
  • Разделение проблем: легче ли отделить логику на стороне клиента от логики на стороне сервера?
  • Эффективность: что более эффективно с точки зрения кодирования и работы?

В конце дня я пытаюсь заставить свою команду перейти ко второму подходу. В этой команде много старых парней, которые боятся этой перемены. Я просто хочу убедить их в правильных фактах и ​​статистике.

Дайте мне знать ваши мысли.

ОБНОВЛЕНИЕ1: Похоже, у всех нас, кто участвовал в этом посте, есть общая мысль; Приятно знать, что есть другие, которые думают одинаково. Теперь чтобы убедить ребят;) Спасибо всем.

Ответы [ 5 ]

3 голосов
/ 17 мая 2010

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * '' '' '' * '

  • вы потеряете кэширование на стороне клиента, которое получилось бы, если бы javascript находился в отдельном js-файле
  • если вам нужно изменить свой javascript, вы должны перекомпилировать (экстраполируйте это на то, что происходит после того, как вы выпустили свой продукт: если вам нужно перекомпилировать, то вам нужно перераспределить двоичные файлы вместо просто измененного файла js)
  • проще использовать отладчик VS, если javascript находится в отдельном файле; Вы можете просто установить точку останова в этом файле, если вы генерируете сторону сервера кода, тогда вам нужно использовать функцию запуска документов, найти сгенерированный код, а затем добавить точку останова, и эту точку останова необходимо добавлять каждый раз, когда вы - запустите ваше приложение. Исходя из этого, если код находится в отдельном файле, вы можете просто настроить код javascript, F5 на странице браузера и продолжить отладку без остановки и перезапуска отладчика.

Следует отметить, что иногда вам нужно вставить js-код с сервера - например, если основная часть вашего кода находится в отдельном js-файле и вам необходимо вставить управляющие идентификаторы на страницу, чтобы этот код работал с , Просто попытайтесь избежать этой ситуации, если это возможно.

3 голосов
/ 17 мая 2010

Ваш второй пример значительно превосходит первый. Javascript - это ваш уровень поведения, который должен быть отделен от вашей семантической разметки (контент) и CSS (презентация). Есть несколько причин, по которым это лучше архитектуры:

  • Поощряет прогрессивное улучшение. Как вы упомянули, внутренний код должен работать правильно в отсутствие JS. Вы не можете положиться на своих клиентов, имеющих JS. Таким образом, вы создадите его один раз без JS, а затем сможете улучшить работу с JS (например, добавив проверку на стороне клиента, а также проверку на стороне сервера, чтобы клиент мог получить мгновенную обратную связь)
  • Очиститель разметки. Обычно уменьшенный размер загрузки. Один повторно используемый селектор в отдельном файле JS, который можно кэшировать и совместно использовать между страницами и обработчиком для каждого элемента.
  • Все ваши JS в одном повторно используемом месте. например если ваш код открывает всплывающее окно и вы решили изменить размеры окна, вы измените его один раз в коде в файле JS вместо необходимости изменять его для каждого отдельного встроенного обработчика.

Есть много других аргументов и причин, но они должны помочь вам начать ...

Кроме того, из вашего примера видно, что у вас есть нормальная ссылка в вашем документе, которая может удалить контент. Это также было бы плохой практикой. Все, что удаляет или обновляет контент, должно выполняться по запросу POST (не GET). Так что это должно быть результатом отправки формы. В противном случае, например googlebot может случайно удалить весь ваш контент, просто просканировав вашу страницу (а роботы поисковых систем не запускают JS, поэтому ваше оповещение здесь не поможет)

1 голос
/ 17 мая 2010

Похоже, вы уже знаете, что делать. Рендеринг на стороне сервера - плохая идея.

Простое рассуждение о том, что вы Javascript, живет как на серверных страницах, так и в отдельных файлах Javascript (при условии, что вы вообще используете Javascript). Это может стать отладочным кошмаром, чтобы исправить вещи, когда все повсюду.

Если бы вы не использовали какой-либо другой Javascript, кроме того, что генерируют сценарии на стороне сервера, он, вероятно, был бы хорошим и управляемым (забудьте, что говорит ненавязчивое движение). Во-вторых, если у вас есть 100 ссылок на странице, вы будете повторять этот же код в 100 местах. Повторение - еще один кошмар обслуживания и отладки. Вы можете обрабатывать все ссылки на всех страницах с помощью одного обработчика событий и одного атрибута. Это даже не нуждается во второй мысли.

<Rant>

Нелегко разделить HTML и Javascript, и даже CSS, особенно если вы хотите использовать AJAX или UI. Чтобы получить полное разделение, нам нужно перейти к модели настольных приложений, где весь код переднего плана генерируется на стороне клиента программно с использованием Javascript, и все взаимодействие с сервером получает ограничен чистым обменом данными.

Большая часть восходящей связи (клиент-сервер) - это просто обмен данными, но не нисходящая связь. Многие серверные скрипты генерируют HTML, объединяют его с данными и выплевывают обратно. Это хорошо, пока сервер остается в команде создания представлений HTML. Но когда навороченный Javascript приходит на борт и начинает добавлять строки в таблицы, и div для комментариев, точно копируя существующую структуру HTML, мы создали две точки, в которых генерируется разметка.

$(".comments").append($("<div>", {
    "id": "123",
    "class": "comment",
    "html": "I would argue this is still bad practice..."
}));

Может быть, это не такой уж страшный кошмар (в зависимости от масштаба), но это может быть и серьезной проблемой. Теперь, если мы изменим структуру комментариев, это нужно сделать в двух местах: на стороне сервера и в шаблонах, где изначально создается контент, и на стороне Javascript, которая динамически добавляет комментарии после загрузки страницы.

Второй пример касается приложений, которые используют перетаскивание. Если вы можете перетаскивать элементы div вокруг страницы, их нужно будет удалить из обычного потока страниц и расположить абсолютно или относительно с точными координатами. Теперь, поскольку мы не можем заранее создать классы для всех возможных координат (и это было бы глупо пытаться), мы в основном внедряем стили непосредственно в элемент. Наш HTML тогда выглядит так:

<div style="position: absolute; top: 100px; left: 250px;">..</div>

Мы испортили наши красивые семантические страницы, но это нужно было сделать.

</Rant>

Семантическое и поведенческое разделение в стороне, я бы сказал, в основном сводится к повторению. Вы повторяете код без необходимости. Несколько слоев обрабатывают одну и ту же логику. Можно ли засыпать все это в один слой или сократить все повторения.

0 голосов
/ 17 мая 2010

Вы и другие люди, отвечающие на этот вопрос, уже перечислили причины, по которым лучше не делать так, чтобы код на стороне сервера выплевывал внутренние атрибуты событий в документы.

Обратная сторона медали такова: быстрая и простая (по крайней мере, в краткосрочной перспективе).

ИМО, это не близко к перевесу минусов подхода, но это причина.

0 голосов
/ 17 мая 2010

Для кода в вашем примере это не имеет большого значения. В коде не используется никакая информация, доступная только на стороне сервера, поэтому связать событие в коде на стороне клиента так же просто.

Иногда вы хотите использовать некоторую информацию, которая доступна на стороне сервера, чтобы решить, следует ли добавить событие или нет, или создать код для события, например:

if (categoryCanBeDeleted) {
  hlRemoveCategory.Attributes.Add(
    "onclick",
    "return confirm('Are you sure you want to delete the " + categoryType + "?');"
  );
}

Если вы сделаете это на стороне клиента, вы должны как-то поместить эту информацию на страницу, чтобы код на стороне клиента также имел к ней доступ.

...