Cum se configurează smartphone-uri și PC-uri. Portal informativ

Browserele sunt. Chrome: o investiție în calitate

Este posibil ca browserul dvs. să nu accepte funcționalitatea din acest articol.

ForEach.call (document.querySelectorAll ("header .date a"), funcție (elem, i) (elem.textContent + = "(" + ["autor", "editor"] [i] + ")";) );

cuvânt înainte

aceasta manual detaliat pe elementele interne ale WebKit și Gecko este rezultatul cercetărilor ample ale programatorului web israelian Tali Garciel. Timp de câțiva ani, ea a urmărit toate informațiile publicate despre modul în care funcționează browserele (vezi secțiunea) și a petrecut mult timp analizând codul sursă. Iată ce scrie însăși Tali:

Când IE a fost instalat pe 90% dintre computere, a fost necesar să suportăm faptul că era o „cutie neagră” misterioasă, dar acum că mai mult de jumătate dintre utilizatori aleg browsere open source, este timpul să ne dăm seama ce este ascuns. în interiorul lor, în milioane de rânduri codul programuluiîn C++...
Tali a publicat rezultatele studiului pe site-ul ei, dar credem că acestea merită atenția unui public mai larg, așa că le postăm aici cu câteva abrevieri.

Un dezvoltator web care este familiarizat cu funcționarea interioară a browserelor ia decizii mai bune și înțelege de ce ar trebui să alegeți anumite instrumente. Acesta este un document destul de lung, totuși vă recomandăm să îl citiți cât mai atent posibil și să vă garantăm că nu veți regreta. Paul Irish, Relații cu dezvoltatorii Chrome

Introducere

Browserele web sunt probabil cele mai comune aplicații. În acest tutorial, explic cum funcționează. Vom arunca o privire mai atentă la ceea ce se întâmplă din momentul în care introduceți google.ru în bara de adrese și până la apariție pagini google pe ecran.

Ce browsere vom lua în considerare

Există cinci browsere majore astăzi: Internet Explorer, Firefox, Safari, Chrome și Opera. Exemplele folosesc browsere cu sursă deschisă: Firefox, Chrome și Safari (sursă deschisă parțial). Conform statisticilor privind utilizarea browserului de pe site-ul StatCounter, din august 2011, browserele Firefox, Safari și Chrome erau instalate pe un total de 60% dintre dispozitive. Astfel, browserele open source au astăzi o poziție foarte puternică.

Funcții de bază ale browserului

Scopul principal al browserului este de a afișa resurse web. Pentru a face acest lucru, o solicitare este trimisă către server, iar rezultatul este afișat în fereastra browserului. Resursele sunt în mare parte documente HTML, dar pot fi și PDF-uri, imagini sau alt conținut. Locația unei resurse este identificată folosind un URI (Uniform Resource Identifier).

Modul în care browserul gestionează și afișează fișierele HTML este determinat de specificațiile HTML și CSS. Sunt dezvoltate de Consorțiu W3C care implementează standarde pentru Internet.
De-a lungul anilor, browserele au îndeplinit doar părți ale specificațiilor și au fost create extensii separate pentru ele. Pentru dezvoltatorii web, acest lucru a însemnat probleme serioase de compatibilitate. Majoritatea browserelor de astăzi îndeplinesc toate specificațiile într-o măsură mai mare sau mai mică.

Interfețe cu utilizatorul browsere diferite avem multe in comun. Elementele principale ale interfeței browserului sunt enumerate mai jos.

  • Bara de adrese pentru introducerea URI
  • Butoanele de navigare Înapoi și Înainte
  • Marcaje
  • Butoane pentru a reîmprospăta și a opri încărcarea paginii
  • Butonul de pornire pentru a merge la pagina principală

Destul de ciudat, specificația care ar defini standardele interfața cu utilizatorul browserul nu există. Interfețe moderne sunt rezultatul multor ani de evoluție, precum și faptul că dezvoltatorii se copiază parțial între ei. Specificația HTML5 nu specifică exact ce ar trebui să conțină interfața browserului, dar listează câteva elemente de bază. Acestea includ bara de adrese, bara de stare și bara de instrumente. Desigur, există și funcții specifice, cum ar fi managerul de descărcare al Firefox.

Structura de nivel superior

Componentele principale ale browserului sunt enumerate mai jos ().

  1. Interfața cu utilizatorul- include bara de adresa, butoanele Înapoi și Înainte, meniul de marcaje etc. Acestea includ toate elementele cu excepția ferestrei în care este afișată pagina solicitată.
  2. Motor de browser- gestionează interacțiunea dintre interfață și modulul de afișare.
  3. Modul de afișare- este responsabil pentru afișarea conținutului solicitat pe ecran. De exemplu, dacă este solicitat un document HTML, rendererul analizează HTML și CSS și afișează rezultatul pe ecran.
  4. Componentele rețelei - sunt concepute pentru a efectua apeluri de rețea, cum ar fi solicitări HTTP. Interfața lor este independentă de platformă, fiecare dintre ele având propria sa implementare.
  5. Partea executivă a interfeței cu utilizatorul- folosit pentru redarea widget-urilor de bază, cum ar fi ferestre și casete combinate. Interfața sa generică este, de asemenea, independentă de platformă. Partea de execuție aplică întotdeauna metodele interfeței utilizator a unui anumit sistem de operare.
  6. interpret JavaScript- folosit pentru a analiza și executa cod JavaScript.
  7. Magazin de date- este necesar pentru persistenţa proceselor. Browserul salvează în HDD date tipuri diferite, de exemplu cookie-uri... Noua specificație HTML (HTML5) definește termenul „bază de date web”: este o bază de date completă (deși ușoară) bazată pe browser.
Desen . Componentele principale ale browserului.

Trebuie remarcat faptul că Chrome, spre deosebire de majoritatea browserelor, folosește mai multe instanțe ale motorului de afișare, câte una în fiecare filă, care reprezintă procese separate.

Modul de afișare

După cum sugerează și numele, modulul de afișare este responsabil pentru afișarea conținutului solicitat pe ecranul browserului.

În mod implicit, este capabil să afișeze documente HTML și XML, precum și imagini. Plug-in-uri speciale (extensii de browser) fac afișare posibilă alt conținut, cum ar fi fișierele PDF. Totuși, acest capitol se concentrează pe funcționalitatea de bază: afișarea documentelor HTML și a imaginilor formatate cu stiluri CSS.

Module de afișare

Browserele care ne interesează (Firefox, Chrome și Safari) folosesc două module de afișare. Firefox aplică Gecko - propria dezvoltare Mozilla, în timp ce Safari și Chrome folosesc WebKit.

WebKit este un modul de afișare open source pentru care a fost dezvoltat inițial Platforme Linux si adaptat de Apple pentru Mac OS și Windows. Detalii poate fi găsit pe webkit.org.

Schema de bază de lucru

Modulul de afișare primește conținutul documentului solicitat prin protocol stratul de rețea, de obicei în bucăți de 8K.

Sistem munca in continuare modulul de afișare arată ca următorul.

Desen . Schema modulului de afișare.

Rendererul analizează documentul HTML și traduce etichetele în noduri în arborele de conținut. Informațiile de stil sunt preluate atât din fișierele CSS externe, cât și din elementele de stil. Aceste informații și instrucțiunile de redare din fișierul HTML sunt folosite pentru a crea un alt arbore -.

Conține dreptunghiuri cu atribute vizuale, cum ar fi culoarea și dimensiunea. Dreptunghiurile sunt aranjate în ordinea în care ar trebui să fie afișate pe ecran.

După crearea arborelui de afișare, încep elementele, timp în care fiecărui nod i se atribuie coordonatele punctului de pe ecran în care ar trebui să apară. Apoi este executat, în care nodurile arborelui de afișare sunt redate secvențial folosind partea de execuție a interfeței cu utilizatorul.

Este important să înțelegeți că acesta este un proces secvenţial. Pentru confortul utilizatorului, motorul de afișare încearcă să afișeze conținutul cât mai curând posibil, astfel încât crearea și aspectul arborelui de afișare pot începe chiar înainte ca HTML-ul să fie analizat. Unele părți ale documentului sunt analizate și afișate, în timp ce altele sunt transmise doar prin rețea.

Exemple de lucru

Desen . Diagrama modulului de afișare WebKit. Desen . Diagrama modulului de afișare Mozilla Gecko ().

După cum puteți vedea din figurile 3 și 4, WebKit și Gecko folosesc o terminologie diferită, dar fluxurile lor de lucru sunt aproape identice.

În Gecko, un arbore de elemente formatate vizual este numit arbore de cadru, în care fiecare element este un cadru. WebKit utilizează un arbore de randare, care este alcătuit din obiecte de randare. Aspectul elementelor din WebKit se numește aspect, iar în Gecko se numește reflow. Uniune noduri DOM iar atributele vizuale pentru a crea arborele de afișare se numesc atașament în WebKit. O mică diferență, non-semantică, în Gecko este că există un alt strat între fișierul HTML și arborele DOM. Acesta se numește chiuveta de conținut și este folosit pentru a forma elemente DOM. Acum să vorbim mai detaliat despre fiecare etapă de lucru.

Analiza: o privire de ansamblu

Din moment ce analizarea este o piatră de hotar importantă a modulului de afișare, să-l luăm în considerare mai detaliat. Să începem cu o scurtă introducere.

Analizarea unui document înseamnă transformarea acestuia într-o structură lizibilă și executabilă. Rezultatul analizei este de obicei un arbore de noduri reprezentând structura documentului. Se numește arbore de analiză, sau pur și simplu arbore de analiză.

De exemplu, ca rezultat al analizei expresiei 2 + 3 - 1, puteți obține următorul arbore:

Desen . Nod de copac pentru expresie matematică.

Gramatică

Analizare funcționează pe bază anumite reguli, care sunt determinate de limba (formatul) documentului. Pentru fiecare format, există reguli gramaticale formate din vocabular și sintaxă. Ele formează așa-numitele. ... Limbile naturale nu respectă regulile gramaticii fără context, așa că tehnicile standard de analizare nu funcționează pentru ele.

Analizoare și analizoare lexicale

Analiza lexicală este utilizată împreună cu analiza sintactică.

Analiza lexicală este împărțirea informațiilor în token-uri sau lexeme. Jetoanele formează dicționarul unei anumite limbi și sunt elemente constructive pentru crearea documentelor. În limbajul natural, jetoanele ar fi toate cuvintele care pot fi găsite în dicționare.

Scopul analizei este aplicarea regulilor sintactice ale limbajului.

Analizarea unui document se face de obicei în două componente: analizator lexical parsarea secvenței de caractere de intrare în jetoane valide și analizator analizând structura documentului conform regulilor de sintaxă a acestei limbiși formând un arbore de sintaxă. Analizorul ignoră caracterele neinformative, cum ar fi spațiile și întreruperile de rând.

Desen . Treceți de la documentul sursă la arborele de sintaxă.

Analiza este un proces iterativ. Analizatorul cere de obicei lexicalului un nou token și îl verifică cu oricare dintre regulile de sintaxă. Dacă se poate face o potrivire, a nod nouîn arborele de sintaxă, iar analizatorul solicită următorul simbol.

Dacă un jeton nu se potrivește cu niciuna dintre reguli, analizatorul îl amână și solicită următoarele jetonuri. Aceasta continuă până când se găsește o regulă care să satisfacă toate jetoanele în așteptare. Dacă nu poate găsi o astfel de regulă, analizorul aruncă o excepție. Aceasta înseamnă că documentul conține erori de sintaxăși nu pot fi procesate complet.

Traducere

Arborele de sintaxă nu este întotdeauna rezultatul final. Analiza este adesea folosită în procesul de traducere a unui document de intrare în formatul dorit... Un exemplu ar fi compilarea. Un compilator care traduce sursăîn mașină, mai întâi îl parsează și formează un arbore de sintaxă și abia apoi creează un document cu codul mașinii bazat pe acest arbore.

Desen . Etape de compilare.

Exemplu de analiză

Figura 5 prezintă un arbore de sintaxă bazat pe o expresie matematică. Să definim un limbaj matematic elementar și să luăm în considerare procesul de parsare.

Dicționar: limba noastră poate conține numere întregi, semne plus și minus.

Sintaxă

  1. Elementele structurale ale limbajului sunt expresiile, operanzii și operatorii.
  2. Limbajul poate conține orice număr de expresii.
  3. O expresie este o secvență formată dintr-un operand, un operator și un alt operand.
  4. Un operator este un simbol plus sau minus.
  5. Operandul este un simbol sau o expresie întreg.

Luați în considerare secvența de introducere a caracterelor 2 + 3 - 1.
Primul element care se potrivește cu regula este 2 (conform regulii #5, acesta este operandul). Al doilea astfel de element este 2 + 3 (o succesiune formată dintr-un operand, un operator și încă un operand este definită de regula #3). Găsim următoarea potrivire la sfârșit: secvența 2 + 3 - 1 este o expresie. Deoarece 2 + 3 este un operand, obținem o secvență formată dintr-un operand, un operator și un alt operand, care se potrivește cu definiția expresiei. Linia 2 + + nu se potrivește cu regulile, așa că ar fi considerată nevalidă.

Definirea formală a vocabularului și a sintaxei

Limbajul din exemplul de mai sus ar putea fi definit astfel:

INTEGER: 0 | * PLUS: + MINUS: - După cum puteți vedea, numerele întregi sunt definite prin expresii regulate.

Sintaxa este de obicei descrisă în format BNF. Limbajul din exemplul de mai sus poate fi descris după cum urmează:

Expresie: = termen operație termen operație: = PLUS | Termenul MINUS: = INTEGER | expresie

După cum s-a spus, o limbă poate fi analizată cu analizatoare standard dacă gramatica sa este fără context, adică poate fi exprimat integral în format BNF. Definiție formală Gramatica fără context poate fi găsită în acest articol Wikipedia.

Tipuri de analizator

Analizoarele sunt de două tipuri: de sus în jos și de jos în sus. Primii fac analiza de sus în jos, în timp ce cei din urmă fac analiza de jos în sus. Analizoarele din aval analizează structura nivel superiorși căutând reguli de sintaxă potrivite. Analizoarele crescătoare procesează mai întâi secvența de caractere de intrare și descoperă treptat regulile de sintaxă din ea, începând cu regulile nivelului inferior și terminând cu regulile nivelului superior.

Acum să vedem cum aceste două tipuri de analizoare s-ar descurca cu exemplul nostru.

Un parser de sus în jos ar începe cu regula de nivel superior și ar determina că 2 + 3 este o expresie. S-ar determina apoi că 2 + 3 - 1 este și o expresie (în procesul de definire a expresiilor se găsesc și potriviri cu alte reguli, dar regula de nivel superior este întotdeauna considerată prima).

Analizatorul din amonte ar procesa secvența de caractere până când va fi găsită regula potrivita, cu care puteți înlocui fragmentul detectat și așa mai departe până la sfârșitul secvenței. Expresiile cu potrivire parțială sunt introduse în stiva de analiză.

Când lucrați cu un astfel de parser, secvența de introducere a caracterelor este deplasată la dreapta (imaginați-vă cursorul, care este plasat la începutul secvenței și este deplasat la dreapta în timpul analizei) și redusă treptat la reguli de sintaxă.

Generarea automată de parseri

Există aplicatii speciale pentru a crea analizatoare numite generatoare. Este suficient să încărcați gramatica limbii (reguli de vocabular și sintaxă) în generator și va crea automat analizatorul. Construirea unui parser necesită o înțelegere profundă a modului în care funcționează și nu este ușor să o faceți manual, așa că generatoarele pot fi foarte utile.

DOM

Arborele de sintaxă rezultat constă din elemente DOM și noduri de atribute. DOM - model de obiect document (Document Object Model) - servește pentru a reprezenta un document și o interfață HTML elemente HTML obiecte externe, cum ar fi codul JavaScript.
La rădăcina arborelui se află obiectul Document.

Modelul DOM aproape identic cu marcajul. Să luăm în considerare un exemplu de marcare:

Salut Lume

Arborele DOM pentru acest marcaj arată astfel: Figura. Arborele DOM pentru marcare din exemplu.

Prin „arborele conține noduri DOM” se înțelege că arborele este format din elemente care implementează una dintre interfețele DOM. Browserele folosesc implementări specifice cu atribute suplimentare pentru uz intern.

Algoritmul de analiză

După cum sa discutat în secțiunile anterioare, analizarea HTML nu poate fi făcută folosind parsere standard de sus în jos sau de jos în sus.

Motivele pentru aceasta sunt enumerate mai jos.

  1. Limbajul are un caracter „cruțător”.
  2. Browserele au mecanisme pentru gestionarea unor erori comune în codul HTML.
  3. Ciclul de analiză este caracterizat de posibilitatea de reintrare. Documentul original de obicei nu se schimbă în timpul analizării, cu toate acestea, în cazul HTML, etichetele de script care conțin document.write pot adăuga noi token-uri, astfel încât codul sursă se poate modifica.

Deoarece analizatorii standard nu sunt potriviti pentru HTML, browserele își creează propriile analizoare.

Algoritmul de analiză este detaliat în specificația HTML5. Se compune din două etape: analiza lexicală și construirea arborelui.

În timpul analizei lexicale, secvența de introducere a caracterelor este împărțită în jetoane. Tokenurile HTML includ etichete de început și de sfârșit, precum și nume și valori ale atributelor.

Analizatorul lexical detectează un token, îl transmite constructorului de arbore și trece la următorul caracter în căutarea altor simboluri și așa mai departe până la sfârșitul secvenței de intrare.

Desen . Pași pentru analizarea codului HTML (sursă: specificația HTML5).

Algoritm de analiză lexicală

Rezultatul algoritmului este un token HTML. Algoritmul este exprimat ca o mașină cu stări finite. În fiecare stare, unul sau mai multe caractere ale secvenței de intrare sunt procesate, pe baza cărora este determinată următoarea stare. Depinde de stadiul analizei lexicale și de stadiul formării arborelui, adică prelucrarea aceluiași simbol poate duce la rezultate diferite (stări diferite) în funcție de starea curentă. Algoritmul este suficient de complex pentru a fi descris în detaliu aici, așa că să ne uităm la un exemplu simplificat care ne va ajuta să înțelegem mai bine cum funcționează.

Să analizăm lexical codul HTML simplu:

Salut Lume

Starea inițială este „date”. Când analizorul detectează simbolul< , состояние меняется на „etichetă deschisă”... Dacă o literă (a – z) este găsită în continuare, este generat un simbol de etichetă de deschidere și starea este schimbată în "nume eticheta"... Ea persistă până când este găsit simbolul>. Simbolurile sunt adăugate unul câte unul la numele noului jeton. În cazul nostru, se obține jetonul html.

Când se găsește simbolul>, jetonul este considerat gata și analizorul revine la starea "date"... Etichetă este tratată în același mod. Deci, analizatorul a generat deja etichetele html și body și a revenit la stare "date"... Găsirea literei H în expresia Hello world are ca rezultat generarea unui simbol de caracter. La fel se întâmplă și cu restul literelor, până când analizorul ajunge la simbol< в теге ... Pentru fiecare personaj al expresiei Hello world, este creat propriul său simbol.

Apoi analizorul revine la starea din nou „etichetă deschisă”... Detectarea simbolului / duce la crearea unui simbol de etichetă de final și o tranziție la stare "nume eticheta"... Ea persistă până când este găsit simbolul>. În acest moment, este generat un nou simbol de etichetă, iar analizorul revine la starea "date"... Secvență de personaje procesate conform descrierii de mai sus.

Desen . Analiza lexicală a secvenței de introducere a caracterelor.

Algoritm pentru construirea unui copac

Când parserul este creat, este generat un obiect Document. În timpul fazei de construcție, arborele DOM la rădăcina căruia se află acest obiect este modificat și i se adaugă elemente noi. Fiecare nod generat de analizorul lexical este procesat de constructorul de arbore. Pentru fiecare token, este creat propriul său element DOM, definit de specificație. Elementele sunt adăugate nu numai arborelui DOM, ci și stivei de elemente deschise, care servește la repararea etichetelor imbricate sau neînchise incorect. Algoritmul este, de asemenea, exprimat ca o mașină cu stări finite numită „modul de inserție”.

Să ne uităm la etapele creării unui arbore pentru următoarea bucată de cod:

Salut Lume

La începutul etapei de construire a arborelui, avem o secvență de jetoane obținute ca rezultat al analizei lexicale. Se numește prima stare original... La primirea simbolului html, starea se schimbă în „înainte de html”, după care jetonul este reprocesat în această stare. Aceasta creează un HTMLHtmlElement și îl adaugă la documentul rădăcină.

Statul se schimbă în „înainte de cap”... Analizorul detectează simbolul cadavrului. Deși nu există nicio etichetă head în codul nostru, HTMLHeadElement va fi creat și adăugat automat în arbore.

Statul se schimbă în „în interiorul capului” apoi "dupa cap"... Jetonul body este analizat din nou, un HTMLBodyElement este creat și adăugat la arbore, iar starea este schimbată în „în interiorul corpului”.

Acum este rândul jetoanelor șir Hello world. Detectarea primei dintre acestea duce la crearea și inserarea unui nod Text, căruia îi sunt apoi atașate caracterele rămase.

La primirea simbolului de închidere al corpului, starea se schimbă în „după corp”... Când analizatorul ajunge la eticheta html de închidere, starea se schimbă în „după după corp”... La primirea simbolului de sfârșit de fișier, analiza se încheie.

Desen . Construirea unui arbore pentru codul HTML din exemplu.

Acțiuni după parsare

În acest moment, browserul marchează documentul ca interactiv și începe să analizeze scripturile amânate care trebuie să fie executate după ce documentul a terminat analizarea. Starea documentului se schimbă apoi în gata și evenimentul de încărcare este declanșat.

Să ne uităm la câteva exemple.
Gramatica lexicală (dicționarul) este definită prin expresii regulate pentru fiecare simbol:

Comentariu \ / \ * [^ *] * \ * + ([^ / *] [^ *] * \ * +) * \ / num + | * "." + Nonascii [\ 200- \ 377] nmstart [_a -z] | (nonascii) | (escape) nmchar [_a-z0-9-] | (nonascii) | (escape) nume (nmchar) + ident (nmstart) (nmchar) *

Ident este un identificator folosit ca nume al clasei. Numele este un element de identificare și este referit cu semnul lire sterline (#).

Regulile de sintaxă sunt descrise în format BNF.

Set de reguli: selector ["," S * selector] * "(" S * declarație [";" S * declarație] * ")" S *; selector: simple_selector [combinator selector | S + [combinator? selector]? ]? ; simple_selector: element_name [HASH | clasa | atribuire | pseudo] * | [HASH | clasa | atribuire | pseudo] +; clasa: "." IDENT; element_name: IDENT | „*”; atribut: "[" S * IDENT S * [["=" | INCLUDE | DASHMATCH] S * [IDENT | SIRURI DE CARACTERE *] "]"; pseudo: ":" [IDENT | FUNCȚIA S * ")"]; Un set de reguli este structura descrisă mai jos. div.error, a.error (culoare: roșu; font-weight: bold;) Elementele div.error și a.error sunt selectoare. Regulile eficiente pentru acest set sunt incluse în acolade. Formal, această structură este definită după cum urmează: set de reguli: selector ["," S * selector] * "(" S * declarație [";" S * declarație] * ")" S *; Aceasta înseamnă că setul de reguli acționează ca un selector sau mai mulți selectori separați prin virgule și spații (S înseamnă spațiu). Un set de reguli conține una sau mai multe declarații, separate prin punct și virgulă. Sunt închise în bretele. Definițiile termenilor „declarație” și „selector” vor fi date mai jos.

Analizor CSS în WebKit

WebKit folosește generatoare pentru a genera automat analizatoare CSS. După cum s-a menționat, Bison este folosit pentru a crea parsere în amonte care mută secvența de caractere de intrare la dreapta. Firefox folosește un analizor de sus în jos dezvoltat de Mozilla. În ambele cazuri, fișierul CSS este analizat în obiecte StyleSheet care conțin regulile CSS. Obiectul reguli CSS conține selectorul și declarația, precum și alte obiecte specifice gramaticii CSS.

Desen . Analizarea CSS.

Ordinea procesării scripturilor și foilor de stil

Scripturi

Documentele web urmează un model sincron. Se presupune că scripturile vor fi analizate și executate de îndată ce analizorul detectează eticheta

Top articole similare