Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
# Getting Started
In this lab you will learn about the development of web sites that are structured as a _single-page application_.
The _shell_ is the tool you use to issue shell commands. On Linux or MacOS this will be the [Terminal](https://askubuntu.com/questions/38162/what-is-a-terminal-and-how-do-i-open-and-use-it) and on Windows this is the [Command Prompt](https://www.computerhope.com/issues/chusedos.htm). If you are on Windows you won't be able to run any git commands using Command Prompt but instead will need to use [Git Bash](https://gitforwindows.org) instead.
# 1 Setup
To complete the lab you will need to ensure you have the correct software installed and have downloaded the source code.
## 1.1 Installing the Tools
To complete this lab you will need the following software installed:
- A standards-compliant browser (such as Chromium or Google Chrome).
- NodeJS (LTS, not the latest version).
- Git running in your shell.
- The Heroku CLI tool (instructions below).
Install the [Heroku CLI](https://devcenter.heroku.com/categories/command-line) tools, using the [instructions](https://devcenter.heroku.com/articles/getting-started-with-nodejs?singlepage=true#set-up) on their website. You may need to restart your shell before continuing.
You will also need to register for a free developer account on the [Heroku website](https://www.heroku.com).
## 1.2 Downloading the Source Code
There is a [template available](https://github.coventry.ac.uk/web/template-single-page-app) on the University GitHub server. This will be used for many labs.
You need to use the "**Use this template**" button each time you need a copy of the code. For the lab exercises (such as this one) you should store the copy of the code in your personal space. Do this now and call it `single-page-app`.
If, for any reason, you are struggling to get the code in this manner an alternative is to click on the "**Clone or download**" button and use the _Download ZIP_ option, renaming the directory `single-page-app`.
# 2 Running the App Locally
Clone your repository and use your shell to navigate to the `single_page_app/` directory created by the clone command. After installing all the module dependencies using `npm install`, you can run the server using `node index.js`. You should be able to point your browser to `localhost:8080` to see the site.
Take a few minutes to see how it works, try registering and account and logging in. Press `ctrl+c` to stop the server.
# 3 Deploying to Heroku
We will now cover how to host your SPA in the cloud.
Heroku is a _cloud application platform_, which is an example of a _platform as a service (PaaS)_. It makes it very easy to deliver and deploy modern apps allowing you to focus on coding them. Deployment uses [Git](https://git-scm.com) to upload the code to the server. When code is pushed, the server runs a _pre-receive [hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks)_ to provision the server and get your app up and running.
### 3.1 Logging Into Heroku
Make sure your shell is still in the `single_page_app/` project directory created by the clone command. Now log into Heroku using the CLI (note this will make use of the browser):
```shell
$ heroku login
heroku: Press any key to open up the browser to login or q to exit
› Warning: If browser does not open, visit
› https://cli-auth.heroku.com/auth/browser/***
heroku: Waiting for login...
Logging in... done
Logged in as jdoe@example.com
```
### 3.2 Configuring the App
Heroku uses the information in the _application manifest_ `package.json` to get your website running:
1. It spins up a [docker](https://www.docker.com) virtual machine container.
2. It installs the version of NodeJS specified in the `engines.node` key. In the sample code we are specifying v12.14.
3. It then goes through all the packages listed in the `dependencies` object and installs the versions specified there.
4. To decide how to run the server it looks for the `start` key inside the `scripts` object and executes what it finds.
For this reason it is absolutely vital that the application manifest is accurate and up-to-date.
### 3.3 Deploying For the First Time
After making sure you are in the correct project directory, run the following command:
```shell
$ heroku create
Creating app... done, ⬢ cryptic-depths-87792
https://cryptic-rain-52361.herokuapp.com/ | https://git.heroku.com/cryptic-rain-52361.git
```
Heroku generates a random name for your app, in this case `cryptic-rain-52361` and provides both a link to the live server and to the git remote it has created for you. If you check your repository remotes you should see this alongside the origin remote on github:
```shell
$ git remote -v
heroku https://git.heroku.com/cryptic-rain-52361.git (fetch)
heroku https://git.heroku.com/cryptic-rain-52361.git (push)
origin https://github.coventry.ac.uk/bloggsj/myapp.git (fetch)
origin https://github.coventry.ac.uk/bloggs/myapp.git (push)
```
To deploy the app we simply have to push to this remote...
```shell
$ git push heroku master
Enumerating objects: 12, done.
Counting objects: 100% (12/12), done.
Delta compression using up to 4 threads
Compressing objects: 100% (7/7), done.
Writing objects: 100% (7/7), 1.41 KiB | 1.41 MiB/s, done.
Total 7 (delta 4), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote: -----> Node.js app detected
remote: -----> Creating runtime environment
remote: -----> Installing binaries
remote: -----> Restoring cache
remote: -----> Installing dependencies
remote: -----> Build
remote: -----> Caching build
remote: -----> Pruning devDependencies
remote: -----> Build succeeded!
remote: -----> Discovering process types
remote: -----> Compressing...
remote: -----> Launching...
remote: https://cryptic-rain-52361.herokuapp.com/ deployed to Heroku
remote: Verifying deploy... done.
To https://git.heroku.com/cryptic-rain-52361.git
9fc3cc6..62ef6a3 master -> master
```
You should now be able to access your deployed app using the URL provided by heroku.
### 3.4 Monitoring the Server
The server generates detailed logs that you should be checking on a regular basis:
```
heroku logs --tail
```
This gives you a live view of the logs. Run the command then try navigating the website. To quit you use the standard `ctrl+c` key combination.
You can also log directly into the server bash shell:
```shell
$ heroku ps:exec
Running this command for the first time requires a dyno restart.
Do you want to continue? [y/n]:
Initializing feature... done
Restarting dynos... done
Waiting for web.1 to start... ⡿
Establishing credentials... done
Connecting to web.1 on ⬢ cryptic-depths-87792...
~ $
```
The prompt changes and you are now logged into the server via the shell and can run all standard bash commands. type `exit` to quit. This returns you to the workstation prompt.
## 4 Monitoring Network Usage
We will be working to improve the efficiency of the apps we will be producing. What do we mean by _efficiency_?
One key metric is concerned with how quicky and smoothly the page(s) load as this impacts the user experience.
If we are to understand the issues we are trying to resolve we need a suitable tool to both test our system under controlled conditions and to generate data which allows us to see the issues.
### 4.1 Visualising Network Load
With the app running locally, open Chromium and, from the main menu (top-right) select **More tools** > **Developer tools** and position this at the bottom of the browser window. Open the **Network** tab and load the page `http://localhost:8080` (or refresh the page if this is already being displayed). You should see something similar to the following:
![Network Tab in the Chromium Browser](.assets/chromium_network.png)
This shows the sequence of steps that were needed to download and display the page, starting with the request for the base html page which then loads the stylesheet and script, etc.
Each bar is broken down into several bands:
![Chromium Document Loading](.assets/chromium_page_load.png)
The narrow bar is the _request_ and the wide bar the _response_. You can see more metrics by hovering your mouse over each bar.
1. White: STALLED, time the request spent waiting before it could be sent.
2. Grey: REQUEST SENT, the http request was sent to the server.
3. Green: TIME TO FIRST BYTE, includes 1 round trip of latency plus the time the server took to prepare the response.
4. Blue: CONTENT DOWNLOAD, The browser is receiving the response.
Notice that HTTP/1.1 can only handle two http requests at one time. This limitation has been removed for HTTP/2 which we will be covering in a later lab.
### 4.2 Simulating Different Network Conditions
Running your web app locally means you will never encounter major bandwidth or latency issues however your apps needs to be able to handle real-world conditions such as users accessing the app over the internet, possibly using an intermittent cellular connection.
Whilst you could take the time to walk around and try and find suitable conditions, ths is clearly not time-efficient or even feasible. because this type of testing is very common, there are tools build into modern web browsers to simulate these conditions.
Let's load the same page, this time over a slow 3G connection such as many mobile users will be limited to. Click on the dropdown link which will be displaying the label **Online** and change this to **Slow 3G**. You should also disable the cache by checking the **Disable cache** checkbox. Now reload the page, watching the browser window to see how the page loads.
![Network Tab in the Chromium Browser](.assets/chromium_network_3g.png)
A 3G network typically has a very high latency and this is clearly shown in the graph by a much longer _TTFB_ time. This represents the delay between a request being sent from the browser and the first byte of data being received back in the response.
## 5 Device Simulation
A key way we can improve the user experience is by ensuring that the controls and layout of our app are optimised for:
1. The size of screen the user is viewing the app on.
2. The mode of interaction (are they using a trackpad or a touchscreen?).
Responsive Web Design principles mean designing you page to change its layout and appearance depending on the type of device, measured by screen resolution and primary input device.
As you develop your responsive designs you will need to quickly test the changes. Whilst this can be carried out using different hardware this is often time consuming as you need to host the site and then take the time to physically use each device.
### 5.1 Accessing The Simulator
To help you during the development process Chromium includes a [Device Mode](https://developers.google.com/web/tools/chrome-devtools/device-mode) which allows you to test how the app will look based on resolution and input device. Whilst these can never be completely accurate, they serve perfectly to iterate through the design, with final tests being carried out on actual devices.
![Device Mode](.assets/chromium_device_mode.png)
If you click on this you will see the following:
![Device Simulation](.assets/chromium_device_simulation.png)
Note if your view looks different from the screenshot above make sure you have the **Responsive** mode selected (see arrow) and have added the extra tools using the main menu button at the top-right of the screen (see arrow).
### 5.2 Changing the Simulator Settings
With the simulator open you can use the settings to simulate a wide range of devices.
<dl>
<dt>Screen Resolution</dt>
<dd>You can use the handles along the edge of the screen (see arrow) to adjust the width and height in pixels. The ruler is calibrated in pixels.</dd>
<dt>Primary Input Device</dt>
<dd>The **Mobile** dropdown allows you to choose between desktop and mobile, each with a touchscreen and non-touchscreen option.</dd>
<dt>Connectivity</dt>
<dd>The **Online** dropdown lets you simulate high or low-end hardware or even simulate being disconnected from the Internet. This simulates a combination of slow CPU and slow network.</dd>
<dt>Device Rotation</dt>
<dd>The last button simulates switching from _landscape_ to _portrait_ mode.</dd>
</dl>
### 5.3 Device Sensors
It is also possible to simulate the hardware sensors on the device. By default this is hidden and needs to be accessed under **Settings** > **More tools** > **Sensors**.
![More Tools](.assets/chromium_more_tools.png)
This will open a new pane in the developer tools where you can simulate:
1. Geolocation.
2. The device orientation.
As you change the simulated location you should see the appropriate coordinates appear in the page footer!
## 6 Responsive Web Design
The interface needs to be optimised for different screen resolutions and different types of input, for example a touch interface can't generate mouse events such as mouse-over and the controls should be of a size that is easy to interact with using a finger. An interface designed to be used with a trackpad or mouse can use much more precise controls.
If you look a the icon in the far left of the footer you should see a tablet-shaped icon. In the settings, switch from **Mobile** to **Desktop**. Notice that when you are simulating a desktop device the cursor changes to a desktop cursor but also the icon changes to a desktop screen!
The current page design is optimised for traditional computers using a mouse or trackpad, what changes would you make for it to work well for users using a touchscreen and finger?
Now drag the screen width wider and narrower in **Responsive** mode. As you do so keep an eye on the "led" indicator in the page footer. Notice that if you make the screen narrow it switches to red and, if you make the screen very wide it goes green. Above the simulated screen you should see a bar split into three levels (typically blue, green and brown). What happens as you drag the screen size between these zones?
You will have noticed that the page layout is optimised for the medium width screen. When it gets very narrow the navigation bars get squashed and the content starts to disappear off the edge of the screen. How could you redesign the layout to prevent the layout isses on small screens?
When the screen is wide you will notice that the list blocks become very wide with a lot of wasted space. How could you redesign the layout to make better use of larger screens?
It looks like the web app is detecting both whether the device supports a touchscreen and which width "zone" it is currently in and updating the "led" accordingly. How does it do this and how are the zones defined?
### 6.1 CSS Media Selectors
Open up the `style.css` file and scroll to the bottom. You will see a series of `@media` selectors, each containing a CSS selector. The first two detect whether the device is touch-screen with fingers (no hover and coarse pointing) or whether it is non-touchscreen controlled with a trackad or mouse (hover supported and fine-grained pointer). If the conditions match the css selectors inside are run. This is how we can adjust the interface based on touch support.
Underneath this are three additional `@media` selectors that are triggered by the current screen width of the device. Again, once the conditions match the selectors are used.
Notice that the values in these are defined as min and max. These are used by Chrome to display the coloured bands. Try changing these and refreshing the browser.
### 6.2 Test Your Understanding
Earlier in the lab you identified some layout issues when the screen was very narrow and also when it was very wide:
1. Locate the media selector that detects the use of a touchscreen and add selectors to this to improve the design for touchscreen users.
2. Locate the media selector that detects narrow screens and add selectors to prevent the layout issues you saw earlier in the lab. You might consider removing the absolute sizes and letting the elements fill the screen width.
3. Locate the media selector that detects wide screens and change the layout so that the lists are presented as tiles that make use of the entire screen width.
## 7 Emulators
Whilst you can do a lot of development work using Google Chrome's _Device Mode_ final testing and tweaking will need to be done running on a browser on the target platform. There are emulators available for both iOS and Android phones and, once the design has been worked through using _Device Mode_ you should load it into the emulators for final tweaking.
### 7.1 Android Emulation
You should start by installing the latest version of [Android Studio](https://developer.android.com/studio) which provides access to the Android Virtual Device (AVD) tools that are used to install and manage the emulators.
#### 7.1.1 Creating a Virtual Device
Once Android Studio is installed, you should launch it and, from the launch screen choose **Configure** > **AVD manager** (see the screenshot below).
![More Tools](.assets/awd_opening.png)
We are going to go through the steps on creating and running an emulator of the _Nexus One_. Once you have understood these steps you can repeat the process to create and run as many emulators as you need for testing. Note that each emulator takes up to 1GB storage and your system may struggle to run emulators for the latest phones.
1. On the next screen choose **Nexus One** and click _Next_.
2. The next screen is where you choose the system image (OS version) to install. We will choose **Android 10.0**, the latest version at the time of writing.
3. The final screen asks you to choose a name for this AVD. You can choose anything you like.
#### 7.1.2 Running the Emulator
To run the emulator simply click on the green "play" button on the main AVD screen as shown.
![More Tools](.assets/awd_start.png)
This will start up the emulator and you can run the web browser on the emulator and point it to your running server.
![More Tools](.assets/awd_running.png)
### 7.2 iOS Emulation
**Note: you can only run iOS emulators if you are developing on MacOS.**
You should start by installing the latest version of [Xcode](https://apps.apple.com/gb/app/xcode/id497799835) from the Mac App Store which provides access to the iOS simulators.
Launch Xcode and, without creating a project use the **Xcode** > **Open Developer Tool** > **Simulator**. If you look in the dock you will see it has an icon. Right-click, choose **Options** > **Keep in dock**. This will create a permanent dock icon which you can use to launch the simulator without needing to open Xcode.