Hello, my name is Dmitry Karlovsky and I ... that still toxic pepper. I recently poured my alpha vibes to Alfa Bank . In response, the guys acted with dignity, and did not attack me in a personal with explanations how much I was wrong, but started a task on the github . And they even fixed something, making some of my claims untenable. But not the part where SSR messes up.
Time has passed, the dust has settled, and here the story continues: recently, the producer of the Habr content studio approached me with a proposal to sand their Cake . Well, let's uncover the fan!
Complex case
Take, for example, this page with 2500 comments. This is such a huge page that if you open it in Chrome, it will truncate it by 1400 comments. To read the rest you will have to open it, for example, in Ognelis. Let's leave the reason for this on the conscience of the developers. Let's better think about how to prevent this. But first, let's take measurements:
Index | Desktop version (HTML) | Mobile version (JSON) | Expedited Universal Version (JSON) |
---|---|---|---|
Data size | 12 MB | 3.4 MB | 3.4 MB |
1000 KB | 700 KB | 700 KB | |
45 s | 42 s | 5 s | |
5 s | 42 s | 5 s | |
DOM | 116K | 100K | < 1K |
700 ms | 30 ms | ||
1800 ms | 30 ms | ||
800 MB | 1000 MB | 80 MB |
- β HTML JSON . , " ". , .
- β , .
- β (, β ), F5 ( " ") . .
- β , , , , .
- DOM β
document.getElementsByTagName('*').length
, . - β . .
- β . .
- β , (shift+esc) .
. - β .
: . HTML. : HTML, "" JSON VueJS . , HTML. HTML , , .
, JSON 4 HTML. Tree , , JSON . , , , β 30%.
HTML , :
- , 8 , . loading="lazy", .
- HTML , , . DOM, HTML . β HTML.
, DOM . , . VueJS , .
100K DOM . 40 . .
DOM . , , , 700. , . β 2 . DOM . DevTools , .
β DOM . , . :
. | . | , , . | |
, . ### | , . | , . | |
. ### | . ## | . ### | |
. ## | . ## . ### | . # . ## | |
### ### ## | ### ## ## | ### ## # |
:
- .
- , .
β $mol, , , $mol .
JSON. , , , . $mol_data:
const Person = Rec({
alias: Str,
id: Str,
login: Str,
fullname: Maybe( Str ),
avatarUrl: Maybe( Str ),
speciality: Maybe( Str ),
})
const Comment = Rec({
id: Int,
author: Maybe( Person ),
children: List( Int ),
isAuthor: Maybe( Bool ),
isPostAuthor: Maybe( Bool ),
message: Str,
parentId: Int,
score: Maybe( Int ),
timeChanged: Maybe( Moment ),
timePublished: Maybe( Moment ),
})
const Comments_response = Rec({
comments: Dict( Comment ),
threads: List( Int ),
})
β null
, .
, . , :
@ $mol_mem
comments_data() {
const uri = `https://m.habr.com/kek/v2/articles/${ this.article_id() }/comments/`
const data = Comments_response( this.$.$mol_fetch.json( uri ) )
return data
}
, , . , HTML. $mol_html_view:
<= Article $mol_html_view
html <= article_content \
highlight <= search
image_uri!node <= image_uri!node \
HTML, $mol_view , . , $mol_html_view , .
image_uri
, IMG
, . , src
, data-src
. :
image_uri( node : HTMLImageElement ) {
return node.dataset.src || node.src || 'about:blank'
}
. / .
@ $mol_mem_key
comments_visible( id : number ) : readonly number[] {
if( this.comment_expanded( id ) ) {
return this.comments_all( id )
} else {
return this.comments_filtered( id )
}
}
, . , $mol . , , - β .
, , , , . . β . :
Ctrl+F
, $mol_hotkey :
plugins /
<= Search_key $mol_hotkey
mod_ctrl true
key * F?event <=> search_focus?event null
<= Theme $mol_theme_auto
:
search_focus( event : Event ) {
this.Search().Suggest().Filter().focused( true )
event.preventDefault()
}
, $mol_theme_auto, .
, , $mol_lights_toggle:
tools /
<= Lights $mol_lights_toggle
<= Sources $mol_link_source
uri \https://github.com/nin-jin/habrcomment
<= Search $mol_search
query?val <=> search?val \
, .
, , $mol_style, , :
$mol_style_define( $my_habrcomment , {
Orig: {
flex: {
grow: 1,
shrink: 0,
basis: per(50),
},
},
Article: {
maxWidth: rem(60),
},
Comments: {
flex: {
shrink: 0,
grow: 1,
},
},
Comments_empty: {
padding: rem(1.5),
},
} )
:
include \/mol/offline/install
Service Worker, .
, , , .
, : https://nin-jin.github.io/habrcomment/#article=423889
, :
javascript: document.location = document.location.href.replace( /\D+/ , 'https://nin-jin.github.io/habrcomment/#article=' )
400 , . :
- /
- /
- /
5 . 6 ( 2 , ). , . .
. , HTML . , - , :
<= Message $mol_html_view
minimal_height 60
highlight <= search \
html <= message \
image_uri!node <= image_uri!node \
HTML . , , , .
5 . 10 .
API, β , , . . , β . :
@ $mol_mem
comments_data() {
const search = encodeURIComponent( this.search() )
const uri = `https://m.habr.com/kek/v2/articles/${ this.article_id() }/comments/?search=${search}`
const data = Comments_response( this.$.$mol_fetch.json( uri ) )
return data
}
, , . . , . - β . API. β .
, β , HTML, , - : , , , BR, . , - , - .
$mol_html_view HTML- β , . , , .
, :
- β - $mol_list. , . - .
- , overflow-anchor, , . , , , 100K , .
β , . , , . , , .
- SSR PWA.
- , , .
- , β .
- VueJS β , $mol β .
- , .
- It is worth preferring those solutions that do not lead to an uncontrolled increase in the number of elementals in the house.
Links
- Reader sources - you can notice that there is nothing at all in the code.
- Page of the $ mol framework - be horrified how much we have there.
- Channel with news about $ mol and MAM - subscribe to be aware of everything important that happens to them.
- $ Mol video channel - video tutorials will appear here someday.