Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Structuring large code bases with small re-usab...
Search
Bastian Hofmann
April 26, 2014
Programming
410
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Structuring large code bases with small re-usable components
From JSUnconf
Bastian Hofmann
April 26, 2014
More Decks by Bastian Hofmann
See All by Bastian Hofmann
Monitoring in Kubernetes with Prometheus and Grafana
bastianhofmann
0
370
Creating a fast Kubernetes Development Workflow
bastianhofmann
0
150
Highly available cross-region deployments with Kubernetes
bastianhofmann
1
180
From source to Kubernetes in 30 minutes
bastianhofmann
0
200
Introduction to Kubernetes
bastianhofmann
1
140
CI/CD with Kubernetes
bastianhofmann
0
250
Creating a fast Kubernetes Development Workflow
bastianhofmann
1
290
Deploying your first Micro-Service application to Kubernetes
bastianhofmann
2
220
Creating a fast Kubernetes Development Workflow
bastianhofmann
0
280
Other Decks in Programming
See All in Programming
コンパウンドプロダクト開発のためのローカルプロセスマネージャー再発明 #layerxgo
izumin5210
0
660
「AI時代、配布するPythonコードをどう守るか: 難読化の実験と判断軸」 #PyconJP2026
pkshadeck
PRO
2
190
マイコン向けの軽量Ruby「PicoRuby」で各種デバイスを制御するネイティブアプリの実現手法
bash0c7
0
310
週末にAI-DLCを本気で回したら$1,600溶けた
hbashimizu
0
130
信頼性の目標を誰も求めてない
shubox
0
500
思考垂れ流し開発 ~音声入力 × AIエージェント × 開発ハーネスによる試行錯誤~
npostring
0
1k
App Storeの外へ──日本のiOSサイドローディング入門 for iOSDC Japan 2026
yuukiw00w
0
130
GraphRAGのKnowledge Graphを 直接!見る/View-GraphRAG's-KnowledgeGraph-directly!
tyumugi1113
1
280
業務時間外もAIに働いてもらう話
colorful12
3
10k
AIエージェント時代のコードレビューを設計する
nogu66
6
2.6k
The Good Stuff, Not the Slop: Engineering High-Quality Android Apps with Modern AI Tooling
danybony
1
230
RSSとCodexを使ってX投稿自動化してみた
ochtum
0
110
Featured
See All Featured
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.4k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
240
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.2k
Embracing the Ebb and Flow
colly
88
5.2k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Everyday Curiosity
cassininazir
0
310
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
510
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
2.8k
What does AI have to do with Human Rights?
axbom
PRO
1
2.4k
Transcript
Structuring a large code base with re-usable components @BastianHofmann
Let's talk about...
Web Application architecture
Handling large code-bases
Code and component re-use
Rapid Development
webserver HTML browser JS
webserver HTML browser JS Ajax
webserver HTML browser JS Ajax
de duplication ode duplication code duplication code duplication code duplication
code duplication code duplication code duplication code duplication code duplication code duplication code duplication code duplication code duplicatio code duplicat code duplic code dup code du code cod co co
A few words about me
None
None
None
None
None
None
None
Questions? Ask
http://speakerdeck.com/u/bastianhofmann
None
webserver loadbalancer pgsql memcached mongodb services
webserver
status quo
None
PHP
MVC
PHP templates
Duplication and only some Code re- use
We can do better
Components
None
None
None
None
None
None
None
None
Self contained
Can be addressed and rendered separately
Server JS Browser JSON HTML HTML
None
PHP controller is part of the component
JS is part of the component
CSS can be part of the component
Share code between server and client
Templates, Validation, Entities,...
It needs to be fast
PHP Controller Mustache Template JavaScript view class Widget Providing data
Handling browser events Displaying data CSS
None
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Institution Menu
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Menu Server
Request Response Institution
LeftColumn Image Menu Server Request Response
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Institution Menu
Widget Requirement
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Menu Institution
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Menu Institution
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Menu Institution
Remember: self contained
Do not fetch data directly
Sssssssllllooooowww
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Menu Account
Account Account Account Account Publication1 Publication2 Publication3 Institution
Require stuff
http://www.infoq.com/presentations/Evolution-of-Code- Design-at-Facebook/
None
Widget Widget Widget Widget Preparer Resolver Resolver Services Connector Interfaces
Connector Implementations
Widget Widget Widget Widget Preparer Fetch Requirements Resolver Resolver Services
Connector Interfaces Connector Implementations
Widget Widget Widget Widget Preparer Resolver Resolver Services Connector Interfaces
Connector Implementations Batch requirements and pass them to resolvers
Widget Widget Widget Widget Preparer Resolver Resolver Services Connector Interfaces
Connector Implementations Call Services as effective as possible (Multi-GET,...)
Widget Widget Widget Widget Preparer Resolver Resolver Services Connector Interfaces
Connector Implementations Attach fetched data to Requirements and pass them back to the preparer
Widget Widget Widget Widget Preparer Resolver Resolver Services Connector Interfaces
Connector Implementations Distribute fetched data to the widgets that required it
public function collect() { return [ new EntityRequirement( 'account', Account::class,
['id' => $this->request->get('id')] ), ]; }
Request Cache
Multi-GET
Futures
Data dependencies within a widget
=> Callbacks
public function collect() { yield [ new EntityRequirement( 'account', Account::class,
['id' => $this->request->get('id')] ), ]; yield [ new ServiceRequirement( 'scienceDisciplines', AccountService::class, 'getScienceDisciplines', ['account' => $this->account] ) ]; }
Data dependencies between Widgets
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Menu Institution
Prefills
class PublicationKeywordSearch { public $publications; public $publicationListItems = [];
public function collect() { yield [ serviceRequirement( 'publications', PublicationService::getCall()->getByKeywords( ['virology', 'cancer'], 10, 0 ) ) ]; foreach ($this->publications as $publication) { yield new WidgetRequirement( 'publicationListItems', PublicationItem::CLASS, [ 'publicationId' => $publication->getId(), 'publication' => $publication ] ); } }
class PublicationItem { public $publicationId; public $publication; public
function collect() { yield new RequestDataRequirement('publicationId'); yield [ new EntityRequirement( 'publication', Publication::class, ['id' => $this->publicationId] ) ]; } }
Whoa, this looks awfully complicated to debug
None
None
None
None
None
So that was the backend
None
Rendering
HTML
JSON
Templates
Mustache } http://mustache.github.com/
<div id="{{widgetId}}"> <h3> Publications <a href="javascript:" class="js-showAll"> ({{count}}) </a>
</h3> <ul> {{#publicationItems}} <li>{{{.}}}</li> {{/publicationItems}} </ul> {{#showLegalFooter}} {{{legalFooter}}} {{/showLegalFooter}} </div>
http://pecl.php.net/package/v8js V8js
JavaScript
WidgetViews
<div id="{{widgetId}}"> <h3> Publications <a href="javascript:" class="js-showAll"> ({{count}}) </a>
</h3> <ul> {{#publicationItems}} <li>{{{.}}}</li> {{/publicationItems}} </ul> {{#showLegalFooter}} {{{legalFooter}}} {{/showLegalFooter}} </div>
YUI.add('views.publicationList', function (Y) { Y.views.publicationList = Y.Base.create(Y.WidgetView, { events :
{ '.js-showALl' : { click : 'showALl' } }, showAll : function () { var node = this.get('container'); node.addClass('loading'); Y.loadWidget(‚/publications/all', { keywords : this.data.keywords }, function (widget) { widget.render({ replace : node }); }); } }); });
http://twitter.github.io/flight/
http://facebook.github.io/react/
http://www.youtube.com/watch?v=fqULJBBEVQE
http://www.polymer-project.org/
<polymer-element name="tk-element" attributes="owner color"> <template> <span>This is <strong>{{owner}}</strong>'s tk-element.</span> <span
id="el" style="color: {{color}}">Not ready...</span> </template> <script> Polymer('tk-element', { owner: "Bastian", color: "red", ready: function() { this.$.el.innerText = this.owner + " is ready!"; } }); </script> </polymer-element>
<!DOCTYPE html> <html> <head> <script src="bower_components/platform/platform.js"> </script> <link rel="import" href="elements/tk-element.html">
</head> <body> <tk-element color="blue"></tk-element> </body> </html>
Benefits
Enables developers to only focus on their components
Rapid prototyping
Easier Refactoring
Error Handling
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Menu Institution
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Menu EXCEPTION
Institution
Profile Publications Publication Publication Publication LeftColumn Image Menu Institution
Experiments (A/B Testing)
None
Caching of Components
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Menu <esi:include
src="..." /> Institution
Easy re-using of components
None
Load components asynchronously
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Menu <div
id="placeholder"></div> <script>loadWidget('/aboutMe', function(w) { w.render({ replace : '#placeholder' }); })</script> Institution
BigPipe https://www.facebook.com/note.php? note_id=389414033919
None
Profile Menu Header LeftColumn RightColumn
None
None
None
None
pushState
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Menu Institution
Profile Questions Question Question Question AboutMe LeftColumn Image Menu Institution
Conclusion?
Think about your architecture
Refactor and make it better continuously
Frontend and backend are part of the same application
Don't rewrite your whole codebase in one go
http://twitter.com/BastianHofmann http://lanyrd.com/people/BastianHofmann http://speakerdeck.com/u/bastianhofmann !
[email protected]