$30 off During Our Annual Pro Sale. View Details »

人気サービスをFlutter Webでリプレースするとどうなるのか

Koji Wakamiya
November 16, 2022

人気サービスをFlutter Webでリプレースするとどうなるのか

FlutterKaigi 2022 Day 1 17:45~18:15

Koji Wakamiya

November 16, 2022
Tweet

More Decks by Koji Wakamiya

Other Decks in Technology

Transcript

  1. ਓؾαʔϏεΛFlutter WebͰ 
 ϦϓϨʔε͢Δͱ Ͳ͏ͳΔͷ͔ FlutterKaigi 2022 @koji-1009/2022-11-16 1

  2. ࣗݾ঺հ • एٶߒ࢘/@koji-1009(GitHub) • ελσΟϓϥεגࣜձࣾ • ϞόΠϧΫϥΠΞϯτνʔϜ ςοΫϦʔυ • Google

    for Startups Accelerator Mentor 2
  3. ࣗݾ঺հ • FlutterʹUIͷϚΠΫϩαʔϏε։ൃΛಋೖ͠ɺ 
 ѹ౗తͳDXΛ࣮ݱ͠Α͏ʂ • FlutterKaigi 2021 day 2

    • Flutter Webͷ։ൃΛߦ͏ͨΊͷ஌ݟʢϦϙδτϦ෼ׂʣ 3
  4. ελσΟϓϥεגࣜձࣾ • Mission • ֶ ぶ ت び Λ͢ べ

    ͯͷਓ΁ • Value • Dive to Learn - ֶशऀͷͨΊʹ΍Ζ͏ • Fail Forward - ど Μ ど Μࣦഊ͠Α͏ • Far Together - ҧ͍ʹ׮༰ で ͋Ζ͏ 4
  5. ελσΟϓϥεגࣜձࣾ • 2010೥૑ۀͷEdTechاۀ • αʔϏε • toC޲͚: Studyplus • toB޲͚:

    Studyplus for School 5
  6. ελσΟϓϥεͱFlutter • 2019೥9݄ϦϦʔεͷPortoʹͯFlutterΛ࠾༻ • Portoͷػೳ͸2021೥͔ΒStudyplusʹ౷߹ • 2021೥12݄͔ΒStudyplusʹ΋Add-to-appͰར༻ • 2023೥ʹKotlin/Swift͔ΒFlutter΁શ໘తʹҠߦ༧ఆ 6

  7. ໨࣍ • Flutter Webͷ঺հ • Flutter Webͷ࠾༻ࣄྫ • Flutter Webͷಛ௃

    • ׆༻ͷͨΊͷ޻෉ • Flutter WebΛ࠾༻͢ΔͱͲ͏ͳΔ͔ 7
  8. Flutter Web 8

  9. Flutter Web • Flutter 2.0.0͔Βstable • fl utter build webίϚϯυʹΑΓSPAΛੜ੒

    • Dart੡ͷύοέʔδͰ͋Ε͹ར༻Մೳ • શͯͷύοέʔδ͕࢖͑ΔΘ͚Ͱ͸ͳ͍ • Windowؔ਺΍JSϥΠϒϥϦΛಡΈࠐΜͰར༻Ͱ͖Δ΋ͷ΋͋Δ 9
  10. Flutter Web • Navigator 2ͱ૊Έ߹ΘͤΔ͜ͱʹΑΓϒϥ΢βͷಈ࡞ʹରԠ • CanvasKitͱHTMLͷ2ͭͷϨϯμϦϯάϞʔυ • Flutter 3.3Ͱ͸SEOʹ՝୊ΞϦ

    • SSR΍SSG͸2022೥࣌఺Ͱਖ਼ࣜαϙʔτ͞Εͣ • ಈతͳΞϓϦέʔγϣϯ޲͚ 10
  11. https://docs. fl utter.dev/development/platform-integration/web/faq#search- engine-optimization-seo In general, Flutter is geared towards

    dynamic application experiences. Flutter’s web support is no exception. Flutter web prioritizes performance, fi delity, and consistency. This means application output does not align with what search engines need to properly index. For web content that is static or document-like, we recommend using HTML—just like we do on fl utter.dev, dart.dev, and pub.dev. You should also consider separating your primary application experience —created in Flutter—from your landing page, marketing content, and help content—created using search-engine optimized HTML. 11
  12. Flutter Webͷ࠾༻ࣄྫ

  13. ࠾༻ࣄྫ • WebΞϓϦέʔγϣϯͷ։ൃʹFlutterΛ࠾༻ • Ұ෦ͷސ٬޲͚ΞϓϦέʔγϣϯ͸ϦϦʔεࡁΈ • Ұൠ޲͚ͷΞϓϦέʔγϣϯΛ։ൃத • ϞόΠϧΫϥΠΞϯτνʔϜ͕։ൃΛओಋ •

    ςοΫϦʔυ + AndroidΤϯδχΞ 2໊ + iOSΤϯδχΞ 2໊ 13
  14. Flutter Web࠾༻ͷϞνϕʔγϣϯ • ϛογϣϯ΍Ϗδωε໨తͱ։ൃ্ͷ੍໿ͷဃ཭ • ϓϥοτϑΥʔϜ͝ͱͷ։ൃ͸ຊ࣭తͳ໨తͰ͸ͳ͍ • ΑΓૣ͘ɺΑΓ޿͍؀ڥʹ޲͚ͨαʔϏεల։ • ΞΫηγϏϦςΟ

    • ݹ͍୺຤΍OSͰ΋ར༻Ͱ͖ΔαʔϏε΁ 14
  15. Flutter Webͷ࠾༻໨త • MobileͷΑ͏ʹWebΞϓϦέʔγϣϯ͕࡞ΕΔ • MobileΤϯδχΞ͕WebΞϓϦέʔγϣϯΛ։ൃͰ͖Δ 15

  16. MobileͷΑ͏ͳWebΞϓϦέʔγϣϯ • WebΞϓϦέʔγϣϯʹMobileతͳίϯϙʔωϯτΛ࣋ͪࠐΊΔ • ListView΍ButtonɺSpinnerɺը໘ભҠͳͲ • LongTap΍Hoverঢ়ଶͳͲʹରԠ • Ϛ΢εɺࢦɺλονϖϯʹରԠ •

    Dark Theme΋ඪ४αϙʔτ 16
  17. ෳ਺ϓϥοτϑΥʔϜʹରԠͰ͖ΔΤϯδχΞ • ΤϯδχΞͷ࠾༻͕ඇৗʹ೉͍͠ • MobileΞϓϦέʔγϣϯ։ൃ͕Ͱ͖ΔΤϯδχΞ͸رগ • طଘϝϯόʔͷطଘεΩϧͷԆ௕ઢ্ͰWebʹରԠ͍ͨ͠ • υϝΠϯ஌ࣝ΋े෼ͳͨΊɺ׆༂Ͱ͖Δૉ஍͸े෼ʹ͋Δ •

    (௕ظతʹ͸ҭ੒΍࠾༻Λ͢Δ΂͖) 17
  18. Flutter Web΁ͷ఍߅ײ • Flutter Web΁औΓ૊Ή͜ͱࣗମ͸఍߅ײͳ͠ • ։ൃ͢ΔͨΊͷ஌ݟ͕଍Γͳ͍ͨΊෆ҆ • DartͷίʔυΛϨϏϡʔ͢Δ஌ݟ΍ࣗ৴ •

    WebʹରԠ͢ΔͨΊͷϥΠϒϥϦ΍ઃܭ 18
  19. Flutter WebΛޮՌతʹ׆༻͢Δ޻෉ • FlutterΛར༻ͯ͠։ൃ͢ΔνʔϜʹม͑Δ • MobileͱWebͷ։ൃϦϙδτϦΛ෼͚Δ • MobileͱWebͷମݧΛ౷Ұ͢Δ 19

  20. FlutterΛར༻ͯ͠։ൃ͢ΔνʔϜʹม͑Δ • طଘͷAndroid/iOSΞϓϦέʔγϣϯ։ൃΛ࠷খݶʹ͢Δ • ։ൃλεΫΛػೳ୯ҐͰ෼ׂ͢Δ • 2 approve͕mergeͷ৚݅ʹͳΔΑ͏มߋ͢Δ 20

  21. ։ൃϦϙδτϦͷ෼ׂ • MobileͱWebʹ߹ΘͤΔͨΊʹɺ։ൃΛ෼͚Δ • Navigation routes͕Web͸MobileͱҟͳΔ • ը໘ͷॎԣൺͷύλʔϯ͕MobileΑΓଟ͍ • MobileͱWebͷϦϙδτϦ͕ಉҰͩͱɺDeployʹࠔΔ

    • Web͸”ଈ࣌”ʹ”ແ৹ࠪ”ͰDeployͰ͖Δ 21
  22. UIΛڞ༗͢ΔͨΊͷϦϙδτϦ෼ׂ • Flutter͸ɺUI(Widget)ϨϕϧͰΞϓϦέʔγϣϯΛ෼ׂͰ͖Δ • 2021೥౓ͷൃද͸ɺUIϨϕϧͷϦϙδτϦ෼ׂΛఏҊ • WebͱMobileͰڞ༗͍ͨ͠UIΛϦϙδτϦԽ • 1ͭͷػೳվળΛɺෳ਺ͷΞϓϦέʔγϣϯʹ൓өͤ͞Δ࢓૊Έ

  23. UIΛڞ༗͢ΔͨΊͷϦϙδτϦ෼ׂ 'MVUUFS8FCΞϓϦ " 'MVUUFS.PCJMFΞϓϦ 'MVUUFS8FCΞϓϦ # 6* .PEVMF 6* .PEVMF

    6* .PEVMF -PHJD .PEVMF -PHJD .PEVMF -PHJD .PEVMF 6* .PEVMF 6* .PEVMF -PHJD .PEVMF 6* .PEVMF
  24. MobileͱWebͷମݧΛ౷Ұ • Phone/Tablet/Desktopͷҧ͍ΛBreakpointͰ੔ཧ • ը໘ͷԣ෯ͷҧ͍ΛϨΠΞ΢τͱMarginͰௐ੔ • ϨΠΞ΢τΛܾఆ͢Δେ࿮͕ɺදࣔWidgetͷݟ͑ํΛ֬ఆ • Widgetͷ֎෦͔ΒPaddingΛௐ੔Մೳʹ͢Δ •

    ListViewΛPaddingͰׅΔॲཧΛͳ͘͢ 24
  25. Paddingͷௐ੔ class HogeWidget extends StatelessWidget { const HogeWidget({super.key}); @override Widget

    build(BuildContext context) { return const Padding( padding: EdgeInsets.symmetric( horizontal: 16, ), child: InnerWidget() ); } }
  26. Paddingͷௐ੔ class HogeWidget extends StatelessWidget { const HogeWidget({super.key}); @override Widget

    build(BuildContext context) { final margin = calculateMargin(context); return Padding( padding: EdgeInsets.symmetric( horizontal: margin, ), child: const InnerWidget() ); } double calculateMargin(BuildContext context) { if (MediaQuery.of(context).size.width < 600) { return 16; } else { return 32; } } } ը໘෯ʹΑΔmarginରԠ
  27. Paddingͷௐ੔ class HogeWidget extends StatelessWidget { const HogeWidget({super.key}); @override Widget

    build(BuildContext context) { final margin = calculateMargin(context); return InnerWidget( margin: margin, ); } double calculateMargin(BuildContext context) { if (MediaQuery.of(context).size.width < 600) { return 16; } else { return 32; } } } Widgetͷ಺෦Padding
  28. None
  29. Paddingͷௐ੔ class InnerWidget extends StatelessWidget { const InnerWidget({ super.key, required

    this.margin, }); final double margin; @override Widget build(BuildContext context) { return ListView.builder( padding: EdgeInsets.symmetric( horizontal: margin, ), itemBuilder: (context, index) => ListTile( title: Text(‘$index’), ), ); } } ֎෦͔Βͷࢦఆ
  30. Paddingͷௐ੔ class InnerWidget extends StatelessWidget { const InnerWidget({ super.key, required

    this.margin, }); final double margin; @override Widget build(BuildContext context) { return ListView.builder( itemBuilder: (context, index) => ListTile( contentPadding: EdgeInsets.symmetric( horizontal: margin, ), title: Text(‘$index’), ), ); } } λονྖҬͷௐ੔
  31. None
  32. Flutter WebΛ 
 ࠾༻͢ΔͱͲ͏ͳΔͷ͔ 32

  33. Flutter Webͷҹ৅ • FontͷରԠΛؚΊɺݸผʹղফ͢Δ΂͖՝୊͕ଟ͍ • MobileͰಈ͍͍ͯͯ΋ɺWebͰಈ͘ͱ͸ݶΒͳ͍ • ϚϧνεϨουͷར༻ʹݸผͷ࣮૷͕ඞཁ • ը໘ͷଟ༷ͳαΠζɺಈతͳαΠζมߋ΁ͷରԠ

    • MobileͱWebͰPadding͕ҟͳΔWidget 33
  34. Flutter Webͷҹ৅ • ύϑΥʔϚϯε͸े෼ʹ࣮༻త • ֤छϥΠϒϥϦαϙʔτ͸ॏཁͳ΋ͷΛ֬ೝ͢Ε͹OK • Firebase͸௥͍͍͖ͭͯͨ • Pure

    DartͰ͸ͳ͍ϥΠϒϥϦ͸ݸผʹ൑அඞਢ 34
  35. ૯࿦ • Ϧιʔεͷগͳ͍νʔϜͰ͸બ୒ࢶʹͳΓ͏Δ • ϞόΠϧΤϯδχΞ͕ଟ͍νʔϜͳΒݕ౼ͯ͠΋Α͍ • Ϧιʔε͕५୔Ͱ͋Ε͹ɺ͋͑ͯબ୒ͤͣͱ΋Α͍ • PWAΛؚΊͨϞόΠϧϑΝʔετͳ։ൃʹϚον͢Δ •

    ϓϥοτϑΥʔϜΛލ͍ͩ࠷େެ໿਺తͳ։ൃʹϚον 35
  36. ૯࿦ • αʔϏε։ൃʹूதͰ͖ΔνʔϜʹͳΔ • όάमਖ਼΍ػೳվળ͕͠΍͍͢ • ػೳ։ൃͷػೳͷ͋Γํʹूத͠΍͍͢ • FlutterΛ࠷େݶʹ׆༻͠΍͘͢ͳΔ •

    Mobile޲͚ͷ։ൃΛͦͷ··Webʹల։Մೳ 36
  37. Thanks! 37