<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Matteo Cargnelutti</title>
    <description>The latest articles on DEV Community by Matteo Cargnelutti (@macargnelutti).</description>
    <link>https://dev.to/macargnelutti</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F141220%2F23f06b80-7cac-4898-91da-ded0b76e70af.jpg</url>
      <title>DEV Community: Matteo Cargnelutti</title>
      <link>https://dev.to/macargnelutti</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/macargnelutti"/>
    <language>en</language>
    <item>
      <title>Server-side JavaScript a decade before Node.js with Netscape LiveWire</title>
      <dc:creator>Matteo Cargnelutti</dc:creator>
      <pubDate>Sun, 12 Sep 2021 15:08:21 +0000</pubDate>
      <link>https://dev.to/macargnelutti/server-side-javascript-a-decade-before-node-js-with-netscape-livewire-l72</link>
      <guid>https://dev.to/macargnelutti/server-side-javascript-a-decade-before-node-js-with-netscape-livewire-l72</guid>
      <description>&lt;p&gt;The year is 1996. JavaScript is less than a year old, making its grand public debut with the release of Netscape Navigator 2.0 to &lt;a href="https://webdevelopmenthistory.com/1996-javascript-annoyances-and-meeting-the-dom/"&gt;a both intrigued and somewhat bewildered web development community&lt;/a&gt;. We are at the very beginning of what would become &lt;a href="https://en.wikipedia.org/wiki/Browser_wars#First_Browser_War_(1995%E2%80%932001)"&gt;"The First Browser War"&lt;/a&gt;: how JavaScript evolved and grew in that context is a story often told, &lt;strong&gt;but did you know that JavaScript was also used as a server-side scripting language as early as 1996?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Today we're going to have a look at &lt;strong&gt;Netscape LiveWire&lt;/strong&gt;, an extension of &lt;em&gt;"Netscape Enterprise Server"&lt;/em&gt; that made &lt;strong&gt;writing server-side JavaScript applications possible more than 10 years before it was cool.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The dawn of server-side J(ava)Script
&lt;/h2&gt;

&lt;p&gt;While Netscape and Microsoft were distributing their browser free of charge, both companies were also in the business of  selling enterprise-level software to companies and institutions looking for a &lt;em&gt;"one stop shop"&lt;/em&gt; solution to their web server and web development needs. This constituted an important part of Netscape's business model, and something Microsoft invested in as part of their &lt;a href="https://www.wired.com/2010/05/0526bill-gates-internet-memo/"&gt;newfound interest for the internet&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We therefore had Microsoft on one side with the &lt;em&gt;"Internet Information Services"&lt;/em&gt; (IIS) suite, featuring their &lt;a href="https://en.wikipedia.org/wiki/Active_Server_Pages"&gt;&lt;em&gt;"Active Server Pages"&lt;/em&gt; (ASP)&lt;/a&gt; server-side scripting technology, and &lt;em&gt;"Netscape Enterprise Server"&lt;/em&gt; with its &lt;strong&gt;LiveWire&lt;/strong&gt; application development solution on the other.&lt;/p&gt;

&lt;p&gt;While ASP did support &lt;strong&gt;JScript&lt;/strong&gt; &lt;em&gt;(Microsoft's early implementation of JavaScript)&lt;/em&gt;, it was only one of the 3 languages supported, alongside &lt;strong&gt;VBScript&lt;/strong&gt; and &lt;strong&gt;PerlScript&lt;/strong&gt;. Netscape chose a different approach and went &lt;em&gt;"all in"&lt;/em&gt; with server-side JavaScript, which was the centerpiece of LiveWire. &lt;/p&gt;




&lt;h2&gt;
  
  
  How did LiveWire's server-side JavaScript work?
&lt;/h2&gt;

&lt;p&gt;Looking back at &lt;a href="https://docs.oracle.com/cd/E19957-01/816-6411-10/contents.htm"&gt;how LiveWire worked&lt;/a&gt; from today's perspective is both fascinating and slightly disorientating. We're only a decade - but galaxies away - from &lt;strong&gt;Node.js&lt;/strong&gt; and its event loop-based, single threaded model. Netscape's server-side implementation of JavaScript was much more of an HTML preprocessor than a multi-purpose runtime, not dissimilar to early-days PHP in some of its inclinations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Everything starts with the &lt;code&gt;&amp;lt;server&amp;gt;&lt;/code&gt; tag
&lt;/h3&gt;

&lt;p&gt;LiveWire introduced a &lt;code&gt;&amp;lt;server&amp;gt;&lt;/code&gt; tag, the likes of ASP's &lt;code&gt;&amp;lt;%&lt;/code&gt; and PHP's &lt;code&gt;&amp;lt;?php&lt;/code&gt; delimiters, used to determine which parts of a given HTML file contained JavaScript logic that needed to be processed on the server before being sent to the client. A global &lt;code&gt;write()&lt;/code&gt; function was used conjointly to &lt;em&gt;"print"&lt;/em&gt; content on the page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Welcome to mid-90s HTML. 
Tags are SCREAMED, because everybody is very excited about THE INTERNET. --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;HTML&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;HEAD&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;TITLE&amp;gt;&lt;/span&gt;My awesome web app&lt;span class="nt"&gt;&amp;lt;/TITLE&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/HEAD&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;BODY&amp;gt;&lt;/span&gt;  
    &lt;span class="nt"&gt;&amp;lt;H1&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;SERVER&amp;gt;&lt;/span&gt;
      /* This tag and its content will be processed on the server side,
      and replaced by whatever is passed to `write()` before being sent to the client. */
      if(client.firstname != null) {
        write("Hello " + client.firstname + " !")  
      }
      else {
        write("What is your name?")
      }
      &lt;span class="nt"&gt;&amp;lt;/SERVER&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/H1&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;FORM&lt;/span&gt; &lt;span class="na"&gt;METHOD=&lt;/span&gt;&lt;span class="s"&gt;"post"&lt;/span&gt; &lt;span class="na"&gt;ACTION=&lt;/span&gt;&lt;span class="s"&gt;"app.html"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;P&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;LABEL&lt;/span&gt; &lt;span class="na"&gt;FOR=&lt;/span&gt;&lt;span class="s"&gt;"firstname"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Your name&lt;span class="nt"&gt;&amp;lt;/LABEL&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;INPUT&lt;/span&gt; &lt;span class="na"&gt;TYPE=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;NAME=&lt;/span&gt;&lt;span class="s"&gt;"firstname"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;        
      &lt;span class="nt"&gt;&amp;lt;/P&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;P&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;INPUT&lt;/span&gt; &lt;span class="na"&gt;TYPE=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt; &lt;span class="na"&gt;VALUE=&lt;/span&gt;&lt;span class="s"&gt;"Send"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/P&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/FORM&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/BODY&amp;gt;&lt;/span&gt;  
&lt;span class="nt"&gt;&amp;lt;/HTML&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To prevent unnecessary cluttering of the HTML files, backquotes could be used as a shorthand for the combination of &lt;code&gt;&amp;lt;server&amp;gt;&lt;/code&gt; and the &lt;code&gt;write()&lt;/code&gt; function, making for a smaller footprint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Long form: --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;H1&amp;gt;&amp;lt;SERVER&amp;gt;&lt;/span&gt;write("Hello " + client.firstname + " !")&lt;span class="nt"&gt;&amp;lt;/SERVER&amp;gt;&amp;lt;/H1&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Short hand: --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;H1&amp;gt;&lt;/span&gt;`"Hello " + client.firstname + " !"`&lt;span class="nt"&gt;&amp;lt;/H1&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The &lt;code&gt;jsac&lt;/code&gt; compiler and &lt;code&gt;.web&lt;/code&gt; files
&lt;/h3&gt;

&lt;p&gt;LiveWire apps required a compilation step. &lt;a href="https://docs.oracle.com/cd/E19957-01/816-6411-10/appdev.htm#1046520"&gt;Using the &lt;code&gt;jsac&lt;/code&gt; compiler&lt;/a&gt;, users had to merge all of the app's HTML and JavaScript resources into a single &lt;code&gt;.web&lt;/code&gt; file. The idea was that every HTML file added to this bundle was to become an entry point for the app, accessible via a url, while loose JavaScript files were meant to be shared resources, allowing to define global functions that could be used in &lt;code&gt;&amp;lt;server&amp;gt;&lt;/code&gt; calls across multiple HTML files. &lt;/p&gt;

&lt;p&gt;The resulting &lt;code&gt;.web&lt;/code&gt; files contained bytecode that could then be executed by Netscape's JavaScript runtime, waiting for HTTP requests to come in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Example: Compiling a LiveWire app made of a single HTML file.&lt;/span&gt;
jsac &lt;span class="nt"&gt;-i&lt;/span&gt; app.html &lt;span class="nt"&gt;-o&lt;/span&gt; app.web

&lt;span class="c"&gt;# Example: Compiling a LiveWire app made of multiple HTML and JS files.&lt;/span&gt;
&lt;span class="c"&gt;# The `-f` option targets a file containing references to all the files that need to be bundled together.&lt;/span&gt;
jsac &lt;span class="nt"&gt;-f&lt;/span&gt; files_list.txt &lt;span class="nt"&gt;-o&lt;/span&gt; app.web 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Netscape's runtime was &lt;strong&gt;multi-threaded&lt;/strong&gt; and allowed for sharing objects between threads of a given application. Shared objects could be accessed and modified by any thread, which made it easy to share state between clients but also came with important thread safety risks. &lt;a href="https://docs.oracle.com/cd/E19957-01/816-6411-10/sessmgmt.htm#1012796"&gt;A locking mechanism was available, but not automatically enforced&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What were some of its core features?
&lt;/h2&gt;

&lt;p&gt;LiveWire was built for &lt;em&gt;"enterprise"&lt;/em&gt; customers, and some of the architectural decisions that were made could be explained by this constraint. &lt;/p&gt;

&lt;p&gt;There was for example a clear focus on &lt;strong&gt;database connectivity&lt;/strong&gt;, &lt;strong&gt;interoperability with Java classes&lt;/strong&gt; &lt;strong&gt;and native libraries&lt;/strong&gt; &lt;em&gt;(LiveConnect and &lt;code&gt;jsacca&lt;/code&gt;)&lt;/em&gt;, all of which making it easier for potential clients to integrate LiveWire into their existing infrastructure and codebases, at least in theory.&lt;/p&gt;

&lt;p&gt;Netscape's server-side JavaScript implementation also came with APIs for &lt;strong&gt;session management&lt;/strong&gt;, &lt;strong&gt;forms processing&lt;/strong&gt;,  &lt;strong&gt;file system access&lt;/strong&gt;, and even &lt;strong&gt;sending emails&lt;/strong&gt; in later versions, which made of LiveWire a seemingly complete and viable solution for backend development.  &lt;/p&gt;




&lt;h2&gt;
  
  
  Was LiveWire a success?
&lt;/h2&gt;

&lt;p&gt;LiveWire was a very interesting and innovative piece of software, but never came come close to becoming the gold standard of &lt;em&gt;"professional"&lt;/em&gt; server-side development of the late nineties. While it is hard to pinpoint a single reason why that was the case, here are a few clues, in no particular order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Having to compile and bundle everything, including HTML content, made for a somewhat cumbersome developer experience&lt;/strong&gt;. &lt;a href="https://philip.greenspun.com/wtr/livewire.html"&gt;This review of LiveWire's development cycle by Philip Greenspun&lt;/a&gt; describes these woes in great detail. LiveWire's direct competitor, Microsoft ASP, didn't require a compilation step.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript was a very young language at the time.&lt;/strong&gt; It still had to prove itself, and hadn't yet become popular enough to have a large pool of developers and libraries available. 
This &lt;a href="http://sunsite.uakom.sk/sunworldonline/swol-08-1999/swol-08-webmaster.html"&gt;article by R. Allen Wyke from 1999&lt;/a&gt; is a good example of how, even a few years later, JavaScript had to be advocated for. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Netscape didn't necessarily invest as much as its competitors&lt;/strong&gt;, and LiveWire quickly lagged behind in terms of features. &lt;a href="https://www.chicagotribune.com/news/ct-xpm-1997-07-18-9801160234-story.html"&gt;This 1997 article from the Chicago Tribune&lt;/a&gt; shows how LiveWire started to lag behind the competition, a year after its launch.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What did LiveWire become?
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;"Enterprise-grade"&lt;/em&gt; software means long term support. Through successive acquisitions, &lt;a href="https://en.wikipedia.org/wiki/Oracle_iPlanet_Web_Server#Release_History"&gt;&lt;em&gt;"Netscape Enterprise Server"&lt;/em&gt; was rebranded multiple times&lt;/a&gt; and merged with other technologies, which explains why &lt;a href="https://docs.oracle.com/cd/E19957-01/816-6411-10/contents.htm"&gt;LiveWire's documentation&lt;/a&gt; can be found on Oracle's website. &lt;/p&gt;

&lt;p&gt;It is a bit difficult to trace exactly how LiveWire evolved in that context, and figure out when exactly it was discontinued. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Its legacy is an interesting one:&lt;/strong&gt; while it is not hard to find comments on the internet about how seemingly hard and unpleasant it was to work with this technology &lt;a href="https://stackoverflow.com/questions/18350910/netscape-enterprise-server-and-server-side-javascript-ssjs-vs-node-js/26321883#26321883"&gt;(1)&lt;/a&gt; &lt;a href="https://philip.greenspun.com/wtr/livewire.html#:~:text=Reader's%20Comments"&gt;(2)&lt;/a&gt; &lt;a href="https://philip.greenspun.com/wtr/dead-trees/53012.htm#:~:text=Netscape%20LiveWire"&gt;(3)&lt;/a&gt;, it remains an important  piece of JavaScript's history, as it was one of the very first attempts at making the language live outside the browser and compete on the &lt;em&gt;"for business"&lt;/em&gt; market of software development solutions.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>history</category>
    </item>
    <item>
      <title>HTML postmortem: frameset and its legacy</title>
      <dc:creator>Matteo Cargnelutti</dc:creator>
      <pubDate>Mon, 13 Jan 2020 03:35:36 +0000</pubDate>
      <link>https://dev.to/macargnelutti/html-postmortem-frameset-and-its-legacy-5h83</link>
      <guid>https://dev.to/macargnelutti/html-postmortem-frameset-and-its-legacy-5h83</guid>
      <description>&lt;p&gt;Ever wondered where the &lt;code&gt;target="_blank"&lt;/code&gt; attribute came from, what it means and why it behaves the way it does? A little bit of HTML history might help with that 🤓📖.&lt;/p&gt;

&lt;p&gt;Part of the &lt;a href="https://www.w3.org/TR/html4/present/frames.html" rel="noopener noreferrer"&gt;HTML 4 standard&lt;/a&gt;, &lt;code&gt;&amp;lt;frame&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;frameset&amp;gt;&lt;/code&gt; were all the rage in the late 90s and early 00s. At a time where &lt;strong&gt;CSS&lt;/strong&gt; wasn't commonly used for layout and &lt;a href="https://en.wikipedia.org/wiki/HTML_editor#WYSIWYG_HTML_editors" rel="noopener noreferrer"&gt;WYSIWYG Web editors&lt;/a&gt; were very popular, &lt;code&gt;&amp;lt;frameset&amp;gt;&lt;/code&gt; offered a simple way of building somewhat complex layouts by allowing to split the browser's window into &lt;strong&gt;a grid of separate HTML documents&lt;/strong&gt;. In a way, they were the old web's solution to challenges the web development community still faces today, such as code modularity and bandwidth usage reduction, and came with many important limitations and side effects we'll go over in this article.&lt;/p&gt;

&lt;p&gt;Let's explore together how this now-deprecated web dinosaur that is &lt;code&gt;&amp;lt;frameset&amp;gt;&lt;/code&gt; worked, what were some of its limitations, and what its legacy to the modern web is.&lt;/p&gt;




&lt;h2&gt;
  
  
  How did it work?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;frameset&amp;gt;&lt;/code&gt; tag took the place of the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag: it was used to indicate to the browser that it was meant to load multiple HTML documents, represented as &lt;code&gt;&amp;lt;frame&amp;gt;&lt;/code&gt; elements, and how they were supposed to be displayed on the screen, using &lt;code&gt;cols&lt;/code&gt; and / or &lt;code&gt;rows&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- This is late 90s HTML, tags were SCREAMED! --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;FRAMESET&lt;/span&gt; &lt;span class="na"&gt;cols=&lt;/span&gt;&lt;span class="s"&gt;"25%, 75%"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;FRAME&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"sidebar"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"menu.html"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;FRAME&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"main"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"home.html"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/FRAMESET&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F55yyae0b3e951rffqa97.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F55yyae0b3e951rffqa97.png" alt="Simple frameset demo with two columns"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was even possible to nest &lt;code&gt;&amp;lt;frameset&amp;gt;&lt;/code&gt; tags to use the &lt;code&gt;cols&lt;/code&gt; and &lt;code&gt;rows&lt;/code&gt; attributes in combination, allowing to build more complex grids.&lt;/p&gt;

&lt;p&gt;A special &lt;strong&gt;HTML Doctype&lt;/strong&gt; was available and was &lt;em&gt;"sometimes"&lt;/em&gt; needed to allow for the rendering of &lt;code&gt;&amp;lt;frameset&amp;gt;&lt;/code&gt;-related tags:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
   "http://www.w3.org/TR/html4/frameset.dtd"&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Having multiple separate documents in a single browser window led to some complications, the first of them being &lt;strong&gt;deciding where a given link should open&lt;/strong&gt;. Hence was created the &lt;code&gt;target&lt;/code&gt; attribute for the &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag, which stands for &lt;em&gt;"frame target"&lt;/em&gt;: If provided the name of a given &lt;code&gt;&amp;lt;frame&amp;gt;&lt;/code&gt;, &lt;code&gt;target&lt;/code&gt; allowed click on &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; to open in a cell of the &lt;code&gt;&amp;lt;frameset&amp;gt;&lt;/code&gt;. A &lt;a href="https://www.w3.org/TR/html4/types.html#type-frame-target" rel="noopener noreferrer"&gt;few special targets&lt;/a&gt; were defined, such as the still overused &lt;code&gt;_blank&lt;/code&gt;, allowing to open the link in a new window.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;A&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"contact.html"&lt;/span&gt; &lt;span class="na"&gt;target=&lt;/span&gt;&lt;span class="s"&gt;"main"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"[...]"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Contact&lt;span class="nt"&gt;&amp;lt;/A&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F89t7w457hg0h5swzsg57.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F89t7w457hg0h5swzsg57.png" alt="Screenshot showing that opening another page in a frameset does not change the url"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, since this patchwork of HTML documents was meant to be a single page, &lt;strong&gt;JavaScript had to be able to talk and share information between frames, and even sometimes across domains&lt;/strong&gt; ... which we'll talk about a bit more when discussing the &lt;strong&gt;security issues of framesets&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What was it "good" for?
&lt;/h2&gt;

&lt;p&gt;The main advantage of &lt;code&gt;&amp;lt;frameset&amp;gt;&lt;/code&gt;-based websites was that they allowed for &lt;strong&gt;code reuse and modularity&lt;/strong&gt;: splitting a webpage in separate documents, organized by role, made possible to focus on the development of a part without affecting the other, of containing code and its effects in a &lt;code&gt;&amp;lt;frame&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This very feature could also help, in a way, with &lt;strong&gt;performance&lt;/strong&gt;: only reloading parts of a page when navigating made for smaller payloads, which is still relevant today but was critically important in the before-broadband-internet times.&lt;/p&gt;

&lt;p&gt;But more importantly, &lt;strong&gt;they were an easy-to-use layout tool&lt;/strong&gt;, that styling alone could not help achieve at the time: there was no &lt;em&gt;"more semantically"&lt;/em&gt; correct way of doing things available at the time.&lt;/p&gt;




&lt;h2&gt;
  
  
  Risks and limitations
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Proper search engine indexation&lt;/strong&gt; was really hard to achieve using &lt;code&gt;&amp;lt;frameset&amp;gt;&lt;/code&gt;. Using &lt;code&gt;target&lt;/code&gt; on a link to open a page on a given &lt;code&gt;&amp;lt;frame&amp;gt;&lt;/code&gt; meant that the window's main url was not changing: &lt;strong&gt;&lt;code&gt;&amp;lt;frameset&amp;gt;&lt;/code&gt; pages did not have a publicly accessible url&lt;/strong&gt;, while individual frames where still crawlable.&lt;br&gt;
As a result, search engines were often indexing single frames separately, which led users to land on &lt;em&gt;"broken"&lt;/em&gt; websites, and on an information deprived of its intended context.&lt;/p&gt;

&lt;p&gt;As they were multiple in effect &lt;em&gt;"screens"&lt;/em&gt; in one, &lt;code&gt;&amp;lt;frameset&amp;gt;&lt;/code&gt; were also poorly supported by &lt;strong&gt;screen readers&lt;/strong&gt;, making it challenging to build &lt;strong&gt;accessible websites&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;On the &lt;strong&gt;performance side of things&lt;/strong&gt;, &lt;code&gt;&amp;lt;framset&amp;gt;&lt;/code&gt;-based websites had a significant advantage once the first load was done: as navigation was happening on generally one or two of the frames, most of the frames didn't need to be reloaded. But this also meant that, on first load, the browser had to download and parse more HTML documents.&lt;/p&gt;

&lt;p&gt;Finally, &lt;strong&gt;they were and still are a security headache&lt;/strong&gt;: the ability for frames to interact with their parents and siblings via JavaScript - even across domains - gave birth to many attacks pattern we are still reckoning with today.&lt;/p&gt;




&lt;h2&gt;
  
  
  What remains of it today?
&lt;/h2&gt;

&lt;p&gt;Besides everything that it taught us, and the millions of older websites out there that are still using &lt;code&gt;&amp;lt;frame&amp;gt;&lt;/code&gt; and that would have been much different otherwise, I feel like one of &lt;code&gt;&amp;lt;frameset&amp;gt;&lt;/code&gt;'s main legacy to modern web development is the &lt;code&gt;target&lt;/code&gt; attribute for the &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag, and the security, accessibility and performance challenges it poses.&lt;/p&gt;

&lt;p&gt;When using &lt;code&gt;target="_blank"&lt;/code&gt;, &lt;a href="https://developers.google.com/web/tools/lighthouse/audits/noopener" rel="noopener noreferrer"&gt;we must add &lt;code&gt;rel="noopener noreferrer"&lt;/code&gt;&lt;/a&gt; to let the browser know that &lt;strong&gt;it should not allow the new window to access the window that called it&lt;/strong&gt;. While modern browsers implement some default protections to prevent leaks, without &lt;code&gt;rel="noopener noreferrer"&lt;/code&gt;, it is still possible to access &lt;strong&gt;some&lt;/strong&gt; of the caller's information via &lt;code&gt;window.opener&lt;/code&gt;, a behavior inherited &lt;em&gt;(to a certain extent)&lt;/em&gt; from the &lt;code&gt;&amp;lt;frameset&amp;gt;&lt;/code&gt; era.&lt;/p&gt;

&lt;p&gt;But access to &lt;code&gt;window.opener&lt;/code&gt; &lt;em&gt;(the caller's window object)&lt;/em&gt; is also the main reason why &lt;code&gt;target="_blank"&lt;/code&gt; can be a threat to performance: sharing objects across pages means sharing memory, which gives the browser less opportunities to separate processes and threads. &lt;a href="https://twitter.com/jaffathecake" rel="noopener noreferrer"&gt;Jake Archibald&lt;/a&gt; wrote a terrific blog post about &lt;a href="https://jakearchibald.com/2016/performance-benefits-of-rel-noopener/" rel="noopener noreferrer"&gt;"The performance benefits of rel=noopener"&lt;/a&gt; back in 2016.&lt;/p&gt;

&lt;p&gt;Its dizzying, sometimes, to look back at the origin of all things web and see how ideas from the past &lt;em&gt;- that we sometimes completely forgot about -&lt;/em&gt; still have an important impact on our everyday lives, and how things evolved for the better.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>html</category>
    </item>
  </channel>
</rss>
