Rendering in Web Browser

The main purpose of the browser is to present the web resources by requesting it from the server and rendering it. In present days, apart from the development phase, web developers face challenges where their UX designs are not the same across the browsers.

Basically, the HTML specifications are designed by W3C(World Wide Web Consortium). But only a part of the rules is followed by the browsers and the other parts are their own extensions and developments. This is why we face cross-browser compatibility issues.

The similarities across all browsers are the address bar, reload URL, bookmarks, home page, etc,,.

High Level Structure of a Browser

  • User Interface:  The View we see it when we hit an URL/link
  • Browser Engine: An engine that invokes the browser and responsible for displaying content on the screen(between UI and Rendering Engine)
  • Rendering Engine
  • Networking: For network calls that happen in the web browsers
  • UI Backend
  • Javascript Engine: Parse Javascript code
  • Data Storage: Refers the Local storage, cookies, WebSQL, IndexedDB, etc..

The Rendering Engine and the Javascript Engine will vary based on the browsers. Due to this, we face compatibility issues. Few are here,

browser-details

Let’s go more detail about Rendering Engine!

Rendering engine

Rendering Outline

First, HTML is parsed to DOM tree using HTML parser. In the meantime, the CSS is parsed to CSSOM tree using CSS parser. Combining both DOM and CSSOM, the ‘Render Tree’ is constructed.
Then goes the layout formation. In the layout process, every DOM element gets its coordinates.
Using the paint method, all coordinates get their position in the view/display

For a better experience, the rendering engine will try to display the contents on the screen as soon as possible. Many times we see the half view is loaded in the browser. This is because only a part of the HTML and CSS is parsed as rendering engine tried to give the view as quickly as possible and remaining are loaded later.

Terms:

Scripts:
The Rendering engine reads the HTML document line by line. If it finds a script tag <script>, the parsing of the document halts until the script finished. Due to this, the loading of the document takes time. To avoid this, use async/defer in the script tag to process asynchronously which means a separate thread is called for script parsing.

Repaint/Restyle:
Changing the style of the element that does not affect the respective element’s position, like changing the background color, the repaint will happen.

Reflow:
The Reflow will happen on changing the content that affects the element’s position or a situation where restructuring the DOM is necessary, like changing the text of an element, animations for the relative elements, resizing, scrolling, etc,.The cost of rendering is high when reflow happens frequently.

Better Optimization:

  • Use proper encoding document types and valid HTML, CSS elements.
  • Apply the rules in the correct cascade order
  • Apply animation only for the absolute/fixed positioned elements.
  • Work with ‘offline elements’.
  • Place the scripts end of the document or use async/defer in the scripts

References:

  • https://www.html5rocks.com/en/tutorials/internals/howbrowserswork/#Rendering_engines
  • https://medium.com/@monica1109/how-does-web-browsers-work-c95ad628a509
  • https://hackernoon.com/how-do-web-browsers-work-40cefd2cb1e1
  • http://frontendbabel.info/articles/webpage-rendering-101/
  • https://developers.google.com/web/updates/2019/02/rendering-on-the-web
  • https://labs.ft.com/2012/08/basic-offline-html5-web-app/

Validations in Full Stack Development

Full Stack Development, a quite tough to explain in a couple of lines. It takes ownership of the entire application from top to bottom. If you see a person as Full Stack Developer, he must be an all-rounder to develop an application from zero to high excellence. Full Stack Development includes 2 layers of architecture :

  1. Front-End Development (aka Client-Side / Presentation Layer)
  2. Back-End Development (aka Server-Side / Business Logic Layer)

Each Layer should have a data validations. Let’s dive in deeper,

Client-Side Validations

Validation takes place on the client side(web browser). It would be more frustrating to wait for the server response and re-enter the form that has nearly 100 inputs. So it is mainly for formatting data instantly and for the quick error recovery process.
Client-side validation gives the user feedback ASAP without having to wait for the server. It is an added topping, but not necessary. This will avoid the majority of validation issues and unnecessary processing from the server to perform data validations.

Pros:

  • Faster than Server-Side Validation
  • Better user experience can be provided by responding quickly(like invalid phone number, required fields,etc..)
  • Saves network bandwidth, traffic API calls

Cons:

  • Not Secure and useless if client-side scripts are disabled(javascript disabled)

Server-Side Validations

It is all about the data validation takes place on the server-side using the server-side scripting language. If you use server-side validation, you are developing a more secure application. Because client-side validations can be bypassed easily.

Let’s take a scenario. If a user is a technical guy/ a malicious user, he can pass invalid inputs through API testing tool or he can disable the javascript in client script or some malicious attack to skip client side validations. In these cases, validation will not happen. This may lead to incorrect entries, server downtime if any serious errors, etc, So we should verify on the server as well.

There are few libraries(eg., express-validator, etc) available to validate the inputs. Better, write a few code snippets for validations before continuing your business logic like

router.post(‘/api’, async(req, res) => {

 let isValidationPassed= await validateAndHandleInputs(req);

 if(isValidationPassed){

  //continue the business logics

 }

})

Pros:

  • More Secure than Client-Side Validation
  • Validation Techniques and Logics cannot be viewed/modified by the user.

Cons

  • Comparatively slower execution

References:

  1. https://www.smashingmagazine.com/2009/07/web-form-validation-best-practices-and-tutorials/
  2. https://medium.com/@davidpetri/server-and-client-side-validation-with-javascript-html-and-hapi-js-eccc779e448a
  3. http://net-informations.com/faq/asp/validation.htm
  4. https://surajdeshpande.wordpress.com/2013/08/10/difference-between-server-side-validation-and-client-side-validation/

Understanding CSS: Precedence & Specificity

Have you faced a situation where you are trying to apply the CSS style to an element, but it does not apply? It seems the webpage is ignoring your code. This could be caused by conflicts in the cascade order.

Things will discuss here:

  1. Origins of Stylesheets
  2. Specificity
  3. Importance
  4. Cascade Order

Origins of stylesheets:

  1. Author stylesheet (Styles set by the web developers)
  2. User stylesheet (Custom styles set by a user – Browsers give you the option of extending the browser’s default style sheet)
  3. Browser stylesheet / User-agent style sheet (Browser defaults – if the author of a web page didn’t apply any styling, the styling details present in the default stylesheet installed within the browser is applied)

Specificity:

        An HTML element can be targeted by multiple CSS rules. If there are two or more conflicting CSS rules, the browser will apply the rule which is more specifically mentioned. Specificity will only apply when one element has multiple declarations to it. To understand in a better way, the specificity is expressed in the form (a, b, c, d). Lets see in detail,

Specificity Hierarchy (High to Low):

  • Inline style

o   ‘style’ attribute rather than a rule with a selector

o   The position ‘a’ – (a, b, c, d) – (1, 0, 0, 0)

  • ID Selectors

o   Eg. The element with id attribute, id=’example’(#example)

o   The position ‘b’ – (a, b, c, d) – (0, 1, 0, 0)

  • Class Selectors(.example), Attribute selectors([type=radio]) and pseudo-classes(:hover)

o   The position ‘c’ – (a, b, c, d) – (0, 0, 1, 0)

  • Type Selectors(h1) and pseudo-elements (::after)

o   The position ‘d’ – (a, b, c, d) – (0,0,0,1)

Example:

Selectors Specificity
*{ } 0,0,0,0
li{ } 0,0,0,1
li:first-line { }   0,0,0,2
ul li{ }   0,0,0,2
ul ol+li{ } 0,0,0,3
h1 + *[rel=up]{ } 0,0,1,1
ul ol li.red  { } 0,0,1,3
li.red.level  { } 0,0,2,1
#exampleId{ } 0,1,0,0
style=”” 1,0,0,0

No Specificity:

  1. The universal selector (*,+, -,>, ~) has no specificity value.
  2. The pseudo-class :not() adds no specificity. The negation ‘ pseudo-class: not’ is not considered a pseudo-class in the specificity calculation. It counts as normal selectors

Origin Hierarchy:

Below is the priority order from highest to lowest for normal styles when there is equal specificity for the declarations. If it was an important style (! important), it is just the reverse.

  1. Author style sheet
  2. User style sheet
  3. User-agent (browser) stylesheet

Importance:

  1. Normal declaration (p {color: red} )
  2. Important declaration (p {color: red !important} )

!important

The !important value appended in a declaration along with the property value in any of the ruleset/rules will be taken as the most priority even if the rule has less specificity.

Override !important:

Either add Specificity to the declaration or have only one !important declaration, remove others.

Cascade Order:

        The cascading order depends on origin, specificity, importance and source order. Below is the precedence order from low to high,

  1. Declarations in user agent style sheets (e.g. the browser’s default styles, used when no other styling is set).
  2. Normal declarations in user style sheets (custom styles set by a user).
  3. Normal declarations in author style sheets (these are the styles set by the web developers).
  4. Important declarations in author style sheets
  5. Important declarations in user style sheets

Note:

  • Declaration with Same Importance and Same-Origin: More specific selectors will override more general ones
  • Source Order – Declaration with the Same Importance, Same Specificity, and Same-Origin: the later rule takes precedence

Best Practices:

  • Use Class selectors instead of ID selectors.
  • Avoid using multiple CSS rules that target the same HTML elements.
  • Do not use inline styles.
  • Use specificity before even considering !important .
  • Although ‘!important’ works, it is generally bad practice. It can make debugging a difficult process
  • Only use !important on page-specific CSS that overrides foreign CSS (from external libraries, like Bootstrap or normalize.css).

Reference:

1) https://www.w3.org/TR/2011/REC-CSS2-20110607/cascade.html#cascade
2) https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
3) https://css-tricks.com/precedence-css-order-css-matters/
4) https://vanseodesign.com/css/css-specificity-inheritance-cascaade/
5) https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS/Cascade_and_inheritance
6) http://tutorials.jenkov.com/css/precedence.html