Коли я повинен використовувати Inline vs. External Javascript?


129

Мені хотілося б знати, коли я повинен включати зовнішні сценарії або писати їх у формі з кодом html, з точки зору продуктивності та простоти обслуговування.

Яка загальна практика для цього?

Реальний сценарій - у мене є кілька html-сторінок, які потребують перевірки форми на стороні клієнта. Для цього я використовую плагін jQuery, який я включаю на всі ці сторінки. Але питання в тому, чи потрібно:

  • написати біти коду, які налаштовують цей сценарій вбудований?
  • включити всі біти в один файл, який є спільним для всіх цих HTML-сторінок?
  • включити кожен біт в окремий зовнішній файл, по одному для кожної html-сторінки?

Дякую.

Відповіді:


114

На той час, коли ця відповідь спочатку була розміщена (2008 р.), Правило було простим: весь сценарій повинен бути зовнішнім. Як для обслуговування, так і для роботи.

(Чому продуктивність? Тому що, якщо код окремий, він може легше кешуватися браузерами.)

JavaScript не належить до коду HTML, і якщо він містить спеціальні символи (наприклад <, >), він навіть створює проблеми.

У наш час масштабність веб-сайту змінилася. Зменшення кількості запитів стало обґрунтованим врахуванням через затримку подання декількох HTTP-запитів. Це робить відповідь складнішою: у більшості випадків наявність зовнішнього JavaScript все ж рекомендується. Але для певних випадків, особливо дуже невеликих фрагментів коду, вбудовування їх у HTML-код сайту має сенс.


6
@Nick: більшість проблем можна подолати. Хоча краще не створювати їх в першу чергу.
Конрад Рудольф

17
Іноді ви отримуєте кращі показники при вкладенні. Подивіться на джерело google.com . Вони знають, що роблять.
callum

13
@callum Google має різні випадки використання у порівнянні з 99,999999% веб-сайтів. Звичайно, вони вимірюють надзвичайно ретельно, і навіть найменша різниця має значення. Але тільки тому, що вони виявили, що в їх конкретному випадку використання вбудовування працює краще (можливо, тому що сценарій дуже часто змінюється?) Не означає, що ми можемо з цього вивести загальне правило, або навіть, що ми повинні ігнорувати «звичайне» правило (для зовнішніх сценаріїв).
Конрад Рудольф

8
@KonradRudolph - Погоджено, жодне загальне правило не повинно випливати з підходу Google. Я просто кажу, що це натяк на те, що, можливо, варто поставити під сумнів це правило у своїй відповіді. У будь-якому разі, я думаю, що причина Google в тому, щоб зменшити HTTP-запити, і це може принести користь понад 0,000001% сайтів. Ширина смуги пропускань стає все більшою, але час у зворотній бік залишається колишнім. Видалення цілого послідовного HTTP-запиту іноді краще, ніж кешування зовнішнього JS. Залежно від розміру вашого JS, звичайно.
callum

5
@callum Хоча це правда, питання щодо кешування все ще залишається і залишається важливим. Зменшення зворотних переходів важливо лише в тому випадку, якщо відвідувачі не повернуться (і тоді ви не отримаєте достатньо звернень до сторінки, щоб зробити це важливим) або якщо ваш вміст змінюється так часто, що кешування файлів скриптів не приносить користі.
Конрад Рудольф

31

Ремонтопридатність, безумовно, є причиною збереження їх зовнішністю, але якщо конфігурація є одноланковою (або взагалі коротшою, ніж HTTP-накладні витрати, які ви отримаєте для того, щоб зробити ці файли зовнішніми), краще зробити їх ефективними. Завжди пам’ятайте, що кожен запит HTTP генерує певні накладні витрати з точки зору часу виконання та трафіку.

Природно, все це стає неактуальним у момент, коли ваш код довший на пару рядків і насправді не характерний для однієї однієї сторінки. У той момент, коли ви хочете мати можливість використовувати цей код, зробіть його зовнішнім. Якщо ви цього не зробите, подивіться на його розмір і вирішіть тоді.


5
Це одна з моїх проблем. Наявність окремого HTTP-запиту на кілька рядків кодів видається марним.
Дан Бурцо,

Чи можете ви розмістити зразок конфігурації свого коду? IMO, якщо він містить менше 300 символів і абсолютно специфічний для сторінки, вставте його.
Хорст Гутманн

Це має бути головна відповідь imo
sgarcia.dev

@ Майте на увазі, що окремий запит відбувається лише з першого разу. Якщо ви очікуєте, що ваші користувачі завантажуватимуть сторінку не один раз, кешування зовнішньої (навіть на кілька рядків) явно швидше, ніж очікування байтів для цих кількох рядків по дроту на n = 2 + завантаженнях сторінки.
jinglesthula

@HorstGutmann, як це мати зовнішню допомогу файлу з ремонтом? Я особисто віддаю перевагу зовнішнім js, коли це можливо, але чи є щось об'єктивне, що полегшує підтримку?
jinglesthula

21

Екстерналізація JavaScript - одне з правил продуктивності Yahoo: http://developer.yahoo.com/performance/rules.html#external

Хоча жорстке правило про те, що завжди слід екстерналізувати сценарії, як правило, є хорошим ставкою, в деяких випадках ви можете вкласти деякі сценарії та стилі. Однак слід лише вбудовувати лише ті речі, які, на вашу думку, покращать ефективність роботи (тому що ви це виміряли).


1
Я думаю, що Yahoo також рекомендує додавати весь Javascript в один HTTP-дзвінок - це не означає, що сценарії повинні бути в одному файлі під час розробки,
Пол Шеннон,

Також, як зазначено вище, HTTP / 2 також змінює практику "1 дзвінок".
jinglesthula

19

Якщо ви дбаєте лише про продуктивність, більшість порад у цій темі виправдовуються неправильно, і все частіше помиляються в епоху SPA, де можна припустити, що сторінка марна без коду JS. Я витратив незліченну кількість годин, оптимізуючи час завантаження SPA-сторінки та перевіряючи ці результати за допомогою різних браузерів. Повсюдно підвищення продуктивності шляхом повторного оркестрування вашого html може бути досить драматичним.

Щоб досягти найкращої продуктивності, ви повинні думати про сторінки як двоступеневі ракети. Ці два етапи приблизно відповідають фазам <head>і <body>фазам, але думайте про них замість як <static>і <dynamic>. Статична частина - це, по суті, струнна константа, яку ти збиваєш у відповідь так швидко, наскільки це можливо. Це може бути трохи складним, якщо ви використовуєте багато проміжного програмного забезпечення, яке встановлює файли cookie (їх потрібно встановити перед надсиланням http-вмісту), але в принципі це просто промивання буфера відповідей, сподіваємось, перш ніж перейти до якогось шаблонного коду (бритва, php, тощо) на сервері. Це може здатися важким, але тоді я просто пояснюю це неправильно, бо це майже тривіально. Як ви вже здогадалися, ця статична частина повинна містити всі вбудовані та мінімізовані JavaScript. Це виглядало б щось на кшталт

<!DOCTYPE html>
     <html>
         <head>
             <script>/*...inlined jquery, angular, your code*/</script>
             <style>/* ditto css */</style>
         </head>
         <body>
             <!-- inline all your templates, if applicable -->
             <script type='template-mime' id='1'></script>
             <script type='template-mime' id='2'></script>
             <script type='template-mime' id='3'></script>

Оскільки вам не доведеться нічого надсилати цю частину по проводу, ви можете розраховувати, що клієнт почне отримувати це десь близько 5 мс + затримки після підключення до вашого сервера. Якщо припустити, що сервер досить близький, ця затримка може бути від 20 до 60 мс. Веб-браузери почнуть обробляти цей розділ, як тільки вони його отримають, і час обробки зазвичай домінуватиме час передачі з коефіцієнтом 20 або більше, який тепер є вашим амортизованим вікном для обробки <dynamic>частини сервера на стороні .

Браузер займає близько 50 мс (хром, відпочинок, можливо, на 20% повільніше), щоб обробити вбудований jquery + сигналр + кутовий + нг анімований + дотик + нг маршрути + лодаш. Це досить дивовижно саме по собі. Більшість веб-додатків мають менше коду, ніж усі популярні бібліотеки разом, але, скажімо, у вас так само багато, тому ми виграємо затримку + 100 мс обробки на клієнті (ця виграш затримки походить від другої частини передачі). До приходу другого фрагменту ми обробили всі js-коди та шаблони, і ми можемо почати виконувати перетворення дому.

Ви можете заперечити, що цей метод є ортогональним для вбудованої концепції, але це не так. Якщо ви замість того, щоб вбудовувати посилання на cdns або власні сервери, браузеру доведеться відкрити інше з'єднання та затримати виконання. Оскільки це виконання в основному безкоштовне (так як сторона сервера спілкується з базою даних), повинно бути зрозуміло, що всі ці стрибки коштуватимуть дорожче, ніж взагалі не робити стрибків. Якби виникла думка браузера, яка сказала, що зовнішній js виконується швидше, ми могли б виміряти, який фактор домінує. Мої вимірювання показують, що додаткові запити вбивають ефективність на цьому етапі.

Я багато працюю з оптимізацією додатків SPA. Людям властиво думати, що обсяг даних - це велика справа, тоді як затримка правди і виконання часто домінують. Перераховані я перераховані бібліотеки містять до 300 кбіт даних, і це всього 68 кбіт gzipped, або 200 м завантаження на телефон 2mbit 3g / 4g, що є саме затримкою, яка знадобиться на тому ж телефоні, щоб перевірити, чи є у нього однакові дані у своєму кеші вже, навіть якщо він був кешований проксі-сервісом, оскільки податок на затримку мобільного зв'язку (затримка від телефону до башти) все ще діє. Тим часом підключення на робочому столі, які мають нижчу затримку першого переходу, як правило, мають більшу пропускну здатність.

Коротше кажучи, саме зараз (2014 р.) Найкраще вкладати всі сценарії, стилі та шаблони.

РЕДАКТУВАТИ (МАЙ 2016)

Оскільки додатки JS продовжують зростати, а деякі мої корисні навантаження тепер накопичують до 3+ мегабайт мінімізованого коду, стає очевидним, що принаймні загальні бібліотеки більше не повинні бути вказівними.


Я не отримав те, що зараз є вашим амортизованим вікном для обробки серверної частини <-динамічної> частини - Сервер обробляє все, що йому потрібно, і лише потім обслуговує весь наданий html (head + body), яку іншу обробку сервера потрібно після цього?
BornToCode

@BornToCode Ідея полягає у тому, щоб дати клієнтові щось робити, в той же час, коли сторона сервера має щось робити. Оскільки клієнтські бібліотеки потрібно інтерпретувати - краще розпочати цей процес, перш ніж робити будь-які обчислення на сервері. Амортизоване вікно - це час, який клієнту потрібно обробити JS. Ви отримуєте це вікно безкоштовно, якщо оркеструєте двоступеневу ракету.
Глено


9

Насправді, існує досить вагомий випадок для використання вбудованого JavaScript. Якщо js досить малий (однолінійний), я, як правило, віддаю перевагу вбудованому JavaScript через два фактори:

  • Місцевість . Немає необхідності переходити до зовнішнього файлу, щоб перевірити поведінку деяких javascript
  • AJAX . Якщо ви оновлюєте деякий розділ сторінки через AJAX, ви можете втратити всі ваші DOM-обробники (onclick тощо) для цього розділу, залежно від того, як ви їх пов’язали. Наприклад, за допомогою jQueryви можете або скористатися методами liveабо delegateметодами, щоб обійти це, але я вважаю, що якщо js досить малий, то краще просто ввести його в рядок.

5

Ще одна причина, чому завжди слід використовувати зовнішні скрипти, - це простіший перехід до політики безпеки вмісту (CSP) . За замовчуванням CSP забороняється використовувати всі вбудовані сценарії, роблячи ваш сайт більш стійким до XSS-атак.


4

Я б подивився на необхідний код і розділив його на стільки окремих файлів, скільки потрібно. Кожен js-файл містив би лише один "логічний набір" функцій тощо, наприклад. один файл для всіх функцій, пов'язаних з входом.

Потім під час розробки сайту на кожній html-сторінці ви включаєте лише ті, які потрібні. Під час роботи з веб-сайтом ви можете оптимізувати, комбінуючи кожен js-файл, який потрібна сторінка, в один файл.


4

Єдиний захист, який я можу запропонувати для вбудованого javascipt, - це те, що при використанні сильно набраних поглядів з .net MVC ви можете звернутися до змінних c # середнього javascript, які я вважаю корисними.


3

Три міркування:

  • Скільки вам потрібно коду (іноді бібліотеки є першокласним споживачем)?
  • Специфіка: чи функціонує цей код лише у контексті цього конкретного документа чи елемента?
  • Кожен код у документі, як правило, робить його довшим і тим самим повільніше. Крім того, що SEO-міркування дозволяють зрозуміти, що ви мінімізуєте внутрішній сценарій ...

2

Зовнішні сценарії також простіше налагоджувати за допомогою Firebug. Мені подобається модульний тест на JavaScript і наявність у нього зовнішньої допомоги. Я ненавиджу бачити JavaScript у PHP-коді та HTML, це здається мені великим безладом.


2

Що стосується збереження JavaScript зовнішнім:

Нещодавно ASP.NET 3.5SP1 представив функціонал для створення ресурсу Composite script (об'єднайте купу файлів js в один). Ще однією перевагою є те, коли компресія веб-сервера увімкнена, завантаження одного трохи більшого файлу матиме кращий коефіцієнт стиснення, ніж багато менших файлів (також менше http overhead, roundtrip тощо ...). Я думаю, що це економить на початковому завантаженні сторінки, а потім кешує браузер, як зазначено вище.

Окрім ASP.NET, цей скріншот пояснює переваги більш докладно: http://www.asp.net/learn/3.5-SP1/video-296.aspx


2

Ще одна прихована перевага зовнішніх скриптів полягає в тому, що ви можете легко запустити їх через перевірку синтаксису, як jslint . Це може врятувати вас від безлічі сердечних, важко знайдених помилок IE6.


1

У вашому сценарії це звучить, як записування зовнішніх матеріалів у один файл, що ділиться між сторінками, було б добре для вас. Я згоден з усім, що було сказано вище.


1

Під час раннього складання прототипів тримайте свій код в Інтернеті для вигоди швидкої ітерації, але обов'язково зробіть це зовнішнім до моменту досягнення виробництва.

Я б навіть наважився сказати, що якщо ви не можете розмістити весь Javascript зовні, то у вас поганий дизайн під вашими руками, і вам слід переробляти свої дані та сценарії.


1

Google включив час завантаження в свої показники ранжирування сторінок; якщо ви вкладете багато, павукам буде потрібно довше повзати через вашу сторінку, це може вплинути на рейтинг вашої сторінки, якщо вам доведеться багато включити. у будь-якому випадку різні стратегії можуть впливати на ваш рейтинг.


1

добре, я думаю, що вам слід використовувати вбудований текст під час створення веб-сайтів на одній сторінці, оскільки сценарії не потрібно буде ділити на декілька сторінок


-3

Завжди намагайтеся використовувати зовнішні Js, оскільки вбудований js завжди важко підтримувати.

Крім того, професійно потрібно використовувати зовнішній js, оскільки більшість розробників рекомендує використовувати js зовнішньо.

Я сам використовую зовнішній js.


2
Професійно потрібно? Чому? Хто це каже?
Сія
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.